diff --git a/nasfaq/connections/api/api.cpp b/nasfaq/connections/api/api.cpp new file mode 100644 index 0000000..348c5d8 --- /dev/null +++ b/nasfaq/connections/api/api.cpp @@ -0,0 +1,11 @@ +#include "api.h" + +class nsfq_proxy_api { +public: + +private: + /* HTTP wrapper to interface with the server. */ + + /* Websocket used to interface with the server. */ + websocket_endpoint ws_endpoint; +} diff --git a/nasfaq/connections/ws/my_ssl.h b/nasfaq/connections/api/api.h similarity index 84% rename from nasfaq/connections/ws/my_ssl.h rename to nasfaq/connections/api/api.h index b40d042..224a668 100644 --- a/nasfaq/connections/ws/my_ssl.h +++ b/nasfaq/connections/api/api.h @@ -1,5 +1,5 @@ -#ifndef _MY_SSL_H_ -#define _MY_SSL_H_ +#ifndef _API_H_ +#define _API_H_ #include #include @@ -16,8 +16,7 @@ #include "../parser/parser.h" #include "../common/common.h" #include "../safe_queue/safe_queue.h" - -int connect_ws(std::string); +#include "../my_ssl/my_ssl.h" #endif diff --git a/nasfaq/connections/client/client.cpp b/nasfaq/connections/client/client.cpp new file mode 100644 index 0000000..c242dbc --- /dev/null +++ b/nasfaq/connections/client/client.cpp @@ -0,0 +1,9 @@ +#include "client.h" + +namespace proxy { + client::client(void) { + m_q = SafeQueue; + m_endpoint = + + } +} diff --git a/nasfaq/connections/client/client.h b/nasfaq/connections/client/client.h new file mode 100644 index 0000000..917f027 --- /dev/null +++ b/nasfaq/connections/client/client.h @@ -0,0 +1,24 @@ +#ifndef _CLIENT_H_ +#define _CLIENT_H_ + +#include "../common/common.h" +#include "../ws/ssl_ws.h" + +namespace proxy { + /** + NASFAQ proxy client. + */ + class client { + public: + client(void); + ~client(void); + + void init(void); + private: + SafeQueue q; + ws::websocket_endpoint endpoint; + } +} + +#endif + diff --git a/nasfaq/connections/common/common.cpp b/nasfaq/connections/common/common.cpp index bdc5991..65d41dd 100644 --- a/nasfaq/connections/common/common.cpp +++ b/nasfaq/connections/common/common.cpp @@ -1,14 +1,73 @@ #include "common.h" -std::ostream& operator<< (std::ostream& stream, MSG_TYPE const & type) { +/*********************************************************************************** + WEBSOCKET MESSAGE STRUCTURES FUNCTIONS +***********************************************************************************/ +/** + Displays websocket message types. +*/ +std::ostream& operator<< (std::ostream& stream, WS_MSG const & type) { std::string ret; switch(type) { - case COIN_PRICE_UPDATE: ret = "COIN_PRICE_UPDATE"; break; - case HISTORY_UPDATE: ret = "HISTORY_UPDATE"; break; - case BROKER_FEE_UPDATE: ret = "BROKER_FEE_UPDATE"; break; - case TODAY_PRICES_UPDATE: ret = "TODAY_PRICES_UPDATE"; break; - default: ret = "Unknown type: "; + #define X(a) case a: ret = #a; break; + #include "ws_msg.def" + #undef X + default: ret = "Unknown type"; } + stream << ret; return stream; } + +/** + Pretty prints COIN_PRICE events. +*/ +template<> +std::ostream& operator<< (std::ostream& stream, ws_msg_parsed const & op) { + stream << "WS_EVENT_COIN_PRICE_UPDATE:" + << " Coin: " << op.coin + << " Price: " << op.price + << " SaleValue: " << op.saleValue + << " inCirculation: " << op.inCirculation; + return stream; +} + +/** + Pretty prints WS_EVENT_TRANSACTION events. +*/ +template<> +std::ostream& operator<< (std::ostream& stream, ws_msg_parsed const & op) { + stream << "WS_EVENT_TRANSACTION:" + << " Coin: " << op.coin + << " Type: " << op.type + << " UserID: " << op.userid + << " Quantity: " << op.quantity + << " Timestamp: " << op.timestamp + << " Completed: " << op.completed + << " Price: " << op.price; + return stream; +} + +/** + Pretty prints the transactions held in the WS_EVENT_HISTORY_UPDATE vector. +*/ +template<> +std::ostream& operator<< (std::ostream& stream, ws_msg_parsed const & op) { + stream << "WS_EVENT_HISTORY_UPDATE:\n"; + for(auto & element : op.transaction_list) { + stream << "\t" << element << std::endl; + } + + return stream; +} + +/*********************************************************************************** + INGAME MESSAGE STRUCTURES FUNCTIONS +***********************************************************************************/ +std::ostream& operator<< (std::ostream& stream, const cycle_t& op) { + stream << "CYCLE: " << std::endl; + for(auto const& element : op) { + stream << element.first << " : " << element.second << std::endl; + } + return stream; +} diff --git a/nasfaq/connections/common/common.h b/nasfaq/connections/common/common.h index df4f5ad..03adbef 100644 --- a/nasfaq/connections/common/common.h +++ b/nasfaq/connections/common/common.h @@ -7,43 +7,125 @@ #include #include #include +#include +#include +#include #include -#include "../common/common.h" -#include "../safe_queue/safe_queue.h" +//#include "../safe_queue/safe_queue.h" - -enum MSG_TYPE - { COIN_PRICE_UPDATE - , HISTORY_UPDATE - , BROKER_FEE_UPDATE - , TODAY_PRICES_UPDATE +/*********************************************************************************** + WEBSOCKET MESSAGE STRUCTURES +***********************************************************************************/ +/** + Types of messages going through the websocket. + X-macros: https://stackoverflow.com/questions/201593/is-there-a-simple-way-to-convert-c-enum-to-string +*/ +enum WS_MSG { + #define X(a) a, + #include "ws_msg.def" + #undef X }; -std::ostream& operator<< (std::ostream&, const MSG_TYPE&); +///** +// Mapping from WS_MSG enum to its name. +//*/ +//std::map WS_MSG_map { +// #define X(a) {a, "#a"}, +// #include "ws_msg.def" +// #undef X +//}; +/** + Structure holding websocket raw data and their type. + Used to fill the queue uniformly +*/ typedef struct raw_msg_t { - enum MSG_TYPE type; + enum WS_MSG type; std::string data; } raw_message_t ; /** - Placeholder for pre-parsed outputs of the socket. + Placeholder for parsed outputs of the websocket. + These structures are c++ formated and should contain the entirety of the represented data. + Specialized below. */ -template -struct pparsed; +template +struct ws_msg_parsed; /** coinPriceUpdate structure */ template <> -struct pparsed { +struct ws_msg_parsed { std::string coin; float price; float saleValue; uint inCirculation; }; +/** + Auxiliary type for WS_EVENT_HISTORY_UPDATE. + This holds individual transactions as handed by the websocket in a list. +*/ +template <> +struct ws_msg_parsed { + std::string coin; + uint type; + std::string userid; + int quantity; + long timestamp; + bool completed; + float price; +}; + +/** + historyUpdate structure holding transactions. +*/ +template<> +struct ws_msg_parsed { + std::vector> transaction_list; +}; + +/*********************************************************************************** + WEBSOCKET MESSAGE STRUCTURES FUNCTIONS +***********************************************************************************/ +std::ostream& operator<< (std::ostream&, const WS_MSG&); + +/*********************************************************************************** + IN-GAME MESSAGE STRUCTURES +***********************************************************************************/ +/** + Types of in-game messages. +*/ +enum IG_MSG + { TRANSACTION + , IG_UNKNOWN_TYPE +}; + + +/*********************************************************************************** + INGAME MESSAGE STRUCTURES FUNCTIONS +***********************************************************************************/ +template +std::ostream& operator<< (std::ostream&, ws_msg_parsed const &); + +/** + Cycle representation. +*/ +typedef std::map cycle_t; +std::ostream& operator<< (std::ostream&, const cycle_t&); + +/** + User representation +*/ +typedef struct user_t{ + std::string userid; + std::string username; + std::string icon; + float networth; +} user_t; + #endif diff --git a/nasfaq/connections/common/ws_msg.def b/nasfaq/connections/common/ws_msg.def new file mode 100644 index 0000000..ce0eb6f --- /dev/null +++ b/nasfaq/connections/common/ws_msg.def @@ -0,0 +1,13 @@ +X(WS_EVENT_COIN_PRICE_UPDATE) +X(WS_EVENT_TRANSACTION) +X(WS_EVENT_HISTORY_UPDATE) +X(WS_EVENT_BROKER_FEE_UPDATE) +X(WS_EVENT_TODAY_PRICES_UPDATE) +X(WS_EVENT_LEADERBOARD_UPDATE) +X(WS_EVENT_FLOOR_UPDATE) +X(WS_EVENT_AUCTION_UPDATE) +X(WS_EVENT_BENCHMARK_UPDATE) +X(WS_EVENT_SUPERCHAT_UPDATE) +X(WS_EVENT_GACHA_UPDATE) +X(WS_EVENT_ADD_MESSAGE_GLOBAL) +X(WS_EVENT_UNKNOWN) diff --git a/nasfaq/connections/http/http_connector b/nasfaq/connections/http/http_connector deleted file mode 100755 index e4af9f3..0000000 Binary files a/nasfaq/connections/http/http_connector and /dev/null differ diff --git a/nasfaq/connections/http/http_connector.cpp b/nasfaq/connections/http/http_connector.cpp index a0a579b..222287a 100644 --- a/nasfaq/connections/http/http_connector.cpp +++ b/nasfaq/connections/http/http_connector.cpp @@ -1,171 +1,171 @@ #include "http_connector.h" -static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) -{ - ((std::string*)userp)->append((char*)contents, size * nmemb); - return size * nmemb; -} - -//class http_connection { -//public: -// http_connection(int id, CURL *hdl, std::string uri) -// : m_id(id) -// ; m_hdl(hdl) -// ; m_uri(uri) -// ; m_response("N/A") -// {} -// -//private: -// int m_id; -// CURL *m_hdl; -// std::string m_uri; -// CURLcode m_status; -// std::string m_response; -// std::vector m_payloads; -//} -// -//class http_endpoint { -//public: -// http_endpoint() { -// -// } -//private: -//} - -std::string get_sid() -{ - CURL *curl; - CURLcode res; - - static const char *POLLING_URL_0 = "https://nasfaq.biz/socket/?EIO=4&transport=polling&t=Ny7z439"; - static const char *POLLING_URL_1 = "https://nasfaq.biz/socket/?user=314d0bda-d7f0-4636-aed7-5ea02743604b&EIO=4&transport=polling&t=Ny7z472"; - static const char *POLLING_URL_2 = "https://nasfaq.biz/socket/?user=314d0bda-d7f0-4636-aed7-5ea02743604b&EIO=4&transport=polling&t=Ny7z4Bn&sid="; - static const char *POLLING_URL_3 = "https://nasfaq.biz/socket/?user=314d0bda-d7f0-4636-aed7-5ea02743604b&EIO=4&transport=polling&t=Ny7z4Bp&sid="; - static const char *POLLING_URL_4 = "https://nasfaq.biz/socket/?user=314d0bda-d7f0-4636-aed7-5ea02743604b&EIO=4&transport=polling&t=Ny7z4EU&sid="; - - long http_code = 0; - std::string sid_final = ""; - std::string readBuffer = ""; - - curl = curl_easy_init(); - - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); - curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &http_code); - - /* Header */ - struct curl_slist *slist1; - slist1 = NULL; - slist1 = curl_slist_append(slist1 , "Cookie: holosesh=s%3AxmS8xBlQk4kH_rXQOaNjHk_3OuaBDsfA.M0yi%2BZmkiq%2BAmJBRj%2FNg9S%2BaSQpsfHRJcEeYVHLiKXg"); - slist1 =curl_slist_append(slist1, "referer : https://nasfaq.biz/market"); - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist1); - - if(curl) { - - /************** ZEROTH STAGE ********/ - readBuffer = ""; - curl_easy_setopt(curl, CURLOPT_URL, POLLING_URL_0); - res = curl_easy_perform(curl); - - /* Check for result */ - if ( res != CURLE_ABORTED_BY_CALLBACK) { - std::cout << "Zeroth stage ok" << std::endl; - }else { - std::cout << "Failure" << std::endl; - return ""; - } - - - /************** FIRST STAGE ********/ - readBuffer = ""; - curl_easy_setopt(curl, CURLOPT_URL, POLLING_URL_1); - - /* Perform the request, res will get the return code */ - res = curl_easy_perform(curl); - - /* Check for result */ - if (res != CURLE_ABORTED_BY_CALLBACK) { - std::cout << "First stage ok" << std::endl; - }else { - std::cout << "Failure" << std::endl; - return ""; - } - - /* Get sid */ - nlohmann::json r = nlohmann::json::parse(readBuffer.substr(1)); - sid_final = r["sid"]; - - - /************** SECOND STAGE ********/ - readBuffer = ""; - std::string polling_url_2 = POLLING_URL_2 + sid_final; - - curl_easy_setopt(curl, CURLOPT_URL, polling_url_2.c_str()); - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "40"); - curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST"); - - /* Perform the request, res will get the return code */ - res = curl_easy_perform(curl); - - /* Check for result */ - if (res != CURLE_ABORTED_BY_CALLBACK && readBuffer == "ok") { - std::cout << "Second stage ok" << std::endl; - }else { - std::cout << "Failure" << std::endl; - return ""; - } - - /************** THIRD STAGE ********/ - readBuffer = ""; - - // Format next url - std::string polling_url_3 = POLLING_URL_3 + sid_final; - - curl_easy_setopt(curl, CURLOPT_URL, polling_url_3.c_str()); - curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET"); - - /* Perform the request, res will get the return code */ - res = curl_easy_perform(curl); - - - /* Check for result */ - if (res != CURLE_ABORTED_BY_CALLBACK) { - nlohmann::json r2 = nlohmann::json::parse(readBuffer.substr(2)); - std::cout << "Third stage ok" << std::endl; - }else { - std::cout << "Failure" << std::endl; - return ""; - } - - - /************** FOURTH STAGE ********/ - readBuffer = ""; - std::string polling_url_4 = POLLING_URL_4 + sid_final; - - curl_easy_setopt(curl, CURLOPT_URL, polling_url_4.c_str()); - curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET"); - - /* Perform the request, res will get the return code */ - res = curl_easy_perform(curl); - - /* Check for result */ - if ( res != CURLE_ABORTED_BY_CALLBACK) { - std::cout << "Fourth stage ok" << std::endl; - }else { - std::cout << "Failure" << std::endl; - return ""; - } - - - - /* Check for errors */ - if(res != CURLE_OK) - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(res)); - - /* always cleanup */ - curl_easy_cleanup(curl); - } - - return sid_final; +namespace nsfq_http { + namespace http_connector { + + /** + Make curl return strings instead of curl objects. + */ + static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) + { + ((std::string*)userp)->append((char*)contents, size * nmemb); + return size * nmemb; + } + + connector::connector() { + m_hdl = curl_easy_init(); + m_uri = ""; + m_response = "N/A"; + m_read_buffer = ""; + + /* Basic buffers and functions. */ + curl_easy_setopt(m_hdl, CURLOPT_WRITEFUNCTION, WriteCallback); + curl_easy_setopt(m_hdl, CURLOPT_WRITEDATA, &m_read_buffer); + curl_easy_getinfo(m_hdl, CURLINFO_RESPONSE_CODE, &m_http_code); + + /* Header definition. TODO: cookie should be handled safely? */ + m_slist1 = NULL; + m_slist1 = curl_slist_append(m_slist1 , "Cookie: holosesh=s%3AxmS8xBlQk4kH_rXQOaNjHk_3OuaBDsfA.M0yi%2BZmkiq%2BAmJBRj%2FNg9S%2BaSQpsfHRJcEeYVHLiKXg"); + m_slist1 = curl_slist_append(m_slist1, "referer : https://nasfaq.biz/market"); + curl_easy_setopt(m_hdl, CURLOPT_HTTPHEADER, m_slist1); + } + + connector::~connector() { + curl_easy_cleanup(m_hdl); + } + + void connector::set_uri(std::string uri) { + /* TODO: check for url sanity. */ + m_uri = uri; + curl_easy_setopt(m_hdl, CURLOPT_URL, m_uri.c_str()); + } + + int connector::perform_request() { + m_result = curl_easy_perform(m_hdl); + + if (m_result == CURLE_OK) { + return 0; + }else { + return -1; + } + } + + void connector::clear_buffer() { + m_read_buffer = ""; + } + + void connector::get(std::string url) { + clear_buffer(); + set_uri(url); + curl_easy_setopt(m_hdl, CURLOPT_CUSTOMREQUEST, "GET"); + + if(perform_request() == -1) { + std::cout << "> Error occured during GET with url " << m_uri + << " CURLcode: " << curl_easy_strerror(m_result) + << " HTTP response: " << m_http_code << std::endl; + }; + } + + void connector::post(std::string url, std::string payload) { + clear_buffer(); + set_uri(url); + curl_easy_setopt(m_hdl, CURLOPT_CUSTOMREQUEST, "POST"); + curl_easy_setopt(m_hdl, CURLOPT_POSTFIELDS, payload.c_str()); + + if(perform_request() == -1) { + std::cout << "> Error occured during POST with url " << m_uri + << " Payload: " << payload + << " CURLcode: " << curl_easy_strerror(m_result) + << " HTTP response: " << m_http_code << std::endl; + }; + } + + std::string connector::get_buffer() const { + return m_read_buffer; + } + + //class http_connector { + //public: + // http_connector() { + // m_hdl = curl_easy_init(); + // m_uri = ""; + // m_response = "N/A"; + // m_read_buffer = ""; + // + // /* Basic buffers and functions. */ + // curl_easy_setopt(m_hdl, CURLOPT_WRITEFUNCTION, WriteCallback); + // curl_easy_setopt(m_hdl, CURLOPT_WRITEDATA, &m_read_buffer); + // curl_easy_getinfo(m_hdl, CURLINFO_RESPONSE_CODE, &m_http_code); + // + // /* Header definition. TODO: cookie should be handled safely? */ + // m_slist1 = NULL; + // m_slist1 = curl_slist_append(m_slist1 , "Cookie: holosesh=s%3AxmS8xBlQk4kH_rXQOaNjHk_3OuaBDsfA.M0yi%2BZmkiq%2BAmJBRj%2FNg9S%2BaSQpsfHRJcEeYVHLiKXg"); + // m_slist1 = curl_slist_append(m_slist1, "referer : https://nasfaq.biz/market"); + // curl_easy_setopt(m_hdl, CURLOPT_HTTPHEADER, m_slist1); + // } + // + // ~http_connector() { + // curl_easy_cleanup(m_hdl); + // } + // + // void set_uri(std::string uri) { + // /* TODO: check for url sanity. */ + // m_uri = uri; + // curl_easy_setopt(m_hdl, CURLOPT_URL, m_uri.c_str()); + // } + // + // int perform_request() { + // m_result = curl_easy_perform(m_hdl); + // + // if (m_result == CURLE_OK) { + // return 0; + // }else { + // return -1; + // } + // } + // + // void clear_buffer() { + // m_read_buffer = ""; + // } + // + // void get(std::string url) { + // clear_buffer(); + // set_uri(url); + // curl_easy_setopt(m_hdl, CURLOPT_CUSTOMREQUEST, "GET"); + // + // if(perform_request() == -1) { + // std::cout << "> Error occured during GET with url " << m_uri + // << " CURLcode: " << curl_easy_strerror(m_result) + // << " HTTP response: " << m_http_code << std::endl; + // }; + // } + // + // void post(std::string url, std::string payload) { + // clear_buffer(); + // set_uri(url); + // curl_easy_setopt(m_hdl, CURLOPT_CUSTOMREQUEST, "POST"); + // curl_easy_setopt(m_hdl, CURLOPT_POSTFIELDS, payload.c_str()); + // + // if(perform_request() == -1) { + // std::cout << "> Error occured during POST with url " << m_uri + // << " Payload: " << payload + // << " CURLcode: " << curl_easy_strerror(m_result) + // << " HTTP response: " << m_http_code << std::endl; + // }; + // } + // + // std::string get_buffer() const { + // return m_read_buffer; + // } + //private: + // int m_id; + // std::string m_uri; + // struct curl_slist *m_slist1; + // CURL *m_hdl; + // CURLcode m_result; + // long m_http_code; + // std::string m_response; + // std::string m_read_buffer; + //}; + } } diff --git a/nasfaq/connections/http/http_connector.h b/nasfaq/connections/http/http_connector.h index 38bf0b8..7103afb 100644 --- a/nasfaq/connections/http/http_connector.h +++ b/nasfaq/connections/http/http_connector.h @@ -7,6 +7,34 @@ #include #include -std::string get_sid(); +/** + Some of these functions such as perform_request should be private +*/ +namespace nsfq_http { + namespace http_connector { + + class connector { + public: + connector(); + ~connector(); + + void set_uri(std::string); + int perform_request(); + void clear_buffer(); + void get(std::string); + void post(std::string, std::string); + std::string get_buffer() const; + private: + int m_id; + std::string m_uri; + struct curl_slist *m_slist1; + CURL *m_hdl; + CURLcode m_result; + long m_http_code; + std::string m_response; + std::string m_read_buffer; + }; + } +} #endif diff --git a/nasfaq/connections/http/users.cpp b/nasfaq/connections/http/users.cpp new file mode 100644 index 0000000..8fcc0a1 --- /dev/null +++ b/nasfaq/connections/http/users.cpp @@ -0,0 +1,28 @@ +#include "users.h" + +namespace users { + std::vector get_users() { + nlohmann::json j; + user_t user_tmp; + std::vector rop; + + static const char *LEADERBOARD_URL = "https://nasfaq.biz/api/getLeaderboard?leaderboard"; + nsfq_http::http_connector::connector c; + + /* Start handshake, first result is discarded. */ + c.get(LEADERBOARD_URL); + + j = nlohmann::json::parse(c.get_buffer())["leaderboard"]["leaderboard"]; + + for(auto const & element:j) { + user_tmp.userid = element["userid"]; + user_tmp.username = element["username"]; + user_tmp.icon = element["icon"]; + user_tmp.networth = element["networth"]; + + rop.push_back(user_tmp); + } + + return rop; + } +} diff --git a/nasfaq/connections/http/users.h b/nasfaq/connections/http/users.h new file mode 100644 index 0000000..305ce85 --- /dev/null +++ b/nasfaq/connections/http/users.h @@ -0,0 +1,19 @@ +#ifndef _USERS_H_ +#define _USERS_H_ + +#include +#include +#include + +//#include +//#include + +#include "../http/http_connector.h" +#include "../common/common.h" + +namespace users { + std::vector get_users(); +} + +#endif + diff --git a/nasfaq/connections/parser/parser.cpp b/nasfaq/connections/parser/parser.cpp index c822640..48b5ffc 100644 --- a/nasfaq/connections/parser/parser.cpp +++ b/nasfaq/connections/parser/parser.cpp @@ -1,29 +1,33 @@ #include "parser.h" -MSG_TYPE msg_type_detect(std::string op) { - MSG_TYPE ret; - if (op.substr(2, 15) == "coinPriceUpdate") { - ret = COIN_PRICE_UPDATE; - } else if (op.substr(2, 13) == "historyUpdate") { - ret = HISTORY_UPDATE; - } else if (op.substr(2, 17) == "todayPricesUpdate") { - ret = TODAY_PRICES_UPDATE; - } else if (op.substr(2, 15) == "brokerFeeUpdate") { - ret = BROKER_FEE_UPDATE; +namespace parser { + +WS_MSG msg_type_detect(std::string op) { + WS_MSG ret; + + if (op.substr(0, 30).find("coinPriceUpdate") != std::string::npos) { + ret = WS_EVENT_COIN_PRICE_UPDATE; + } else if (op.substr(0, 30).find("historyUpdate") != std::string::npos) { + ret = WS_EVENT_HISTORY_UPDATE; + } else if (op.substr(0, 30).find("todayPricespdate") != std::string::npos) { + ret = WS_EVENT_TODAY_PRICES_UPDATE; + } else if (op.substr(0, 30).find("brokerFeeUpdate") != std::string::npos) { + ret = WS_EVENT_BROKER_FEE_UPDATE; + } else { + ret = WS_EVENT_UNKNOWN; } return ret; } -template -pparsed parse(raw_msg_t rmsg) {}; +template +ws_msg_parsed parse(std::string rmsg) {}; template <> -pparsed parse(raw_msg_t rmsg) { - std::string payload = rmsg.data; - nlohmann::json jparsed = nlohmann::json::parse(payload.substr(21, payload.length()-21-1)); /* Check for errors and emptiness needed */ +ws_msg_parsed raw_msg_parse(std::string rmsg) { + nlohmann::json jparsed = nlohmann::json::parse(rmsg); /* Check for errors and emptiness needed */ - pparsed rop; + ws_msg_parsed rop; rop.coin = jparsed["coin"]; rop.price = (jparsed["info"])["price"]; rop.saleValue = (jparsed["info"])["saleValue"]; @@ -32,28 +36,141 @@ pparsed parse(raw_msg_t rmsg) { return rop; } +/**************************************************************** + Helper functions should go in common or something more general +****************************************************************/ -//class parser { -//public: -// parser (SafeQueue queue) -// : m_queue(queue); -// {} -// -// void parse() { -// std::string raw_data; -// -// msg_type type; -// std::string data; -// -// while(1) { -// raw_data = m_queue.dequeue(); -// type = msg_type_detect(raw_data); -// -// data = m_queue. -// sleep(0.5); -// } -// } -//private: -// SafeQueue m_queue; -//} -// +/* + See https://stackoverflow.com/questions/2896600/how-to-replace-all-occurrences-of-a-character-in-string +*/ +static inline void replace_all(std::string& str, const std::string& from, const std::string& to) { + size_t start_pos = 0; + while((start_pos = str.find(from, start_pos)) != std::string::npos) { + str.replace(start_pos, from.length(), to); + start_pos += to.length(); // Handles case where 'to' is a substring of 'from' + } +} + +/* + Splits a string "{...}, ..., {...}" in an array ["{...}", ..., "{...}"]. + ONLY HANDLES DICTIONARIES OF DEPTH 1. +*/ +std::vector tokenize_json_array(std::string op, std::string token = "}") { + int start = 0; + int end = op.find("}"); + std::vector ret; + + while( end != -1 ) { + ret.push_back(op.substr(start, end - start + 1)); + start = end + token.size() + 1; // + 1 accounts for the ",". + end = op.find(token, start); + } + + return ret; +} + +template <> +ws_msg_parsed raw_msg_parse(std::string rmsg) { + nlohmann::json jparsed = nlohmann::json::parse(rmsg); /* Check for errors and emptiness needed */ + + ws_msg_parsed rop; + rop.coin = jparsed["coin"]; + rop.type = jparsed["type"]; + rop.userid = jparsed["userid"]; + rop.quantity = jparsed["quantity"]; + rop.timestamp = jparsed["timestamp"]; + rop.completed = jparsed["completed"]; + rop.timestamp = jparsed["timestamp"]; + rop.price = jparsed["price"]; + + return rop; +} + +template<> +ws_msg_parsed raw_msg_parse(std::string rmsg) { + std::vector raw_vect; + ws_msg_parsed rop; + + /* Replace \" by " */ + replace_all(rmsg, "\\\"", "\""); + + /* Extract array */ + raw_vect = tokenize_json_array(rmsg); + + /* Create the output array by parsing each transaction elements */ + for(auto & raw_tr : raw_vect) { + rop.transaction_list.push_back(raw_msg_parse(raw_tr)); + } + + return rop; +} + +parser::parser(ws::connection_metadata::ptr metadata, pqxx::connection* C) + : m_metadata(metadata) + , m_process_queue_state(false) + , m_connection(C) +{} + +parser::~parser() { + +} + +void parser::process_queue() { + + WS_MSG type; + std::string raw_data; + std::string parsed_msg; + + m_process_queue_state = true; + + while(m_process_queue_state) { + raw_data = m_metadata->pop_message(); + type = msg_type_detect(raw_data); + + /* POSTGRESQL STUFF GOES HERE */ + if (type == WS_EVENT_COIN_PRICE_UPDATE) { + /* 18 = 3 + 15 */ + raw_data = raw_data.substr(18, raw_data.length()-18); + ws_msg_parsed parsed_msg = raw_msg_parse(raw_data); + + std::cout << parsed_msg << std::endl; + db::push_coin_price(m_connection, parsed_msg); + + } else if (type == WS_EVENT_HISTORY_UPDATE) { + raw_data = raw_data.substr(18, raw_data.length()-18); + ws_msg_parsed parsed_msg = raw_msg_parse(raw_data); + + std::cout << parsed_msg << std::endl; + db::push_history(m_connection, parsed_msg); + //std::cout << "\x1B[31mTexting\033[0m\t\t" << std::endl; + } + } +} + +void* parser::process_queue_helper(void* arg) +{ + parser* p = reinterpret_cast(arg); + p->process_queue(); + return 0; +} + +void parser::process_queue_start() { + int rc = pthread_create(&m_process_queue_thread, NULL, process_queue_helper, this); + + if (rc) { + std::cout << "Error:unable to create thread," << rc << std::endl; + exit(-1); + } +} + +void parser::process_queue_thread_join() +{ + pthread_join(m_process_queue_thread, 0); +} + + +void parser::process_queue_stop() { + m_process_queue_state = false; +} + +} diff --git a/nasfaq/connections/parser/parser.h b/nasfaq/connections/parser/parser.h index c80d568..ef8cc2e 100644 --- a/nasfaq/connections/parser/parser.h +++ b/nasfaq/connections/parser/parser.h @@ -6,11 +6,46 @@ #include #include +#include "../sql/db_handle.h" #include "../common/common.h" -#include "../safe_queue/safe_queue.h" +#include "../ws/ssl_ws.h" -MSG_TYPE msg_type_detect(std::string); +namespace parser { + +WS_MSG msg_type_detect(std::string); + +template +ws_msg_parsed raw_msg_parse(std::string); + +template <> +ws_msg_parsed raw_msg_parse(std::string); + +template<> +ws_msg_parsed raw_msg_parse(std::string); + +template<> +ws_msg_parsed raw_msg_parse(std::string); + +class parser { +public: + parser(ws::connection_metadata::ptr, pqxx::connection*); + ~parser(void); + + void process_queue(); + void process_queue_start(); + void process_queue_stop(); + void process_queue_thread_join(); +private: + ws::connection_metadata::ptr m_metadata; + bool m_process_queue_state; + pthread_t m_process_queue_thread; + pqxx::connection* m_connection; + + static void* process_queue_helper(void*); +}; + +} #endif diff --git a/nasfaq/connections/safe_queue/safe_queue.cpp b/nasfaq/connections/safe_queue/safe_queue.cpp index b6f7008..7501531 100644 --- a/nasfaq/connections/safe_queue/safe_queue.cpp +++ b/nasfaq/connections/safe_queue/safe_queue.cpp @@ -1,2 +1,50 @@ #include "safe_queue.h" +template +TestQueue::TestQueue(void) + : q() +{} + +template +TestQueue::~TestQueue(void) +{} + +template +SafeQueue::SafeQueue(void) + : q() + , m() + , c() +{} + +template +SafeQueue::~SafeQueue(void) +{} + +// Add an element to the queue. +template +void SafeQueue::enqueue(T t) +{ + std::lock_guard lock(m); + q.push(t); + c.notify_one(); +} + +// Get the "front"-element. +// If the queue is empty, wait till a element is avaiable. +template +T SafeQueue::dequeue(void) { + std::unique_lock lock(m); + while(q.empty()) + { + // release lock as long as the wait and reaquire it afterwards. + c.wait(lock); + } + T val = q.front(); + q.pop(); + return val; +} + +template +bool SafeQueue::empty(void) { + return q.empty(); +} diff --git a/nasfaq/connections/safe_queue/safe_queue.h b/nasfaq/connections/safe_queue/safe_queue.h index 5fe85b8..c972965 100644 --- a/nasfaq/connections/safe_queue/safe_queue.h +++ b/nasfaq/connections/safe_queue/safe_queue.h @@ -1,47 +1,32 @@ -#ifndef SAFE_QUEUE -#define SAFE_QUEUE +#ifndef _SAFE_QUEUE_H_ +#define _SAFE_QUEUE_H_ #include #include #include +// A threadsafe-queue. +template +class TestQueue +{ +public: + TestQueue(); + ~TestQueue(); +private: + std::queue q; +}; + // A threadsafe-queue. template class SafeQueue { public: - SafeQueue(void) - : q() - , m() - , c() - {} - - ~SafeQueue(void) - {} - - // Add an element to the queue. - void enqueue(T t) - { - std::lock_guard lock(m); - q.push(t); - c.notify_one(); - } - - // Get the "front"-element. - // If the queue is empty, wait till a element is avaiable. - T dequeue(void) - { - std::unique_lock lock(m); - while(q.empty()) - { - // release lock as long as the wait and reaquire it afterwards. - c.wait(lock); - } - T val = q.front(); - q.pop(); - return val; - } + SafeQueue(void); + ~SafeQueue(void); + void enqueue(T); + T dequeue(void); + bool empty(void); private: std::queue q; mutable std::mutex m; diff --git a/nasfaq/connections/sql/db_handle.cpp b/nasfaq/connections/sql/db_handle.cpp new file mode 100644 index 0000000..46df4a2 --- /dev/null +++ b/nasfaq/connections/sql/db_handle.cpp @@ -0,0 +1,285 @@ +#include "db_handle.h" + +namespace db { + namespace query { + /* Query templates for HISTORY. */ + //TODO: Move these definitions to .h file. + const std::string query_template_transaction = "INSERT INTO HISTORY(COIN, TYPE, USERID, QUANTITY, TIMESTAMP, COMPLETED, PRICE) "\ + "VALUES('{}', {}, '{}', {}, {}, {}, {});"; + const std::string query_template_history_ts = "SELECT * FROM HISTORY WHERE TIMESTAMP <= {} AND TIMESTAMP > {};"; + const std::string query_template_userid_ts = "SELECT DISTINCT USERID FROM HISTORY WHERE TIMESTAMP <= {} AND TIMESTAMP > {};"; + + const std::string query_template_slope_ts_top = "SELECT PRICE, TIMESTAMP FROM HISTORY "\ + "WHERE COIN = '{}' AND TIMESTAMP <= {} AND TIMESTAMP > {} "\ + "ORDER BY TIMESTAMP ASC "\ + "LIMIT 1;"; + const std::string query_template_transactions_userid_ts = "SELECT * FROM HISTORY WHERE USERID = '{}' AND TIMESTAMP <= {} AND TIMESTAMP > {};"; + + const std::string query_template_slope_ts_bot = "SELECT PRICE, TIMESTAMP FROM HISTORY "\ + "WHERE COIN = '{}' AND TIMESTAMP <= {} AND TIMESTAMP > {} "\ + "ORDER BY TIMESTAMP DESC "\ + "LIMIT 1;"; + + const std::string query_template_last_n_spaced_prices = "select PRICE, TIMESTAMP FROM last_n_spaced_prices('{}', {}, {});"; + + const std::string query_template_user = "INSERT INTO USERS(USERID, USERNAME, ICON, NETWORTH) "\ + "VALUES('{}', E'{}', '{}', {}) " + "ON CONFLICT (USERID) DO UPDATE SET "\ + "NETWORTH = {};"; + + const std::string query_template_userid_to_username = "select USERNAME FROM USERS WHERE USERID = '{}'"; + + /******************************************************************************** + GLOBAL QUERIES + ********************************************************************************/ + + std::string make_push_query_transaction( ws_msg_parsed op ) { + return fmt::format(query_template_transaction, + op.coin, + op.type, + op.userid, + op.quantity, + op.timestamp, + op.completed, + op.price); + } + + std::string make_pull_query_history_ts( long ts_high, long ts_low ) { + return fmt::format(query_template_history_ts, ts_high, ts_low); + } + + std::string make_pull_query_userid_list_ts( long ts_high, long ts_low ) { + return fmt::format(query_template_userid_ts, ts_high, ts_low); + } + + std::string make_pull_query_transactions_userid_ts( std::string userid, long ts_high, long ts_low ) { + return fmt::format(query_template_transactions_userid_ts, userid, ts_high, ts_low); + } + + std::string make_pull_query_top_price_cycle_ts( std::string coin, long ts_high, long ts_low ) { + return fmt::format(query_template_slope_ts_top, coin, ts_high, ts_low); + } + + std::string make_pull_query_bot_price_cycle_ts( std::string coin, long ts_high, long ts_low ) { + return fmt::format(query_template_slope_ts_bot, coin, ts_high, ts_low); + } + + + /* Query templates for COIN PRICE. */ + const std::string query_template_coin_price = "INSERT INTO COINPRICE(COIN, PRICE, SALEVALUE, INCIRCULATION, LASTUPDATE) "\ + "VALUES('{}', {}, {}, {}, {}) "\ + "ON CONFLICT (COIN) DO UPDATE SET "\ + "PRICE = {}, SALEVALUE = {}, INCIRCULATION = {}, LASTUPDATE = {};"; + + std::string make_push_query_coin_price( ws_msg_parsed op ) { + return fmt::format(query_template_coin_price, + op.coin, + op.price, + op.saleValue, + op.inCirculation, + std::time(NULL)*1000, + op.price, + op.saleValue, + op.inCirculation, + std::time(NULL)*1000); + } + + /* Query templates for math functions. */ + std::string make_pull_query_last_n_spaced_prices( std::string coin, int nb_cycles, int delta) { + return fmt::format(query_template_last_n_spaced_prices, + coin, + nb_cycles, + delta); + } + + std::string make_push_query_user(user_t user){ + return fmt::format(query_template_user, + user.userid, + user.username, + user.icon, + user.networth, + user.networth); + } + + std::string make_pull_query_userid_to_username(std::string userid) { + return fmt::format(query_template_userid_to_username, + userid); + } + } + + /******************************************************************************** + HISTORY + ********************************************************************************/ + + /* Add transactions contained in history update to the database. */ + void push_history( pqxx::connection* C, ws_msg_parsed op ) { + std::string query; + + for(auto& element : op.transaction_list){ + query += query::make_push_query_transaction(element); + } + + /* Create a transactional object. */ + pqxx::work W(*C); + + /* Execute SQL query */ + W.exec( query ); + W.commit(); + } + + /* Returns the last cycle in form of a ws_msg_parsed struct. */ + ws_msg_parsed pull_last_cycle(pqxx::connection* C) { + std::string query; + long ts_high, ts_low; + ws_msg_parsed tmp; + ws_msg_parsed rop; + + ts_high = time(NULL)*1000; + ts_low = ts_high - 600*1000; + + query = query::make_pull_query_history_ts(ts_high, ts_low); + + /* Create a non-transactional object. */ + pqxx::nontransaction N(*C); + + /* Execute SQL query */ + pqxx::result R( N.exec( query )); + + /* Parse result. */ + for (pqxx::result::const_iterator c = R.begin(); c != R.end(); ++c) { + tmp.coin = c[1].as(); + tmp.type = c[2].as(); + tmp.userid = c[3].as(); + tmp.quantity = c[4].as(); + tmp.timestamp = c[5].as(); + tmp.completed = c[6].as(); + tmp.price = c[7].as(); + + rop.transaction_list.push_back(tmp); + } + + return rop; + } + + /* Fetches unique user ids having transactions between ts_low and ts_high. */ + std::vector pull_userid_list_ts( pqxx::connection *C, long ts_high, long ts_low ) { + std::string query; + std::vector rop; + + query = query::make_pull_query_userid_list_ts(ts_high, ts_low); + + /* Create a non-transactional object. */ + pqxx::nontransaction N(*C); + + /* Execute SQL query */ + pqxx::result R( N.exec( query )); + + /* Parse result. */ + for (pqxx::result::const_iterator c = R.begin(); c != R.end(); ++c) { + rop.push_back(c[0].as()); + } + + return rop; + } + + /* Fetches all transactions by userid during period ts_low to ts_high. */ + ws_msg_parsed pull_transactions_userid_ts( pqxx::connection *C, std::string userid, long ts_high, long ts_low) { + std::string query; + ws_msg_parsed tmp; + ws_msg_parsed rop; + + query = query::make_pull_query_transactions_userid_ts(userid, ts_high, ts_low); + + /* Create a non-transactional object. */ + pqxx::nontransaction N(*C); + + /* Execute SQL query */ + pqxx::result R( N.exec( query )); + + /* Parse result. */ + for (pqxx::result::const_iterator c = R.begin(); c != R.end(); ++c) { + tmp.coin = c[1].as(); + tmp.type = c[2].as(); + tmp.userid = c[3].as(); + tmp.quantity = c[4].as(); + tmp.timestamp = c[5].as(); + tmp.completed = c[6].as(); + tmp.price = c[7].as(); + + rop.transaction_list.push_back(tmp); + } + + return rop; + } + + /* Fetches last cycle's transactions for userid. */ + ws_msg_parsed pull_last_cycle_userid( pqxx::connection *C, std::string userid) { + long ts_high, ts_low; + + ts_high = time(NULL)*1000; + ts_low = ts_high - 600*1000; + + return pull_transactions_userid_ts(C, userid, ts_high, ts_low); + } + + /******************************************************************************** + COIN PRICE + ********************************************************************************/ + void push_coin_price( pqxx::connection* C, ws_msg_parsed op) { + std::string query; + + query = query::make_push_query_coin_price(op); + + /* Create a transactional object. */ + pqxx::work W(*C); + + /* Execute SQL query */ + W.exec( query ); + W.commit(); + } + + + /******************************************************************************** + USERS + ********************************************************************************/ + // TODO: goes into common or algo + void ReplaceAll(std::string &str, const std::string& from, const std::string& to) { + size_t start_pos = 0; + while((start_pos = str.find(from, start_pos)) != std::string::npos) { + str.replace(start_pos, from.length(), to); + start_pos += to.length(); // Handles case where 'to' is a substring of 'from' + } + } + void push_users( pqxx::connection* C, std::vector op){ + std::string query; + std::string tmp; + + for(auto& user : op){ + tmp = user.username; + ReplaceAll(tmp, "'", "\\'"); + user.username = tmp; + query += query::make_push_query_user(user); + } + + /* Create a transactional object. */ + pqxx::work W(*C); + + /* Execute SQL query */ + W.exec( query ); + W.commit(); + } + + std::string userid_to_username(pqxx::connection* C, std::string userid){ + std::string query; + query = query::make_pull_query_userid_to_username(userid); + + /* Create a non-transactional object. */ + pqxx::nontransaction N(*C); + + /* Execute SQL query */ + pqxx::result R( N.exec( query )); + + return (R.begin())[0].as(); + + } +} diff --git a/nasfaq/connections/sql/db_handle.h b/nasfaq/connections/sql/db_handle.h new file mode 100644 index 0000000..05e0181 --- /dev/null +++ b/nasfaq/connections/sql/db_handle.h @@ -0,0 +1,50 @@ +#ifndef _DB_HANDLE_H_ +#define _DB_HANDLE_H_ + +#include +#include +#include +#include + +#include "../common/common.h" + + +/* DB API to store and fetch data. */ +namespace db { + namespace query { + std::string make_pull_query_last_n_spaced_prices(std::string, int, int); + } + + + /******************************************************************************** + HISTORY + ********************************************************************************/ + void push_history( pqxx::connection*, ws_msg_parsed ); + + ws_msg_parsed pull_last_cycle( pqxx::connection*); + std::vector pull_userid_list_ts( pqxx::connection *, long, long); + ws_msg_parsed pull_transactions_userid_ts( pqxx::connection *, std::string, long, long); + ws_msg_parsed pull_last_cycle_userid( pqxx::connection *, std::string); + + float pull_last_cycle_slope(pqxx::connection*, std::string); + + + + /******************************************************************************** + COIN PRICE + ********************************************************************************/ + void push_coin_price( pqxx::connection*, ws_msg_parsed ); + + /******************************************************************************** + COIN PRICE + ********************************************************************************/ + std::string userid_to_username(pqxx::connection*, std::string userid); + + /******************************************************************************** + USERS + ********************************************************************************/ + void push_users( pqxx::connection*, std::vector ); + std::string userid_to_username(pqxx::connection*, std::string userid); +} +#endif + diff --git a/nasfaq/connections/sql/db_init.cpp b/nasfaq/connections/sql/db_init.cpp new file mode 100644 index 0000000..fd14ecd --- /dev/null +++ b/nasfaq/connections/sql/db_init.cpp @@ -0,0 +1,157 @@ +#include "db_init.h" + +namespace db { + +int create_table_history(pqxx::connection& C) { + std::string query; + + try { + /* Create a transactional object. */ + pqxx::work W(C); + + /* Create sql query for history table creation */ + query = "CREATE TABLE IF NOT EXISTS HISTORY(" \ + "ID SERIAL PRIMARY KEY NOT NULL," \ + "COIN CHAR(32) NOT NULL,"\ + "TYPE INT,"\ + "USERID CHAR(128) NOT NULL,"\ + "QUANTITY INT,"\ + "TIMESTAMP BIGINT NOT NULL,"\ + "COMPLETED BOOLEAN,"\ + "PRICE REAL);"; + + /* Execute SQL query */ + W.exec( query ); + W.commit(); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + return 1; + } + return 0; +} + +int create_table_coin_price(pqxx::connection& C) { + std::string query; + + try { + /* Create a transactional object. */ + pqxx::work W(C); + + /* Create sql query for history table creation */ + query = "CREATE TABLE IF NOT EXISTS COINPRICE(" \ + "COIN CHAR(32) PRIMARY KEY,"\ + "PRICE REAL," \ + "SALEVALUE REAL," \ + "INCIRCULATION INT, "\ + "LASTUPDATE BIGINT);"; + + /* Execute SQL query */ + W.exec( query ); + W.commit(); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + return 1; + } + return 0; +} + +int create_last_n_anchor_prices_function(pqxx::connection& C) { + std::string query; + + try { + /* Create a transactional object. */ + pqxx::work W(C); + + /* Create sql query for spaced prices function, delta is in seconds*/ + query = "CREATE OR REPLACE FUNCTION last_n_spaced_prices(var_coin CHAR(32), var_n INT, var_delta INT) RETURNS SETOF HISTORY AS $$" \ + "DECLARE "\ + " row HISTORY%ROWTYPE; "\ + " cur_date BIGINT = 9223372036854775806; "\ + " nb_dates INT = 0; "\ + " nb_dates_max INT = var_n; "\ + "BEGIN "\ + " FOR row IN "\ + " SELECT * "\ + " FROM HISTORY "\ + " WHERE HISTORY.COIN = var_coin "\ + " ORDER BY TIMESTAMP DESC "\ + " LOOP "\ + " IF nb_dates = nb_dates_max "\ + " THEN "\ + " EXIT; "\ + " END IF; "\ + " "\ + " IF row.TIMESTAMP <= cur_date - var_delta*1000 OR cur_date IS NULL "\ + " THEN "\ + " cur_date := row.TIMESTAMP; "\ + " nb_dates := nb_dates + 1; "\ + " RETURN NEXT row; "\ + " END IF; "\ + " END LOOP; "\ + "END; "\ + "$$ LANGUAGE plpgsql; "; + + /* Execute SQL query */ + W.exec( query ); + W.commit(); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + return 1; + } + return 0; + +} + +int create_table_users(pqxx::connection& C) { + std::string query; + + try { + /* Create a transactional object. */ + pqxx::work W(C); + + /* Create sql query for history table creation */ + query = "CREATE TABLE IF NOT EXISTS USERS(" \ + "USERID CHAR(128) PRIMARY KEY,"\ + "USERNAME TEXT NOT NULL,"\ + "ICON CHAR(32) NOT NULL,"\ + "NETWORTH REAL);"; + + /* Execute SQL query */ + W.exec( query ); + W.commit(); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + return 1; + } + return 0; + +} + + +int populate() { + try { + pqxx::connection C("dbname = nasfaq user = steaky \ + hostaddr = 127.0.0.1 port = 5432"); + + if (C.is_open()) { + std::cout << "Opened database successfully: " << C.dbname() << std::endl; + } else { + std::cout << "Can't open database" << std::endl; + return 1; + } + + /* Create tables. */ + create_table_history(C); + create_table_coin_price(C); + create_table_users(C); + + /* Create functions. */ + create_last_n_anchor_prices_function(C); + + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + return 1; + } + return 0; +} +} diff --git a/nasfaq/connections/sql/db_init.h b/nasfaq/connections/sql/db_init.h new file mode 100644 index 0000000..20bf5b0 --- /dev/null +++ b/nasfaq/connections/sql/db_init.h @@ -0,0 +1,19 @@ +#ifndef _DB_INIT_H_ +#define _DB_INIT_H_ + +#include +#include +#include +#include + +#include "../http/users.h" + +namespace db { + int create_table_history(pqxx::connection&); + int create_table_coin_price(pqxx::connection&); + int create_table_users(pqxx::connection&); + int populate(); +} + +#endif + diff --git a/nasfaq/connections/test/graph b/nasfaq/connections/test/graph new file mode 100755 index 0000000..b0e1b9c Binary files /dev/null and b/nasfaq/connections/test/graph differ diff --git a/nasfaq/connections/test/graph.cpp b/nasfaq/connections/test/graph.cpp new file mode 100644 index 0000000..e7d61fa --- /dev/null +++ b/nasfaq/connections/test/graph.cpp @@ -0,0 +1,11 @@ +#include +#include + +#include "../common/common.h" +#include "../../maths/graph.h" + + +int main(void) { + test(); + return 1; +} diff --git a/nasfaq/connections/test/graph.html b/nasfaq/connections/test/graph.html new file mode 100644 index 0000000..465f39b --- /dev/null +++ b/nasfaq/connections/test/graph.html @@ -0,0 +1,227 @@ + + + + +
+

+
+ + + + + + + + +
+ +
+
+
0%
+
+
+
+
+
+ + +
+ + + + \ No newline at end of file diff --git a/nasfaq/connections/test/graph.json b/nasfaq/connections/test/graph.json new file mode 100644 index 0000000..b76f351 --- /dev/null +++ b/nasfaq/connections/test/graph.json @@ -0,0 +1,3335 @@ +{ + " [造] ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "0 ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "35P ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "6letters ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Acedia ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Anemachi Holdings LLC ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Ars Vie ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Asdae ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Blasphemer ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Bombshell Blondes Banking ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Crest Industries ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "East Aldenard Trading Co. ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Fauna's Left Antler ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Gawrons(๑╹ᆺ╹) ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "GodEmperorJamal ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "GreenQuan ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "HFZArchiveAnon ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Haachama's Duck ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Holo Birding Association ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "IKZ ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "IllidanStormrage ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Imyourtarget ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "JFP ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Jim's Skeleton Emporium ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Joe ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Kaczynski Logistics Co. ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Kanamori Compliance ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "King Kazama ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Kitsune Holdings 🌽🦊🍔 ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Koog ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Lolibaba ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Lolicon Rights Fund ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Lurker Tako ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "M ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Mas F ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Mr. Wizard ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Mr.Daddy Paddy ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Multi-Level Marketing ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "NIQQAMURDERER ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "NenePro Ltd. ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Nerd ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Nesp ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Ninjin ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Owligarch ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Patrick Bateman ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "PonRyS ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Reaper Sans Frontières ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Retard ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Rin ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Roboco Ch. - ロボ子 ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Shikemura Elite Holdings K.K. ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Sino-Austrian Unity Bank ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Sky Finance (On Break) ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Sneed ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Soppy ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Tako Inastments™ ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Tako Instruments ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Tenshi X Tenshi ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "The Tampa Bay Buccaneers ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "TheDuke ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Ț̸̿h̴̕͜e̴̞̚ ̷̨͋V̶͕̚ơ̶̯i̶̚͜d̶̖̉ ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Watomato ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Watoto Dispensary ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "WhatDoesTheButtonDo ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Wooper Wednesday ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "YourKStalker ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "Z ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "[1 Free Financial Advice] ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "[造] Applause ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "[造] LemonyLC ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "[造] Miyatsuko-Nino Treasury ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "[造] Touching Fluffy Tails Management Co. ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "[造] Triangle Consulting ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "[造] pagibot ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "bread will come back... right?! ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "bucca ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "cron ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "cutegirl420 ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "cypherposter ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "jup ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "littlepjs ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "mogu ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "nzm ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "ocean goblin ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "sneedster11 ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "tomatokun ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "towasamarich ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "uuuu ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "watamate ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "wtfamidoing ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "zezajon ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "☢️ アイキシウム発電所 ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "⚓smiles🌸 ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "クソメスガキEnjoyer ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "ポルカの夫🎪 ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "关注嘉然顿顿解馋 ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "暗闇の中でダンサー ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "🎪 𝐘𝐨𝐧𝐣𝐮 𝐀𝐫𝐜𝐡𝐢𝐭𝐞𝐜𝐭𝐬 𝐊.𝐊. ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "💕HeartAttack💓 Financials ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "💥💥Boom Boom💥💥 ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + }, + "🤖 ": { + "0 ": 4.0, + "Acedia ": 7.874007701873779, + "Anemachi Holdings LLC ": 8.124038696289063, + "Blasphemer ": 6.0, + "GodEmperorJamal ": 6.324555397033691, + "IllidanStormrage ": 3.872983455657959, + "Imyourtarget ": 3.1622776985168457, + "Kaczynski Logistics Co. ": 5.4772257804870605, + "King Kazama ": 9.486832618713379, + "Koog ": 5.4772257804870605, + "Lurker Tako ": 8.485280990600586, + "Mr. Wizard ": 8.366600036621094, + "Nesp ": 5.830951690673828, + "Owligarch ": 4.358899116516113, + "Retard ": 6.480740547180176, + "Sino-Austrian Unity Bank ": 7.549834251403809, + "TheDuke ": 5.830951690673828, + "YourKStalker ": 8.426149368286133, + "[1 Free Financial Advice] ": 5.0, + "[造] LemonyLC ": 9.591663360595703, + "[造] Touching Fluffy Tails Management Co. ": 6.244997978210449, + "bucca ": 4.4721360206604, + "cutegirl420 ": 5.74456262588501, + "jup ": 8.246211051940918, + "nzm ": 7.071067810058594, + "tomatokun ": 9.797959327697754, + "wtfamidoing ": 5.830951690673828, + "zezajon ": 7.549834251403809, + "⚓smiles🌸 ": 9.165151596069336, + "关注嘉然顿顿解馋 ": 9.949873924255371, + "🤖 ": 4.242640495300293 + } +} diff --git a/nasfaq/connections/test/graph_run.sh b/nasfaq/connections/test/graph_run.sh new file mode 100755 index 0000000..a5255d4 --- /dev/null +++ b/nasfaq/connections/test/graph_run.sh @@ -0,0 +1,4 @@ +g++ ../common/common.cpp \ + ../../maths/graph.cpp \ + graph.cpp \ + -L/usr/lib -lgvc -lcgraph -lfmt -lpqxx -lpq -o graph && ./graph diff --git a/nasfaq/connections/test/http_run.sh b/nasfaq/connections/test/http_run.sh deleted file mode 100755 index 76966eb..0000000 --- a/nasfaq/connections/test/http_run.sh +++ /dev/null @@ -1,3 +0,0 @@ -clang++ ../http/http_connector.cpp \ - ./main_http.cpp \ - -o main_http -lcurl && ./main_http diff --git a/nasfaq/connections/test/main b/nasfaq/connections/test/main index b13c4fd..89d3cdc 100755 Binary files a/nasfaq/connections/test/main and b/nasfaq/connections/test/main differ diff --git a/nasfaq/connections/test/main.cpp b/nasfaq/connections/test/main.cpp index cc14920..2fe251e 100644 --- a/nasfaq/connections/test/main.cpp +++ b/nasfaq/connections/test/main.cpp @@ -1,11 +1,95 @@ -#include "../http/http_connector.h" -#include "../ws/my_ssl.h" -#include "../safe_queue/safe_queue.h" -#include "../parser/parser.h" #include "../common/common.h" +#include "../http/http_connector.h" +#include "../http/users.h" +#include "../ws/http_handshake.h" +#include "../safe_queue/safe_queue.h" +#include "../ws/ssl_ws.h" +#include "../sql/db_init.h" +#include "../sql/db_handle.h" +#include "../parser/parser.h" + +int connect_ws() { + + bool done = false; + std::string input; + ws::websocket_endpoint endpoint; + + /* Get session id */ + std::string sid = ws::http_handshake::get_sid(); + + /* Start connection */ + std::string uri = "wss://nasfaq.biz/socket/?user=314d0bda-d7f0-4636-aed7-5ea02743604b&EIO=4&transport=websocket&sid=" + sid; + int id = endpoint.connect(uri); + if(id != -1) { + std::cout << ">Created nasfaq websocket connection" << std::endl; + } else { + return -1; + } + sleep(1); + + /* Display connection metadata */ + ws::connection_metadata::ptr metadata = endpoint.get_metadata(id); + if (metadata) { + std::cout << *metadata << std::endl; + } else { + std::cout << ">Unknown connection id " << id << std::endl; + } + + /* Populate database if needed. */ + db::populate(); + + /* Open up database connection. */ + pqxx::connection C("dbname = nasfaq user = steaky \ + hostaddr = 127.0.0.1 port = 5432"); + + if (C.is_open()) { + std::cout << "Opened database successfully: " << C.dbname() << std::endl; + } else { + std::cout << "Can't open database" << std::endl; + return 1; + } + + /* Update users. */ + db::push_users(&C, users::get_users()); + + /* Set up parser */ + parser::parser p(metadata, &C); + + /* Loop and print data through parser*/ + while(!done) { + input = std::cin.get(); + + if(input == "q" || input == "quit") { + done = true; + } else if (input == "p") { + std::cout << "PROCESSING QUEUE " << std::endl; + p.process_queue_start(); + } else if (input == "s") { + std::cout << "STOPPING QUEUE PROCESSING" << std::endl; + p.process_queue_stop(); + } else if (input == "t") { + std::cout << "TEST" << std::endl; + auto ret = db::pull_last_cycle(&C); + std::cout << ret << std::endl; + } + } + + /* Close websocket */ + std::stringstream ss(input); + + std::string cmd; + int close_code = websocketpp::close::status::normal; + std::string reason; + + ss >> cmd >> id >> close_code; + std::getline(ss, reason); + + endpoint.close(id, close_code, reason); + + return 0; +} int main(void) { - std::string sid = get_sid(); - connect_ws(sid); - + connect_ws(); + return 1; } diff --git a/nasfaq/connections/test/main_http b/nasfaq/connections/test/main_http deleted file mode 100755 index 439b991..0000000 Binary files a/nasfaq/connections/test/main_http and /dev/null differ diff --git a/nasfaq/connections/test/main_http.cpp b/nasfaq/connections/test/main_http.cpp deleted file mode 100644 index fa50dbd..0000000 --- a/nasfaq/connections/test/main_http.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "../http/http_connector.h" - -int main(void) { - get_sid(); - -} diff --git a/nasfaq/connections/test/output-[00.02.150-00.06.266]-[00.00.000-00.04.100].webm b/nasfaq/connections/test/output-[00.02.150-00.06.266]-[00.00.000-00.04.100].webm new file mode 100644 index 0000000..208fa85 Binary files /dev/null and b/nasfaq/connections/test/output-[00.02.150-00.06.266]-[00.00.000-00.04.100].webm differ diff --git a/nasfaq/connections/test/output-[00.02.150-00.06.266].webm b/nasfaq/connections/test/output-[00.02.150-00.06.266].webm new file mode 100644 index 0000000..26b8bff Binary files /dev/null and b/nasfaq/connections/test/output-[00.02.150-00.06.266].webm differ diff --git a/nasfaq/connections/test/output.mp4 b/nasfaq/connections/test/output.mp4 new file mode 100644 index 0000000..adb1f38 Binary files /dev/null and b/nasfaq/connections/test/output.mp4 differ diff --git a/nasfaq/connections/test/output_2.mp4 b/nasfaq/connections/test/output_2.mp4 new file mode 100644 index 0000000..a1a0971 Binary files /dev/null and b/nasfaq/connections/test/output_2.mp4 differ diff --git a/nasfaq/connections/test/output_trim.mp4 b/nasfaq/connections/test/output_trim.mp4 new file mode 100644 index 0000000..a1a0971 Binary files /dev/null and b/nasfaq/connections/test/output_trim.mp4 differ diff --git a/nasfaq/connections/test/parseGraph.py b/nasfaq/connections/test/parseGraph.py new file mode 100644 index 0000000..fdb179f --- /dev/null +++ b/nasfaq/connections/test/parseGraph.py @@ -0,0 +1,60 @@ +from pyvis.network import Network +import matplotlib.pyplot as plt +import networkx as nx +import pyvis +import json + +THRESHOLD = 10 + +def make_net(N, json_path): + with open(json_path, 'r') as f: + data = json.load(f) + + weighted_edges = [] + for parent, element in data.items(): + for child, weight in element.items(): + if parent == child: pass + elif weight > THRESHOLD: pass + else: + weighted_edges.append((parent, child, round(weight, 1))) + + # Add edges + N.add_weighted_edges_from(weighted_edges) + +def nudge(pos, x_shift, y_shift): + return {n:(x + x_shift, y + y_shift) for n,(x,y) in pos.items()} + +net = nx.Graph() +make_net(net, "graph.json") + +pos = nx.circular_layout(net) + +nx.draw_networkx( + net, pos, edge_color='black', width=1, linewidths=1, + node_size=100, node_color='pink', alpha=0.9, + with_labels = False) + #labels={node: node for node in net.nodes()} + +edge_labels = dict([((n1, n2), net[n1][n2]['weight']) + for n1, n2 in net.edges]) + +#nx.draw_networkx_edge_labels( +# net, pos, +# edge_labels=edge_labels, +# font_color='red' +#) + + +pretty_net = Network(height='750px', width='100%', bgcolor='#222222', font_color='white') +pretty_net.barnes_hut() +pretty_net.from_nx(net) +pretty_net.show_buttons(filter_=['physics']) + + + + +pretty_net.show("graph.html") + + +#plt.axis('off') +#plt.show() diff --git a/nasfaq/connections/test/run.sh b/nasfaq/connections/test/run.sh index 04676f8..be03905 100755 --- a/nasfaq/connections/test/run.sh +++ b/nasfaq/connections/test/run.sh @@ -1,7 +1,11 @@ -clang++ ../common/common.cpp \ - ../parser/parser.cpp \ - ../safe_queue/safe_queue.cpp \ +g++ ../safe_queue/safe_queue.cpp \ + ../common/common.cpp \ ../http/http_connector.cpp \ - ../ws/my_ssl.cpp \ + ../http/users.cpp \ + ../ws/ssl_ws.cpp \ + ../sql/db_init.cpp \ + ../sql/db_handle.cpp \ + ../parser/parser.cpp \ + ../ws/http_handshake.cpp \ ./main.cpp \ - -o main -lcurl -lcrypto -lssl -lboost_system -lboost_random -lboost_thread -lpthread && ./main + -o main -lpqxx -lpq -lfmt -lcurl -lcrypto -lssl -lboost_system -lboost_random -lboost_thread -lpthread && ./main diff --git a/nasfaq/connections/test/sql b/nasfaq/connections/test/sql new file mode 100755 index 0000000..5a4e2c5 Binary files /dev/null and b/nasfaq/connections/test/sql differ diff --git a/nasfaq/connections/test/sql.cpp b/nasfaq/connections/test/sql.cpp new file mode 100644 index 0000000..ed6ef7e --- /dev/null +++ b/nasfaq/connections/test/sql.cpp @@ -0,0 +1,62 @@ +#include "../common/common.h" +#include "../sql/db_init.h" +#include "../sql/db_handle.h" +#include "../../maths/maths.h" +#include "../../maths/graph.h" + +int connect_db() { + + bool done = false; + std::string input; + + /* Populate database if needed. */ + db::populate(); + + /* Open up database connection. */ + pqxx::connection C("dbname = nasfaq user = steaky \ + hostaddr = 127.0.0.1 port = 5432"); + + if (C.is_open()) { + std::cout << "Opened database successfully: " << C.dbname() << std::endl; + } else { + std::cout << "Can't open database" << std::endl; + return 1; + } + + /* Loop and print data through parser*/ + while(!done) { + input = std::cin.get(); + + if(input == "q" || input == "quit") { + done = true; + } else if (input == "t") { + std::string coin = "miko"; + //float s = db::pull_last_cycle_slope(&C, coin); + float ws = optimizer::get_last_n_weighted_slope(&C, coin, 2, 600); + std::cout << "slope: " << ws << std::endl; + } else if (input == "d") { + long ts_low, ts_high; + float threshold; + + std::vector userids; + std::map> result; + + ts_high = time(NULL)*1000; + ts_low = ts_high - 600*1000; + threshold = 10; + + userids = db::pull_userid_list_ts(&C, ts_high, ts_low); + result = norm::diff_map(&C, userids, ts_high, ts_low, threshold); + + //make_graph_from_map(result); + norm::diff_save_json(&C, result); + } + } + + return 0; +} + +int main(void) { + connect_db(); + return 1; +} diff --git a/nasfaq/connections/test/sql_run.sh b/nasfaq/connections/test/sql_run.sh new file mode 100755 index 0000000..a98cc39 --- /dev/null +++ b/nasfaq/connections/test/sql_run.sh @@ -0,0 +1,7 @@ +g++ ../common/common.cpp \ + ../sql/db_init.cpp \ + ../sql/db_handle.cpp \ + ../../maths/maths.cpp \ + ../../maths/graph.cpp \ + sql.cpp \ + -L/usr/lib -lgvc -lcgraph -lfmt -lpqxx -lpq -o sql && ./sql diff --git a/nasfaq/connections/ws/http_handshake.cpp b/nasfaq/connections/ws/http_handshake.cpp new file mode 100644 index 0000000..07d9ac0 --- /dev/null +++ b/nasfaq/connections/ws/http_handshake.cpp @@ -0,0 +1,35 @@ +#include "http_handshake.h" + +namespace ws { + namespace http_handshake { + std::string get_sid() { + static const char *POLLING_URL_0 = "https://nasfaq.biz/socket/?EIO=4&transport=polling&t=Ny7z439"; + static const char *POLLING_URL_1 = "https://nasfaq.biz/socket/?user=314d0bda-d7f0-4636-aed7-5ea02743604b&EIO=4&transport=polling&t=Ny7z472"; + static const char *POLLING_URL_2 = "https://nasfaq.biz/socket/?user=314d0bda-d7f0-4636-aed7-5ea02743604b&EIO=4&transport=polling&t=Ny7z4Bn&sid="; + static const char *POLLING_URL_3 = "https://nasfaq.biz/socket/?user=314d0bda-d7f0-4636-aed7-5ea02743604b&EIO=4&transport=polling&t=Ny7z4Bp&sid="; + static const char *POLLING_URL_4 = "https://nasfaq.biz/socket/?user=314d0bda-d7f0-4636-aed7-5ea02743604b&EIO=4&transport=polling&t=Ny7z4EU&sid="; + nlohmann::json json_ret; + std::string sid; + + nsfq_http::http_connector::connector c; + + /* Start handshake, first result is discarded. */ + c.get(POLLING_URL_0); + c.get(POLLING_URL_1); + + /* Get session id for websocket. */ + json_ret = nlohmann::json::parse(c.get_buffer().substr(1)); + sid = json_ret["sid"]; + + /* Post "40" acknowledgement with sid. */ + c.post(POLLING_URL_2 + sid, "40"); + + /* Continue handshake (might be unneeded). See XHR trace. */ + //c.get(POLLING_URL_3 + sid); + //c.get(POLLING_URL_4 + sid); + + return sid; + } + } + +} diff --git a/nasfaq/connections/ws/http_handshake.h b/nasfaq/connections/ws/http_handshake.h new file mode 100644 index 0000000..f4e225b --- /dev/null +++ b/nasfaq/connections/ws/http_handshake.h @@ -0,0 +1,19 @@ +#ifndef _HTTP_HANDSHAKE_H_ +#define _HTTP_HANDSHAKE_H_ + +#include +#include +#include +#include +#include + +#include "../http/http_connector.h" + +namespace ws { + namespace http_handshake { + std::string get_sid(); + } +} + +#endif + diff --git a/nasfaq/connections/ws/my_ssl.cpp b/nasfaq/connections/ws/my_ssl.cpp deleted file mode 100644 index 1b7d536..0000000 --- a/nasfaq/connections/ws/my_ssl.cpp +++ /dev/null @@ -1,334 +0,0 @@ -#include "my_ssl.h" - -typedef websocketpp::client client; -typedef std::shared_ptr context_ptr; - -class connection_metadata { -public: - typedef websocketpp::lib::shared_ptr ptr; - - connection_metadata(client *endpoint, int id, websocketpp::connection_hdl hdl, std::string uri) - : m_id(id) - , m_hdl(hdl) - , m_status("Connecting") - , m_uri(uri) - , m_server("N/A") - , m_endpoint(endpoint) // I really hate this, maybe the whole send function altogether should be in this class? - {} - - void on_open(client *c, websocketpp::connection_hdl hdl) { - websocketpp::lib::error_code ec; - m_status = "Open"; - - client::connection_ptr con = c->get_con_from_hdl(hdl); - m_server = con->get_response_header("Server"); - - sleep(1); /* How to wait for status? */ - m_endpoint->send(m_hdl, "2probe", websocketpp::frame::opcode::text, ec); - if (ec) { - std::cout << "> Error sending 2probe: " << ec.message() << std::endl; - return; - } - - sleep(1); /* How to wait for status? */ - m_endpoint->send(m_hdl, "5", websocketpp::frame::opcode::text, ec); - if (ec) { - std::cout << "> Error sending 5: " << ec.message() << std::endl; - return; - } - } - - void on_fail(client *c, websocketpp::connection_hdl hdl) { - m_status = "Failed"; - - client::connection_ptr con = c->get_con_from_hdl(hdl); - m_server = con->get_response_header("Server"); - m_error_reason = con->get_ec().message(); - } - - void on_close(client *c, websocketpp::connection_hdl hdl) { - m_status = "Closed"; - - client::connection_ptr con = c->get_con_from_hdl(hdl); - std::stringstream s; - s << "close code: " << con->get_remote_close_code() << " (" - << websocketpp::close::status::get_string(con->get_remote_close_code()) - << "), close reason: " << con->get_remote_close_reason(); - m_error_reason = s.str(); - } - - void on_message(websocketpp::connection_hdl hdl, client::message_ptr msg) { - if (msg->get_opcode() == websocketpp::frame::opcode::text) { - std::string payload = msg->get_payload(); - - if (payload == "2") { - websocketpp::lib::error_code ec; - m_endpoint->send(m_hdl, "3", websocketpp::frame::opcode::text, ec); - if (ec) { - std::cout << "> Error sending pong 3: " << ec.message() << std::endl; - return; - } - - } else if (payload.substr(0, 2) == "42") { - /* Add message to a raw struct and pass to parser */ - raw_message_t rmsg; /* should be cached somewhere? */ - rmsg.type = msg_type_detect(payload.substr(2, 20)); /* Get message type, this should be out of this loop and encompassing the pongs and probes */ - rmsg.data = payload.substr(3, payload.length() - 1); /* Should use regex */ - - std::cout << "Got payload of type: " << rmsg.type << std::endl; - - //nlohmann::json jres = nlohmann::json::parse(payload.substr(21, payload.length()-21-1)); - m_messages.push_back(payload); - } - } - } - - websocketpp::connection_hdl get_hdl() const { - return m_hdl; - } - - int get_id() const { - return m_id; - } - - std::string get_status() const { - return m_status; - } - - friend std::ostream & operator<< (std::ostream & out, connection_metadata const & data); - - void record_sent_message(std::string message) { - m_messages.push_back(">> " + message); - } - -private: - int m_id; - websocketpp::connection_hdl m_hdl; - std::string m_status; - std::string m_uri; - std::string m_server; - std::string m_error_reason; - std::vector m_messages; - client *m_endpoint; -}; - -std::ostream & operator<< (std::ostream & out, connection_metadata const & data) { - out - - << "> URI: " << data.m_uri << "\n" - << "> Status: " << data.m_status << "\n" - << "> Remote Server: " << (data.m_server.empty() ? "None Specified" : data.m_server) << "\n" - << "> Error/close reason: " << (data.m_error_reason.empty() ? "N/A" : data.m_error_reason); - - std::vector::const_iterator it; - for (it = data.m_messages.begin(); it != data.m_messages.end(); ++it) { - out << *it << "\n"; - } - - return out; -} - -static context_ptr on_tls_init() { - // establishes a SSL connection - context_ptr ctx = std::make_shared(boost::asio::ssl::context::sslv23); - - try { - ctx->set_options(boost::asio::ssl::context::default_workarounds | - boost::asio::ssl::context::no_sslv2 | - boost::asio::ssl::context::no_sslv3 | - boost::asio::ssl::context::single_dh_use); - } catch (std::exception &e) { - std::cout << "Error in context pointer: " << e.what() << std::endl; - } - return ctx; -} - -class websocket_endpoint { -public: - websocket_endpoint() { - m_endpoint.clear_access_channels(websocketpp::log::alevel::all); - m_endpoint.clear_error_channels(websocketpp::log::elevel::all); - - m_endpoint.init_asio(); - m_endpoint.set_tls_init_handler(bind(&on_tls_init)); - m_endpoint.start_perpetual(); - m_thread.reset(new websocketpp::lib::thread(&client::run, &m_endpoint)); - } - - ~websocket_endpoint() { - m_endpoint.stop_perpetual(); - - for (con_list::const_iterator it = m_connection_list.begin(); it != m_connection_list.end(); ++it) { - if (it->second->get_status() != "Open") { - // Close only open connections - continue; - } - - std::cout << "> Closing connection " << it->second->get_id() << std::endl; - - websocketpp::lib::error_code ec; - m_endpoint.close(it->second->get_hdl(), websocketpp::close::status::going_away, "", ec); - if (ec) { - std::cout << "> Error closing connection " << it->second->get_id() << ": " - << ec.message() << std::endl; - } - } - } - - int connect(std::string const &uri) { - websocketpp::lib::error_code ec; - - client::connection_ptr con = m_endpoint.get_connection(uri, ec); - con->append_header("Cookie", "holosesh=s%3AxmS8xBlQk4kH_rXQOaNjHk_3OuaBDsfA.M0yi%2BZmkiq%2BAmJBRj%2FNg9S%2BaSQpsfHRJcEeYVHLiKXg"); - - if(ec) { - std::cout << ">Connect initialization error: " << ec.message() << std::endl; - return -1; - } - - int new_id = m_next_id++; - connection_metadata::ptr metadata_ptr(new connection_metadata(&m_endpoint, new_id, con->get_handle(), uri)); - m_connection_list[new_id] = metadata_ptr; - - con->set_open_handler(websocketpp::lib::bind( - &connection_metadata::on_open, - metadata_ptr, - &m_endpoint, - websocketpp::lib::placeholders::_1 - )); - con->set_fail_handler(websocketpp::lib::bind( - &connection_metadata::on_fail, - metadata_ptr, - &m_endpoint, - websocketpp::lib::placeholders::_1 - )); - con->set_message_handler(websocketpp::lib::bind( - &connection_metadata::on_message, - metadata_ptr, - websocketpp::lib::placeholders::_1, - websocketpp::lib::placeholders::_2 - )); - - m_endpoint.connect(con); - - return new_id; - } - - void close(int id, websocketpp::close::status::value code, std::string reason) { - websocketpp::lib::error_code ec; - - con_list::iterator metadata_it = m_connection_list.find(id); - if (metadata_it == m_connection_list.end()) { - std::cout << "> No connection found with id " << id << std::endl; - return; - } - - m_endpoint.close(metadata_it->second->get_hdl(), code, "", ec); - if (ec) { - std::cout << "> Error initiating close: " << ec.message() << std::endl; - } - } - - void send(int id, std::string message) { - websocketpp::lib::error_code ec; - - con_list::iterator metadata_it = m_connection_list.find(id); - if (metadata_it == m_connection_list.end()) { - std::cout << "> No connection found with id " << id << std::endl; - return; - } - - m_endpoint.send(metadata_it->second->get_hdl(), message, websocketpp::frame::opcode::text, ec); - if (ec) { - std::cout << "> Error sending message: " << ec.message() << std::endl; - return; - } - - metadata_it->second->record_sent_message(message); - } - - connection_metadata::ptr get_metadata(int id) const { - con_list::const_iterator metadata_it = m_connection_list.find(id); - if(metadata_it == m_connection_list.end()) { - return connection_metadata::ptr(); - } else { - return metadata_it->second; - } - } -private: - typedef std::map con_list; - - client m_endpoint; - websocketpp::lib::shared_ptr m_thread; - - con_list m_connection_list; - int m_next_id; -}; - -int connect_ws(std::string sid) { - - bool done = false; - std::string input; - websocket_endpoint endpoint; - - while(!done) { - - std::cout << "Enter command: "; - std::getline(std::cin, input); - - if(input == "quit" || input == "q" ) done = true; - else if(input == "help") { - std::cout - << "\nCommand List:\n" - << "help: Display this help text\n" - << "quit: Exit the program\n" - << std::endl; - } else if (input.substr(0, 3) == "nsf") { - std::string uri = "wss://nasfaq.biz/socket/?user=314d0bda-d7f0-4636-aed7-5ea02743604b&EIO=4&transport=websocket&sid=" + sid; - int id = endpoint.connect(uri); - if(id != -1) { - std::cout << ">Created nsf connection with id " << id << std::endl; - } - } else if (input.substr(0, 7) == "connect") { - int id = endpoint.connect(input.substr(8)); - if(id != -1) { - std::cout << ">Created connection with id " << id << std::endl; - } - } else if (input.substr(0,4) == "show") { - int id = atoi(input.substr(5).c_str()); - - connection_metadata::ptr metadata = endpoint.get_metadata(id); - if (metadata) { - std::cout << *metadata << std::endl; - } else { - std::cout << ">Unknown connection id " << id << std::endl; - } - } else if (input.substr(0, 5) == "close") { - std::stringstream ss(input); - - std::string cmd; - int id; - int close_code = websocketpp::close::status::normal; - std::string reason; - - ss >> cmd >> id >> close_code; - std::getline(ss, reason); - - endpoint.close(id, close_code, reason); - } else if (input.substr(0,4) == "send") { - std::stringstream ss(input); - - std::string cmd; - int id; - std::string message = ""; - - ss >> cmd >> id; - std::getline(ss,message); - - endpoint.send(id, message); - } else { - std::cout << "Unrecognized command" << std::endl; - } - } - return 0; -} diff --git a/nasfaq/connections/ws/ssl_ws.cpp b/nasfaq/connections/ws/ssl_ws.cpp new file mode 100644 index 0000000..a99f66e --- /dev/null +++ b/nasfaq/connections/ws/ssl_ws.cpp @@ -0,0 +1,273 @@ +#include "ssl_ws.h" + +// TODO: rewrite this in the header + +namespace ws { + + connection_metadata::connection_metadata(client *endpoint, int id, websocketpp::connection_hdl hdl, std::string uri) + : m_id(id) + , m_hdl(hdl) + , m_status("Connecting") + , m_uri(uri) + , m_server("N/A") + , m_endpoint(endpoint) // I really hate this, maybe the whole send function altogether should be in this class? + {} + + void connection_metadata::on_open(client *c, websocketpp::connection_hdl hdl) { + websocketpp::lib::error_code ec; + m_status = "Open"; + + client::connection_ptr con = c->get_con_from_hdl(hdl); + m_server = con->get_response_header("Server"); + + sleep(1); /* How to wait for status? */ + m_endpoint->send(m_hdl, "2probe", websocketpp::frame::opcode::text, ec); + if (ec) { + std::cout << "> Error sending 2probe: " << ec.message() << std::endl; + return; + } + + sleep(1); /* How to wait for status? */ + m_endpoint->send(m_hdl, "5", websocketpp::frame::opcode::text, ec); + if (ec) { + std::cout << "> Error sending 5: " << ec.message() << std::endl; + return; + } + } + + void connection_metadata::on_fail(client *c, websocketpp::connection_hdl hdl) { + m_status = "Failed"; + + client::connection_ptr con = c->get_con_from_hdl(hdl); + m_server = con->get_response_header("Server"); + m_error_reason = con->get_ec().message(); + } + + void connection_metadata::on_close(client *c, websocketpp::connection_hdl hdl) { + m_status = "Closed"; + + client::connection_ptr con = c->get_con_from_hdl(hdl); + std::stringstream s; + s << "close code: " << con->get_remote_close_code() << " (" + << websocketpp::close::status::get_string(con->get_remote_close_code()) + << "), close reason: " << con->get_remote_close_reason(); + m_error_reason = s.str(); + } + + void connection_metadata::on_message(websocketpp::connection_hdl hdl, client::message_ptr msg) { + if (msg->get_opcode() == websocketpp::frame::opcode::text) { + std::string payload = msg->get_payload(); + + if (payload == "2") { + websocketpp::lib::error_code ec; + m_endpoint->send(m_hdl, "3", websocketpp::frame::opcode::text, ec); + if (ec) { + std::cout << "> Error sending pong 3: " << ec.message() << std::endl; + return; + } + + } else if (payload.substr(0, 2) == "42") { + std::string payload_format = payload.substr(3, payload.length() - 4); + push_message(payload_format); + } + } + } + + websocketpp::connection_hdl connection_metadata::get_hdl() const { + return m_hdl; + } + + int connection_metadata::get_id() const { + return m_id; + } + + std::string connection_metadata::get_status() const { + return m_status; + } + + /** + Should it use the cdt variable? + If it doesn't lock this thread up maybe, otherwise it should be defined externally. + Isn't the connection in another thread anyways? + */ + bool connection_metadata::msg_queue_empty(void) { + return m_msg_q.empty(); + } + + std::string connection_metadata::pop_message(void) { + std::unique_lock lock(m_msg_q_mutex); + while(m_msg_q.empty()) + { + // release lock as long as the wait and reaquire it afterwards. + m_msg_q_cdt.wait(lock); + } + std::string ret = m_msg_q.front(); + m_msg_q.pop(); + return ret; + } + + void connection_metadata::push_message(std::string msg) { + std::lock_guard lock(m_msg_q_mutex); + m_msg_q.push(msg); + m_msg_q_cdt.notify_one(); + } + + std::ostream & operator<< (std::ostream & out, connection_metadata const & data) { + out + << "> URI: " << data.m_uri << "\n" + << "> Status: " << data.m_status << "\n" + << "> Remote Server: " << (data.m_server.empty() ? "None Specified" : data.m_server) << "\n" + << "> Error/close reason: " << (data.m_error_reason.empty() ? "N/A" : data.m_error_reason); + return out; + } + + + + + + /******************************************************************************************* + Connection endpoint + *******************************************************************************************/ + + + + + + /** + TLS initialization. + */ + static context_ptr on_tls_init() { + // establishes a SSL connection + context_ptr ctx = std::make_shared(boost::asio::ssl::context::sslv23); + + try { + ctx->set_options(boost::asio::ssl::context::default_workarounds | + boost::asio::ssl::context::no_sslv2 | + boost::asio::ssl::context::no_sslv3 | + boost::asio::ssl::context::single_dh_use); + } catch (std::exception &e) { + std::cout << "Error in context pointer: " << e.what() << std::endl; + } + return ctx; + } + + + websocket_endpoint::websocket_endpoint() { + m_endpoint.clear_access_channels(websocketpp::log::alevel::all); + m_endpoint.clear_error_channels(websocketpp::log::elevel::all); + + m_endpoint.init_asio(); + m_endpoint.set_tls_init_handler(bind(&on_tls_init)); + m_endpoint.start_perpetual(); + m_thread.reset(new websocketpp::lib::thread(&client::run, &m_endpoint)); + } + + websocket_endpoint::~websocket_endpoint() { + m_endpoint.stop_perpetual(); + + for (con_list::const_iterator it = m_connection_list.begin(); it != m_connection_list.end(); ++it) { + if (it->second->get_status() != "Open") { + // Close only open connections + continue; + } + + std::cout << "> Closing connection " << it->second->get_id() << std::endl; + + websocketpp::lib::error_code ec; + m_endpoint.close(it->second->get_hdl(), websocketpp::close::status::going_away, "", ec); + if (ec) { + std::cout << "> Error closing connection " << it->second->get_id() << ": " + << ec.message() << std::endl; + } + } + } + + int websocket_endpoint::connect(std::string const &uri) { + websocketpp::lib::error_code ec; + + client::connection_ptr con = m_endpoint.get_connection(uri, ec); + con->append_header("Cookie", "holosesh=s%3AxmS8xBlQk4kH_rXQOaNjHk_3OuaBDsfA.M0yi%2BZmkiq%2BAmJBRj%2FNg9S%2BaSQpsfHRJcEeYVHLiKXg"); + + if(ec) { + std::cout << ">Connect initialization error: " << ec.message() << std::endl; + return -1; + } + + int new_id = m_next_id++; + connection_metadata::ptr metadata_ptr(new connection_metadata(&m_endpoint, new_id, con->get_handle(), uri)); + m_connection_list[new_id] = metadata_ptr; + + con->set_open_handler(websocketpp::lib::bind( + &connection_metadata::on_open, + metadata_ptr, + &m_endpoint, + websocketpp::lib::placeholders::_1 + )); + con->set_fail_handler(websocketpp::lib::bind( + &connection_metadata::on_fail, + metadata_ptr, + &m_endpoint, + websocketpp::lib::placeholders::_1 + )); + con->set_message_handler(websocketpp::lib::bind( + &connection_metadata::on_message, + metadata_ptr, + websocketpp::lib::placeholders::_1, + websocketpp::lib::placeholders::_2 + )); + + m_endpoint.connect(con); + + return new_id; + } + + void websocket_endpoint::close(int id, websocketpp::close::status::value code, std::string reason) { + websocketpp::lib::error_code ec; + + con_list::iterator metadata_it = m_connection_list.find(id); + if (metadata_it == m_connection_list.end()) { + std::cout << "> No connection found with id " << id << std::endl; + return; + } + + m_endpoint.close(metadata_it->second->get_hdl(), code, "", ec); + if (ec) { + std::cout << "> Error initiating close: " << ec.message() << std::endl; + } + } + + void websocket_endpoint::send(int id, std::string message) { + websocketpp::lib::error_code ec; + + con_list::iterator metadata_it = m_connection_list.find(id); + if (metadata_it == m_connection_list.end()) { + std::cout << "> No connection found with id " << id << std::endl; + return; + } + + m_endpoint.send(metadata_it->second->get_hdl(), message, websocketpp::frame::opcode::text, ec); + if (ec) { + std::cout << "> Error sending message: " << ec.message() << std::endl; + return; + } + + // metadata_it->second->record_sent_message(message); + } + + connection_metadata::ptr websocket_endpoint::get_metadata(int id) const { + con_list::const_iterator metadata_it = m_connection_list.find(id); + if(metadata_it == m_connection_list.end()) { + return connection_metadata::ptr(); + } else { + return metadata_it->second; + } + } + std::string websocket_endpoint::get_queue_front(int id) const { + con_list::const_iterator metadata_it = m_connection_list.find(id); + if(metadata_it == m_connection_list.end()) { + return ""; + } else { + return metadata_it->second->pop_message(); + } + } +} diff --git a/nasfaq/connections/ws/ssl_ws.h b/nasfaq/connections/ws/ssl_ws.h new file mode 100644 index 0000000..cdb295b --- /dev/null +++ b/nasfaq/connections/ws/ssl_ws.h @@ -0,0 +1,82 @@ +#ifndef _SSL_WS_H_ +#define _SSL_WS_H_ + +#include +#include +#include + +//#include "../parser/parser.h" +#include "../common/common.h" +#include "../safe_queue/safe_queue.h" + +#include +#include + +#include +#include + +#include + + +namespace ws { + typedef websocketpp::client client; + typedef std::shared_ptr context_ptr; + + class connection_metadata { + public: + typedef websocketpp::lib::shared_ptr ptr; + + connection_metadata(client*, int, websocketpp::connection_hdl, std::string); + + void on_open(client *, websocketpp::connection_hdl); + void on_fail(client *, websocketpp::connection_hdl); + void on_close(client *, websocketpp::connection_hdl); + void on_message(websocketpp::connection_hdl, client::message_ptr); + + websocketpp::connection_hdl get_hdl() const; + int get_id() const; + std::string get_status() const; + + friend std::ostream & operator<< (std::ostream &, connection_metadata const &); + + bool msg_queue_empty(void); + std::string pop_message(void); + + private: + int m_id; + websocketpp::connection_hdl m_hdl; + std::string m_status; + std::string m_uri; + std::string m_server; + std::string m_error_reason; + //std::vector m_messages; + client *m_endpoint; + std::queue m_msg_q; + mutable std::mutex m_msg_q_mutex; + std::condition_variable m_msg_q_cdt; + + void push_message(std::string); + }; + + + class websocket_endpoint { + public: + websocket_endpoint(); + ~websocket_endpoint(); + + int connect(std::string const &); + void close(int, websocketpp::close::status::value, std::string); + void send(int, std::string); + connection_metadata::ptr get_metadata(int) const; + std::string get_queue_front(int) const; + private: + typedef std::map con_list; + client m_endpoint; + websocketpp::lib::shared_ptr m_thread; + con_list m_connection_list; + int m_next_id; + }; +} + +#endif + diff --git a/nasfaq/maths/graph.cpp b/nasfaq/maths/graph.cpp new file mode 100644 index 0000000..1a3f463 --- /dev/null +++ b/nasfaq/maths/graph.cpp @@ -0,0 +1,55 @@ +#include "graph.h" + +//template +void make_graph_from_map(std::map> op) { + #ifndef NO_LAYOUT_OR_RENDERING + // set up a graphviz context - but only once even for multiple graphs + GVC_t *gvc = gvContext(); + #endif + + // Create a simple digraph + Agraph_t *g = agopen("g", Agundirected, 0); + + // Placeholders + Agnode_t *parent; + Agnode_t *child; + char float_buffer[64]; + + // Add vertices and edges + for (auto& userid1_map:op) { + parent = agnode(g, (char *)(userid1_map.first).c_str(), 1); + agsafeset(parent, "label", (char *)(userid1_map.first).c_str(), ""); + std::cout << "Parent: " << userid1_map.first << std::endl; + for (auto& element:userid1_map.second) { + child = agnode(g, (char *)(element.first).c_str(), 1); + agsafeset(parent, "label", (char *)(element.first).c_str(), ""); + + //std::cout << " Child: " << element.first << " Dist: " << element.second << std::endl; + Agedge_t *e = agedge(g, parent, child, 0, 1); + + // Convert float to char* + snprintf(float_buffer, sizeof(float_buffer), "%f", element.second); + agsafeset(e, "label", float_buffer, ""); + } + } + + // Set an attribute - in this case one that affects the visible rendering + //agsafeset(n, "color", "red", ""); + + #ifdef NO_LAYOUT_OR_RENDERING + // Just write the graph without layout + agwrite(g, savefile); + #else + // Use the directed graph layout engine + gvLayout(gvc, g, "dot"); + + // Output in .dot format + FILE *fptr = fopen("graph.dot", "w"); + gvRender(gvc, g, "dot", fptr); + fclose(fptr); + + gvFreeLayout(gvc, g); + #endif + + agclose(g); +} diff --git a/nasfaq/maths/graph.h b/nasfaq/maths/graph.h new file mode 100644 index 0000000..8857c41 --- /dev/null +++ b/nasfaq/maths/graph.h @@ -0,0 +1,18 @@ +#ifndef _GRAPH_H_ +#define _GRAPH_H_ + +#include +#include +#include +#include + +#include "../connections/common/common.h" + +#include +#include + +//template +void make_graph_from_map(std::map>); + +#endif + diff --git a/nasfaq/maths/maths.cpp b/nasfaq/maths/maths.cpp new file mode 100644 index 0000000..e149d10 --- /dev/null +++ b/nasfaq/maths/maths.cpp @@ -0,0 +1,199 @@ +#include "maths.h" + +namespace query { + const std::string query_template_slope_ts_bot = "SELECT PRICE, TIMESTAMP FROM HISTORY "\ + "WHERE COIN = '{}' AND TIMESTAMP <= {} AND TIMESTAMP > {} "\ + "ORDER BY TIMESTAMP DESC "\ + "LIMIT 1;"; + + const std::string query_template_last_n_spaced_prices = "select PRICE, TIMESTAMP FROM last_n_spaced_prices('{}', {}, {});"; +} + +namespace norm { + + float norm(cycle_t c) { + float rop = 0; + + for (auto const & element : c) { + rop += pow(element.second, 2); + } + return sqrt(rop); + } + + /* Should balance with weights. */ + cycle_t history_to_cycle(ws_msg_parsed op) { + cycle_t rop; + + for(auto const& element : op.transaction_list) { + rop[element.coin] = element.quantity * pow((-1), element.type); + } + + return rop; + } + + cycle_t diff_vector(cycle_t op1, cycle_t op2) { + cycle_t rop; + + rop = op1; + + for(auto const& element : op2) { + if (op1.count(element.first)) { + rop[element.first] -= element.second; + } else { + rop[element.first] = -element.second; + } + } + + return rop; + } + + int cycle_size(cycle_t op) { + int rop = 0; + for (auto const & element : op) { + rop += std::abs(element.second); + } + + return rop; + } + + std::map diff_all(pqxx::connection *C, cycle_t base_cycle, std::map cycles, std::vector userid_list, std::string userid, long ts_high, long ts_low, float threshold) { + std::map result; + cycle_t tmp1, tmp2; + float tmp_res; + + for(auto const& id : userid_list) { + tmp2 = cycles.find(id)->second; + if (cycle_size(tmp2) >= 10) { + tmp_res = norm(diff_vector(tmp1, tmp2)); + if (tmp_res < threshold) { + result[id] = tmp_res; + std::cout << "Difference between " << userid << " and " << id << " : " << result[id] << std::endl; + } + } + } + return result; + } + + std::map> diff_map(pqxx::connection *C, std::vector userids, long ts_high, long ts_low, float threshold){ + std::map> result; + std::map cycles; + std::map tmp; + + /* Prepare cycles from db. */ + for(auto const& id : userids) { + cycles.insert( std::pair(id, history_to_cycle(db::pull_last_cycle_userid(C, id))) ); + } + + for (auto& userid:userids) { + tmp = norm::diff_all(C, cycles[userid], cycles, userids, userid, ts_high, ts_low, threshold); + result.insert( std::pair>( userid, tmp )); + } + + return result; + } + + void diff_save_json( pqxx::connection *C, std::map> op) { + json j; + std::string parent, child; + + for (auto& userid1_map:op) { + parent = db::userid_to_username(C, userid1_map.first); + for (auto& element:userid1_map.second) { + child = db::userid_to_username(C, element.first); + j[parent][child] = element.second; + } + } + std::ofstream o("graph.json"); + o << std::setw(4) << j << std::endl; + } +} + +namespace optimizer{ + std::tuple get_last_nth_cycle_ts(int n) { + long ts_now, ts_top, ts_bot; + + ts_now = time(NULL); + ts_top = (ts_now - ts_now % 600) - n * 600; // floor (top) - n cycles + ts_bot = ts_top - (n+1) * 600; + + return std::make_tuple(ts_top * 1000, ts_bot * 1000); + } + + ///* Returns slope over last cycle. */ + //float pull_last_cycle_slope(pqxx::connection* C, std::string coin) { + // std::string query; + + // float price_top, price_bot, delta_p; + // float ts_top, ts_bot, delta_t; + // float slope; + + // pqxx::nontransaction N(*C); + // pqxx::result::const_iterator c; + // pqxx::result R; + + // auto [ts_high, ts_low] = optimizer::get_last_nth_cycle_ts(1); + // //ts_high = time(NULL)*1000; + // //ts_low = ts_high - 600*1000; + + // query = db::query::make_pull_query_top_price_cycle_ts(coin, ts_high, ts_low); + // R = N.exec( query ); + // c = R.begin(); + // price_top = c[0].as(); + // ts_top = c[1].as(); + + // query = db::query::make_pull_query_bot_price_cycle_ts(coin, ts_high, ts_low); + // R = N.exec( query ); + // c = R.begin(); + // price_bot = c[0].as(); + // ts_bot = c[1].as(); + + // slope = (price_top - price_bot) / ( (ts_top - ts_bot) ) * 1000 * 600; + // std::cout << "pt: " << price_top << " pb: " << price_bot << std::endl; + // std::cout << "tt: " << ts_top << " tb: " << ts_bot << std::endl; + + + // return slope; + //} + + float get_last_n_weighted_slope(pqxx::connection* C, std::string coin, int nb_cycles, int delta = 600) { + std::string query; + float wma, tmp_slope, price_top, price_bot; + double ts_top, ts_bot; + int weight, denum; + + query = db::query::make_pull_query_last_n_spaced_prices(coin, nb_cycles, delta); + + /* Create a non-transactional object. */ + pqxx::nontransaction N(*C); + + /* Execute SQL query */ + pqxx::result R( N.exec( query )); + + /* Parse result. */ + price_top = R[0][0].as(); + price_bot = R[1][0].as(); + ts_top = R[0][1].as(); + ts_bot = R[1][1].as(); + + tmp_slope = (price_top - price_bot) / (ts_top - ts_bot); + weight = nb_cycles; + + wma = weight * tmp_slope; + denum = weight; + + for (pqxx::result::const_iterator c = R.begin() + 1; c != R.end(); ++c) { + price_bot = price_top; + ts_bot = ts_top; + + price_top = c[0].as(); + ts_top = c[1].as(); + + weight--; + tmp_slope = (price_top - price_bot) / (ts_top - ts_bot); + wma += weight * tmp_slope; + denum += weight; + } + + return wma / denum * 1000 * 600; + } +} diff --git a/nasfaq/maths/maths.h b/nasfaq/maths/maths.h new file mode 100644 index 0000000..844cd80 --- /dev/null +++ b/nasfaq/maths/maths.h @@ -0,0 +1,28 @@ +#ifndef _MATHS_H_ +#define _MATHS_H_ + +#include +#include +#include +#include +using json = nlohmann::json; + +#include "../connections/common/common.h" +#include "../connections/sql/db_handle.h" + +namespace norm { + float norm(cycle_t); + cycle_t history_to_cycle(ws_msg_parsed); + cycle_t diff_vector(cycle_t, cycle_t); + std::map diff_all(pqxx::connection *C, cycle_t base_cycle, std::map cycles, std::vector userid_list, std::string userid, long ts_high, long ts_low, float threshold); + std::map> diff_map(pqxx::connection *C, std::vector userid_list, long, long, float); + void diff_save_json( pqxx::connection *, std::map>); +} + +namespace optimizer{ + std::tuple get_last_nth_cycle_ts(int); + float get_last_n_weighted_slope(pqxx::connection*, std::string, int, int); +} + +#endif + diff --git a/nasfaq/maths/optimizer/__pycache__/common.cpython-310.pyc b/nasfaq/maths/optimizer/__pycache__/common.cpython-310.pyc new file mode 100644 index 0000000..dd72fa2 Binary files /dev/null and b/nasfaq/maths/optimizer/__pycache__/common.cpython-310.pyc differ diff --git a/nasfaq/maths/optimizer/__pycache__/db_handle.cpython-310.pyc b/nasfaq/maths/optimizer/__pycache__/db_handle.cpython-310.pyc new file mode 100644 index 0000000..c55ceca Binary files /dev/null and b/nasfaq/maths/optimizer/__pycache__/db_handle.cpython-310.pyc differ diff --git a/nasfaq/maths/optimizer/__pycache__/http_handle.cpython-310.pyc b/nasfaq/maths/optimizer/__pycache__/http_handle.cpython-310.pyc new file mode 100644 index 0000000..2ddaf20 Binary files /dev/null and b/nasfaq/maths/optimizer/__pycache__/http_handle.cpython-310.pyc differ diff --git a/nasfaq/maths/optimizer/__pycache__/optimizer.cpython-310.pyc b/nasfaq/maths/optimizer/__pycache__/optimizer.cpython-310.pyc new file mode 100644 index 0000000..9f343a9 Binary files /dev/null and b/nasfaq/maths/optimizer/__pycache__/optimizer.cpython-310.pyc differ diff --git a/nasfaq/maths/optimizer/common.py b/nasfaq/maths/optimizer/common.py new file mode 100644 index 0000000..97484eb --- /dev/null +++ b/nasfaq/maths/optimizer/common.py @@ -0,0 +1,7 @@ +import json + +USERID = "314d0bda-d7f0-4636-aed7-5ea02743604b" + +URL_API = "https://nasfaq.biz/api/" + +COINS = ['aki', 'amelia', 'aqua', 'ayame', 'azki', 'botan', 'calliope', 'choco', 'civia', 'coco', 'flare', 'fubuki', 'gura', 'haato', 'himemoriluna', 'hololive', 'inanis', 'iofi', 'kanata', 'kiara', 'korone', 'lamy', 'marine', 'matsuri', 'mel', 'melfissa', 'miko', 'mio', 'moona', 'nana', 'nene', 'noel', 'okayu', 'ollie', 'pekora', 'polka', 'reine', 'risu', 'roboco', 'rushia', 'shion', 'sora', 'subaru', 'suisei', 'towa', 'ui', 'watame', 'laplus', 'lui', 'koyori', 'chloe', 'iroha', 'irys', 'sana', 'fauna', 'kronii', 'mumei', 'baelz'] diff --git a/nasfaq/maths/optimizer/db_handle.py b/nasfaq/maths/optimizer/db_handle.py new file mode 100644 index 0000000..acaa309 --- /dev/null +++ b/nasfaq/maths/optimizer/db_handle.py @@ -0,0 +1,47 @@ +import psycopg2 + +from common import * + +def get_db_connection(): + return psycopg2.connect(database="nasfaq", user = "steaky", host = "127.0.0.1", port = "5432") + +def fetch_wma_slope_all(cursor): + + slope_dict = {} + + nb_cycles = 2 + delta = 600 + + for coin in COINS: + tmp = 0 + weight = nb_cycles + wma = 0 + denum = 0 + + query = "select PRICE, TIMESTAMP FROM last_n_spaced_prices('{}', {}, {});".format(coin, nb_cycles, delta) + cursor.execute(query) + rows = cursor.fetchall() + + price_top = float(rows[0][0]) + price_bot = float(rows[1][0]) + ts_top = int(rows[0][1]) + ts_bot = int(rows[1][1]) + + tmp = (price_top - price_bot) / (ts_top - ts_bot) + wma = weight * tmp + denum = weight + + for row in rows[1::]: + price_bot = price_top + price_top = row[0] + ts_bot = ts_top + ts_top = row[1] + + weight -= 1 + tmp = (price_top - price_bot) / (ts_top - ts_bot) + wma += weight * tmp + denum += weight + + slope_dict[coin] = wma / denum * 1000 * 600 + + return slope_dict diff --git a/nasfaq/maths/optimizer/http_handle.py b/nasfaq/maths/optimizer/http_handle.py new file mode 100644 index 0000000..2c17264 --- /dev/null +++ b/nasfaq/maths/optimizer/http_handle.py @@ -0,0 +1,24 @@ +from common import * +import requests + +def fetch_marketInfo_all(): + url = URL_API + "getMarketInfo?all" + r = requests.get(url) + return r.json()['coinInfo']['data'] + +def fetch_coin_qty_all(): + rop = {} + + url = URL_API + "getUserWallet?userid=" + USERID + r = requests.get(url) + + for key, item in r.json()['wallet']['coins'].items(): + rop[key] = item['amt'] + + return rop + +def fetch_balance(): + url = URL_API + "getUserWallet?userid=" + USERID + r = requests.get(url) + + return r.json()['wallet']['balance'] diff --git a/nasfaq/maths/optimizer/main.py b/nasfaq/maths/optimizer/main.py new file mode 100644 index 0000000..1de08c0 --- /dev/null +++ b/nasfaq/maths/optimizer/main.py @@ -0,0 +1,46 @@ +import random + +from common import * +from optimizer import * +from db_handle import * +from http_handle import * + +if __name__ == '__main__': + C = get_db_connection() + cur = C.cursor() + + user_balance = fetch_balance() + coin_qty = fetch_coin_qty_all() + coin_prices = fetch_marketInfo_all() + wma_coins = fetch_wma_slope_all(cur) + #wma_coins = {coin:20 for coin in coin_prices.keys() } + + # Cut down for test + u = 0 + max_u = 10 + + smp_prices = {} + smp_wma = {} + #coins = ["lamy", "towa", "luna", "marine", "subaru", "aqua", "hololive"] + for key in coin_prices.keys(): + if u > max_u: break + else: + try: + a = wma_coins[key] + if abs(a) > 10: + smp_prices[key] = coin_prices[key] + smp_wma[key] = wma_coins[key] + u += 1 + except KeyError: + pass + + print("Coins prices: ") + print(smp_prices) + print("Coins wma: ") + print(smp_wma) + + M = 10 + nb_cycles = 144 + + sol = optimize(smp_wma, smp_prices, nb_cycles, M) + print(sol) diff --git a/nasfaq/maths/optimizer/optimizer.py b/nasfaq/maths/optimizer/optimizer.py new file mode 100644 index 0000000..ba9d299 --- /dev/null +++ b/nasfaq/maths/optimizer/optimizer.py @@ -0,0 +1,138 @@ +#import numpy as np +#import itertools +#import json +#import math +#import collections + +from common import * + +import matplotlib +import matplotlib.pyplot as plt + +from scipy.optimize import minimize + +from gekko import GEKKO +""" + Gekko function. + Function to minimize +""" +def to_optimize(x, S, a, nb_cycles, M, m): + local_gain = 0 + + t = m.if2(a, -1, 1) # type of trade + tax = m.if2(a, 0.035, 0.045) # type of tax + + for i in range(1, M): + mult = m.if2( x[0] - t*i, 0, x[0] - t*i) + delta = x[i+1] - x[i] + local_gain += t*mult*delta*( (S+a*nb_cycles) - (S+a*(x[i] + x[i+1] + 1)/2)*(1+t*tax*mult)) + + return -local_gain # We minimize the opposite function + +""" + GEKKO optimizer +""" +def optimize(wma_coins, coin_prices, nb_cycles, M): + + nb_rows, nb_cols = len(wma_coins.keys()), M + + # Transform dict to lists + coin_prices_list = [coin_prices[coin]["price"] for coin in coin_prices.keys()] + wma_coins_list = [wma_coins[coin] for coin in coin_prices.keys()] + + m = GEKKO(remote=False) + x = m.Array(m.Var, (nb_rows, nb_cols + 1), lb=0, ub=144, integer=True) # Lower bound is 0: no order, upper bound is 10: hyper-multicoining + + # Set multicoin bounds + for i in range(nb_rows): + x[i][0].value = 0 + x[i][0].lower = -10 + x[i][0].upper = 10 + + # constraints on cycles + for i in range(nb_rows): + for j in range(1, nb_cols): + m.Equation(x[i][j] <= x[i][j+1]) + + # EQUATIONS + for i in range(nb_rows): + m.Obj(to_optimize(x[i], coin_prices_list[i], wma_coins_list[i], nb_cycles, M, m)) + + + m.options.SOLVER=3 + m.options.IMODE = 3 + m.options.COLDSTART=1 + #m.solver_options = ['maximum_iterations 10000'] + + #m.Minimize(to_optimize(x, nb_rows, nb_cols, coin_prices_list, wma_coins_list, nb_cycles, m)) + m.solve(disp=True) + + return x + + +#def save_result(res): +# +# print(res) +# d = dict() +# for i in range(len(L)): +# d[L[i]] = round(int(res[i].value[0])) +# +# +# with open(PATH_OUT, "w") as f: +# json.dump(d, f) + +def display_strategy(x): + s = {} + m = -1 + index = 0 + toprint = "" + for i in range(len(x)): + if x[i] != m: + toprint = "[Change@" + str(i) + "\t:x" + str(int(x[i])) + "]" + m = x[i] + s[i] = x[i] + print(toprint) + return s + +def plot_results(x, s): + fig, ax = plt.subplots() + + M = len(x) + X = [i for i in range(M)] + + # Naive Strategies to plot + n_strats = [i for i in range(1, 5)] + + # Plot the straight strategies + for n in n_strats: + xx = [n for _ in range(M)] + Y = [to_optimize_(xx, m) for m in X] + ax.scatter(X, Y, marker = "+", label = "Constant x{}".format(n)) + + # Plot optimized strategy + Y = [to_optimize_(x, m) for m in X] + ax.scatter(X, Y, marker = "^", label = "Optimized") + + for cycle, n in s.items(): + ax.annotate("x{}".format(int(n)), textcoords = "offset pixels", xytext = (0, 10), xy = (X[cycle], Y[cycle])) + + # Display parameters + textstr = '\n'.join(( + r'Coin price at adjustment: {}'.format(S), + r'Tax baseline: {}'.format(T), + r'Slope extrapolation: {}'.format(a), + r'Number of cycles: {}'.format(M))) + props = dict(boxstyle='round', facecolor='white', alpha=0.5) + + # place a text box in upper left in axes coords + ax.text(0.12, 0.98, textstr, transform=ax.transAxes, fontsize=14, + verticalalignment='top', bbox=props) + + #ax.set_yscale("log") + #ax.set_xscale("log") + ax.legend(loc="upper left") + ax.set_xlabel("Cycle") + ax.set_ylabel("Profit") + ax.set_title("Profit using naive and optimized strategies") + ax.grid(True) + plt.show() diff --git a/nasfaq/maths/optimizer/trash/optimizer.cpp b/nasfaq/maths/optimizer/trash/optimizer.cpp new file mode 100644 index 0000000..b4d7af0 --- /dev/null +++ b/nasfaq/maths/optimizer/trash/optimizer.cpp @@ -0,0 +1,38 @@ +#include "optimizer.h" + +namespace operations_research { +void BasicExample() { + // Create the linear solver with the GLOP backend. + std::unique_ptr solver(MPSolver::CreateSolver("SCIP")); + if (!solver) { + LOG(WARNING) << "SCIP solver unavailable."; + return; + } + + // Create the variables x and y. + MPVariable* const x = solver->MakeIntVar(0.0, 1, "x"); + MPVariable* const y = solver->MakeIntVar(0.0, 2, "y"); + + LOG(INFO) << "Number of variables = " << solver->NumVariables(); + + // Create a linear constraint, 0 <= x + y <= 2. + MPConstraint* const ct = solver->MakeRowConstraint(0.0, 2.0, "ct"); + ct->SetCoefficient(x, 1); + ct->SetCoefficient(y, 1); + + LOG(INFO) << "Number of constraints = " << solver->NumConstraints(); + + // Create the objective function, 3 * x + y. + MPObjective* const objective = solver->MutableObjective(); + objective->SetCoefficient(x, 3); + objective->SetCoefficient(y, 1); + objective->SetMaximization(); + + solver->Solve(); + + LOG(INFO) << "Solution:" << std::endl; + LOG(INFO) << "Objective value = " << objective->Value(); + LOG(INFO) << "x = " << x->solution_value(); + LOG(INFO) << "y = " << y->solution_value(); +} +} // namespace operations_research diff --git a/nasfaq/maths/optimizer/trash/optimizer.h b/nasfaq/maths/optimizer/trash/optimizer.h new file mode 100644 index 0000000..a6c17a4 --- /dev/null +++ b/nasfaq/maths/optimizer/trash/optimizer.h @@ -0,0 +1,11 @@ +#ifndef _OPTIMIZER_H_ +#define _OPTIMIZER_H_ + +#include "ortools/linear_solver/linear_solver.h" + +namespace operations_research { +void BasicExample(); +} + +#endif + diff --git a/nasfaq/maths/strategy/__pycache__/common.cpython-310.pyc b/nasfaq/maths/strategy/__pycache__/common.cpython-310.pyc new file mode 100644 index 0000000..fb9114e Binary files /dev/null and b/nasfaq/maths/strategy/__pycache__/common.cpython-310.pyc differ diff --git a/nasfaq/maths/strategy/__pycache__/db_handle.cpython-310.pyc b/nasfaq/maths/strategy/__pycache__/db_handle.cpython-310.pyc new file mode 100644 index 0000000..5ed67a9 Binary files /dev/null and b/nasfaq/maths/strategy/__pycache__/db_handle.cpython-310.pyc differ diff --git a/nasfaq/maths/strategy/__pycache__/http_handle.cpython-310.pyc b/nasfaq/maths/strategy/__pycache__/http_handle.cpython-310.pyc new file mode 100644 index 0000000..7fde120 Binary files /dev/null and b/nasfaq/maths/strategy/__pycache__/http_handle.cpython-310.pyc differ diff --git a/nasfaq/maths/strategy/__pycache__/optimizer.cpython-310.pyc b/nasfaq/maths/strategy/__pycache__/optimizer.cpython-310.pyc new file mode 100644 index 0000000..117b9e1 Binary files /dev/null and b/nasfaq/maths/strategy/__pycache__/optimizer.cpython-310.pyc differ diff --git a/nasfaq/maths/strategy/common.py b/nasfaq/maths/strategy/common.py new file mode 100644 index 0000000..97484eb --- /dev/null +++ b/nasfaq/maths/strategy/common.py @@ -0,0 +1,7 @@ +import json + +USERID = "314d0bda-d7f0-4636-aed7-5ea02743604b" + +URL_API = "https://nasfaq.biz/api/" + +COINS = ['aki', 'amelia', 'aqua', 'ayame', 'azki', 'botan', 'calliope', 'choco', 'civia', 'coco', 'flare', 'fubuki', 'gura', 'haato', 'himemoriluna', 'hololive', 'inanis', 'iofi', 'kanata', 'kiara', 'korone', 'lamy', 'marine', 'matsuri', 'mel', 'melfissa', 'miko', 'mio', 'moona', 'nana', 'nene', 'noel', 'okayu', 'ollie', 'pekora', 'polka', 'reine', 'risu', 'roboco', 'rushia', 'shion', 'sora', 'subaru', 'suisei', 'towa', 'ui', 'watame', 'laplus', 'lui', 'koyori', 'chloe', 'iroha', 'irys', 'sana', 'fauna', 'kronii', 'mumei', 'baelz'] diff --git a/nasfaq/maths/strategy/db_handle.py b/nasfaq/maths/strategy/db_handle.py new file mode 100644 index 0000000..acaa309 --- /dev/null +++ b/nasfaq/maths/strategy/db_handle.py @@ -0,0 +1,47 @@ +import psycopg2 + +from common import * + +def get_db_connection(): + return psycopg2.connect(database="nasfaq", user = "steaky", host = "127.0.0.1", port = "5432") + +def fetch_wma_slope_all(cursor): + + slope_dict = {} + + nb_cycles = 2 + delta = 600 + + for coin in COINS: + tmp = 0 + weight = nb_cycles + wma = 0 + denum = 0 + + query = "select PRICE, TIMESTAMP FROM last_n_spaced_prices('{}', {}, {});".format(coin, nb_cycles, delta) + cursor.execute(query) + rows = cursor.fetchall() + + price_top = float(rows[0][0]) + price_bot = float(rows[1][0]) + ts_top = int(rows[0][1]) + ts_bot = int(rows[1][1]) + + tmp = (price_top - price_bot) / (ts_top - ts_bot) + wma = weight * tmp + denum = weight + + for row in rows[1::]: + price_bot = price_top + price_top = row[0] + ts_bot = ts_top + ts_top = row[1] + + weight -= 1 + tmp = (price_top - price_bot) / (ts_top - ts_bot) + wma += weight * tmp + denum += weight + + slope_dict[coin] = wma / denum * 1000 * 600 + + return slope_dict diff --git a/nasfaq/maths/strategy/http_handle.py b/nasfaq/maths/strategy/http_handle.py new file mode 100644 index 0000000..2c17264 --- /dev/null +++ b/nasfaq/maths/strategy/http_handle.py @@ -0,0 +1,24 @@ +from common import * +import requests + +def fetch_marketInfo_all(): + url = URL_API + "getMarketInfo?all" + r = requests.get(url) + return r.json()['coinInfo']['data'] + +def fetch_coin_qty_all(): + rop = {} + + url = URL_API + "getUserWallet?userid=" + USERID + r = requests.get(url) + + for key, item in r.json()['wallet']['coins'].items(): + rop[key] = item['amt'] + + return rop + +def fetch_balance(): + url = URL_API + "getUserWallet?userid=" + USERID + r = requests.get(url) + + return r.json()['wallet']['balance'] diff --git a/nasfaq/maths/strategy/main.py b/nasfaq/maths/strategy/main.py new file mode 100644 index 0000000..0245978 --- /dev/null +++ b/nasfaq/maths/strategy/main.py @@ -0,0 +1,42 @@ +from common import * +from optimizer import * +from db_handle import * +from http_handle import * + +if __name__ == '__main__': + C = get_db_connection() + cur = C.cursor() + + user_balance = fetch_balance() + coin_qty = fetch_coin_qty_all() + coin_prices = fetch_marketInfo_all() + wma_coins = fetch_wma_slope_all(cur) + #wma_coins = {coin:20 for coin in coin_prices.keys() } + + # Cut down for test + u = 0 + max_u = 10 + + smp_prices = {} + smp_wma = {} + #coins = ["lamy", "towa", "luna", "marine", "subaru", "aqua", "hololive"] + for key in coin_prices.keys(): + if u > max_u: break + else: + try: + a = wma_coins[key] + if abs(a) > 10: + smp_prices[key] = coin_prices[key] + smp_wma[key] = wma_coins[key] + u += 1 + except KeyError: + pass + + print("Coins prices: ") + print(smp_prices) + print("Coins wma: ") + print(smp_wma) + + M = 144 + sol = optimize_all(smp_wma, smp_prices, M) + save_strategy_all(sol, smp_wma, smp_prices, M) diff --git a/nasfaq/maths/strategy/optimizer.py b/nasfaq/maths/strategy/optimizer.py new file mode 100644 index 0000000..e02eeac --- /dev/null +++ b/nasfaq/maths/strategy/optimizer.py @@ -0,0 +1,164 @@ +#import numpy as np +#import itertools +#import json +#import math +#import collections + +import matplotlib +import matplotlib.pyplot as plt + +from scipy.optimize import minimize + +from gekko import GEKKO + +""" + Global Parameters + S: Stock price at adjustment + T: Tax baseline + a: Slope + M: Number of cycles (maximum of 24*6 = 144) +""" + +""" + Function to minimize + This one is for python +""" +def to_optimize_(x, S, a, M, m): + res = 0 + t = -1 if a<0 else 1 + tax = 0.035 if a <0 else 0.045 + + for i in range(m): #Ineffective when plotting (O(m^2)) + res += t*x[i]*( a*(M - (i+1)) - x[i]*tax*t*(S + a*i)) + return res # We minimize the opposite function + +""" + Gekko function. + Function to minimize +""" +def to_optimize(x, S, a, M, m): + res = 0 + t = m.if2(a, -1, 1) # type of trade + tax = m.if2(a, 0.035, 0.045) # type of tax + for i in range(M): + res += t*x[i]*( a*(M - (i+1)) - x[i]*t*tax*(S + a*i)) + return -res # We minimize the opposite function + +""" + GEKKO optimizer +""" +def optimize_all(wma, prices, M): + + result = {} + for coin in prices.keys(): + try: + m = GEKKO(remote=False) + x = m.Array(m.Var, M, lb=0, ub=10, integer=True) + + m.options.SOLVER=1 + m.options.IMODE = 3 + m.options.COLDSTART=1 + m.solver_options = ['maximum_iterations 10000'] + m.Minimize(to_optimize(x, prices[coin]["price"] , wma[coin], M, m)) + m.solve(disp=True) + + result[coin] = [y.value[0] for y in x] + except Exception as e: + pass + + return result + +#def save_result(res): +# +# print(res) +# d = dict() +# for i in range(len(L)): +# d[L[i]] = round(int(res[i].value[0])) +# +# +# with open(PATH_OUT, "w") as f: +# json.dump(d, f) + +def display_strategy(x): + s = {} + m = -1 + index = 0 + toprint = "" + for i in range(len(x)): + if x[i] != m: + toprint = "[Change@" + str(i) + "\t:x" + str(int(x[i])) + "]" + m = x[i] + s[i] = x[i] + print(toprint) + return s + +def plot_results(x, S, T, a, M, s, coin, save_path = None): + fig, ax = plt.subplots(figsize=(20, 10)) + + M = len(x) + X = [i for i in range(M)] + + # Naive Strategies to plot + n_strats = [i for i in range(1, 5)] + + # Plot the straight strategies + for n in n_strats: + xx = [n for _ in range(M)] + Y = [to_optimize_(xx, S, a, M, m) for m in X] + ax.scatter(X, Y, marker = "+", label = "Constant x{}".format(n)) + + # Plot optimized strategy + Y = [to_optimize_(x, S, a, M, m) for m in X] + ax.scatter(X, Y, marker = "^", label = "Optimized") + + for cycle, n in s.items(): + ax.annotate("x{}".format(int(n)), textcoords = "offset pixels", xytext = (0, 10), xy = (X[cycle], Y[cycle])) + + # Display parameters + textstr = '\n'.join(( + r'Coin price: {}'.format(S), + r'Tax baseline: {}'.format(T), + r'Slope extrapolation: {}'.format(round(a, 2)), + r'Number of cycles: {}'.format(M))) + props = dict(boxstyle='round', facecolor='white', alpha=0.5) + + # place a text box in upper left in axes coords + ax.text(0.12, 0.98, textstr, transform=ax.transAxes, fontsize=14, + verticalalignment='top', bbox=props) + + #ax.set_yscale("log") + #ax.set_xscale("log") + ax.legend(loc="upper left") + ax.set_xlabel("Cycle") + ax.set_ylabel("Profit") + ax.set_title("[{}] Profit for naive and optimized strategies".format(coin)) + ax.grid(True) + + if save_path != None: + plt.savefig(save_path, dpi=200) + else: + plt.show() + +def save_strategy_all(x, wma, prices, M): + for coin in x.keys(): + try: + T = 0.045 if wma[coin] > 0 else 0.035 + s = display_strategy(x[coin]) + plot_results(x[coin], prices[coin]["price"], T, wma[coin], M, s, coin, save_path = "res/" + str(coin) + ".png") + except e: + pass + + +#def main(): +# #x = [3 for _ in range(M)] +# #res = to_optimize(x, 0) +# #print(res) +# res = optimize() +# res_ = [x.value[0] for x in res] +# print("Net profit with strategy x: ", to_optimize_(res_, M)) +# print("Strategy vector:") +# s = display_strategy(res_) +# plot_results(res_, s) +# +#if __name__ == "__main__": +# main() diff --git a/nasfaq/maths/strategy/original.py b/nasfaq/maths/strategy/original.py new file mode 100644 index 0000000..de1d931 --- /dev/null +++ b/nasfaq/maths/strategy/original.py @@ -0,0 +1,147 @@ +#import numpy as np +#import itertools +#import json +#import math +#import collections + +import matplotlib +import matplotlib.pyplot as plt + +from scipy.optimize import minimize + +from gekko import GEKKO + +""" + Global Parameters + S: Stock price at adjustment + T: Tax baseline + a: Slope + M: Number of cycles (maximum of 24*6 = 144) +""" +S = 11360 +T = 0.045 +a = 20 +M = 144 + + +""" + Function to minimize + This one is for python +""" +def to_optimize_(x, m): + global S, T, M + res = 0 + for i in range(m): #Ineffective when plotting (O(m^2)) + res += x[i]*( a*(M - (i+1)) - x[i]*T*(S + a*i)) + return res # We minimize the opposite function + +""" + Gekko function. + Function to minimize +""" +def to_optimize(x, m): + global S, T + res = 0 + for i in range(M): + res += x[i]*( a*(M - (i+1)) - x[i]*T*(S + a*i)) + return -res # We minimize the opposite function + +""" + GEKKO optimizer +""" +def optimize(): + global L, T + + m = GEKKO(remote=False) + x = m.Array(m.Var, M, lb=0, ub=10, integer=True) # Lower bound is 0: no order, upper bound is 10: hyper-multicoining + + m.options.SOLVER=1 + m.options.IMODE = 3 + m.options.COLDSTART=1 + m.solver_options = ['maximum_iterations 10000'] + m.Minimize(to_optimize(x, m)) + m.solve(disp=True) + return x + + +#def save_result(res): +# +# print(res) +# d = dict() +# for i in range(len(L)): +# d[L[i]] = round(int(res[i].value[0])) +# +# +# with open(PATH_OUT, "w") as f: +# json.dump(d, f) + +def display_strategy(x): + s = {} + m = -1 + index = 0 + toprint = "" + for i in range(len(x)): + if x[i] != m: + toprint = "[Change@" + str(i) + "\t:x" + str(int(x[i])) + "]" + m = x[i] + s[i] = x[i] + print(toprint) + return s + +def plot_results(x, s): + fig, ax = plt.subplots() + + M = len(x) + X = [i for i in range(M)] + + # Naive Strategies to plot + n_strats = [i for i in range(1, 5)] + + # Plot the straight strategies + for n in n_strats: + xx = [n for _ in range(M)] + Y = [to_optimize_(xx, m) for m in X] + ax.scatter(X, Y, marker = "+", label = "Constant x{}".format(n)) + + # Plot optimized strategy + Y = [to_optimize_(x, m) for m in X] + ax.scatter(X, Y, marker = "^", label = "Optimized") + + for cycle, n in s.items(): + ax.annotate("x{}".format(int(n)), textcoords = "offset pixels", xytext = (0, 10), xy = (X[cycle], Y[cycle])) + + # Display parameters + textstr = '\n'.join(( + r'Coin price at adjustment: {}'.format(S), + r'Tax baseline: {}'.format(T), + r'Slope extrapolation: {}'.format(a), + r'Number of cycles: {}'.format(M))) + props = dict(boxstyle='round', facecolor='white', alpha=0.5) + + # place a text box in upper left in axes coords + ax.text(0.12, 0.98, textstr, transform=ax.transAxes, fontsize=14, + verticalalignment='top', bbox=props) + + #ax.set_yscale("log") + #ax.set_xscale("log") + ax.legend(loc="upper left") + ax.set_xlabel("Cycle") + ax.set_ylabel("Profit") + ax.set_title("Profit using naive and optimized strategies") + ax.grid(True) + plt.show() + + +def main(): + #x = [3 for _ in range(M)] + #res = to_optimize(x, 0) + #print(res) + res = optimize() + res_ = [x.value[0] for x in res] + print("Net profit with strategy x: ", to_optimize_(res_, M)) + print("Strategy vector:") + s = display_strategy(res_) + plot_results(res_, s) + +if __name__ == "__main__": + main() diff --git a/nasfaq/maths/strategy/plot.py b/nasfaq/maths/strategy/plot.py new file mode 100644 index 0000000..7e99e7b --- /dev/null +++ b/nasfaq/maths/strategy/plot.py @@ -0,0 +1,51 @@ +import json +import math +import matplotlib.pyplot as plt +font = {'family' : 'normal', + 'size' : 18} + +plt.rc('font', **font) + +DIR = "./files/" +FILENAME = "timings.json" + +EXTENSION_DEGREE = [1, 1, 1, 1, 1, 1, 1, 1, 1, + 3, 3, + 4, 4, + 5, 5, 5, + 7, 7, 7, + 8, + 9, 9] + +with open(DIR+FILENAME) as f: + timings = json.load(f) + +x = [int(l) for l in timings.keys()] +y = [timings[str(l)] for l in x] + +x_rad = x[0:3] +y_rad = y[0:3] + +x_velu = x[3:] +y_velu = y[3:] + + +fig, ax = plt.subplots() + +ax.scatter(x_rad, y_rad, marker = "2", label = "Radical isogeny") +ax.scatter(x_velu, y_velu, marker = "^", label = "Sqrt-Velu") +ax.set_yscale("log") +ax.set_xscale("log") + +for i, txt in enumerate(x_rad): + ax.annotate(" " + str(txt) + " [{}] {}".format(EXTENSION_DEGREE[:3][i], math.floor(math.log(x_rad[i])/math.log(2))), (x_rad[i], y_rad[i])) + +for i, txt in enumerate(x_velu): + ax.annotate(" " + str(txt) + " [{}] {}".format(EXTENSION_DEGREE[3:][i], math.floor(math.log(x_velu[i])/math.log(2))), (x_velu[i], y_velu[i])) + +ax.legend(loc="upper left") +ax.set_xlabel("l (log)") +ax.set_ylabel("Average step time in seconds (log)") +ax.set_title("Timings for the l-primes") +ax.grid(True) +plt.show() diff --git a/nasfaq/maths/strategy/res/aki.png b/nasfaq/maths/strategy/res/aki.png new file mode 100644 index 0000000..c01b98f Binary files /dev/null and b/nasfaq/maths/strategy/res/aki.png differ diff --git a/nasfaq/maths/strategy/res/aqua.png b/nasfaq/maths/strategy/res/aqua.png new file mode 100644 index 0000000..afeeb8e Binary files /dev/null and b/nasfaq/maths/strategy/res/aqua.png differ diff --git a/nasfaq/maths/strategy/res/baelz.png b/nasfaq/maths/strategy/res/baelz.png new file mode 100644 index 0000000..578e117 Binary files /dev/null and b/nasfaq/maths/strategy/res/baelz.png differ diff --git a/nasfaq/maths/strategy/res/botan.png b/nasfaq/maths/strategy/res/botan.png new file mode 100644 index 0000000..3a7257d Binary files /dev/null and b/nasfaq/maths/strategy/res/botan.png differ diff --git a/nasfaq/maths/strategy/res/calliope.png b/nasfaq/maths/strategy/res/calliope.png new file mode 100644 index 0000000..d2252ee Binary files /dev/null and b/nasfaq/maths/strategy/res/calliope.png differ diff --git a/nasfaq/maths/strategy/res/chloe.png b/nasfaq/maths/strategy/res/chloe.png new file mode 100644 index 0000000..66dcc65 Binary files /dev/null and b/nasfaq/maths/strategy/res/chloe.png differ diff --git a/nasfaq/maths/strategy/res/choco.png b/nasfaq/maths/strategy/res/choco.png new file mode 100644 index 0000000..cc6541b Binary files /dev/null and b/nasfaq/maths/strategy/res/choco.png differ diff --git a/nasfaq/maths/strategy/res/coco.png b/nasfaq/maths/strategy/res/coco.png new file mode 100644 index 0000000..c35dd4a Binary files /dev/null and b/nasfaq/maths/strategy/res/coco.png differ diff --git a/nasfaq/maths/strategy/res/gura.png b/nasfaq/maths/strategy/res/gura.png new file mode 100644 index 0000000..be5425d Binary files /dev/null and b/nasfaq/maths/strategy/res/gura.png differ diff --git a/nasfaq/maths/strategy/res/haato.png b/nasfaq/maths/strategy/res/haato.png new file mode 100644 index 0000000..cb807f5 Binary files /dev/null and b/nasfaq/maths/strategy/res/haato.png differ diff --git a/nasfaq/maths/strategy/res/res.pdf b/nasfaq/maths/strategy/res/res.pdf new file mode 100644 index 0000000..bd40a53 Binary files /dev/null and b/nasfaq/maths/strategy/res/res.pdf differ diff --git a/nasfaq/socket/ws/simple-libwebsockets-example b/nasfaq/socket/ws/simple-libwebsockets-example deleted file mode 160000 index 1088642..0000000 --- a/nasfaq/socket/ws/simple-libwebsockets-example +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1088642db8abbcf9f034bab61f2496864235c042 diff --git a/nasfaq/tests/optimizer b/nasfaq/tests/optimizer new file mode 100755 index 0000000..543133e Binary files /dev/null and b/nasfaq/tests/optimizer differ diff --git a/nasfaq/tests/optimizer.sh b/nasfaq/tests/optimizer.sh new file mode 100755 index 0000000..d6256bd --- /dev/null +++ b/nasfaq/tests/optimizer.sh @@ -0,0 +1,3 @@ +g++ ../maths/optimizer/optimizer.cpp \ + optimizer_main.cpp \ + -lortools -o optimizer && ./optimizer diff --git a/nasfaq/tests/optimizer_main.cpp b/nasfaq/tests/optimizer_main.cpp new file mode 100644 index 0000000..7062afb --- /dev/null +++ b/nasfaq/tests/optimizer_main.cpp @@ -0,0 +1,8 @@ +#include "../maths/optimizer/optimizer.h" + +int main() { + operations_research::BasicExample(); + return EXIT_SUCCESS; + + return 1; +} diff --git a/nasfaq/api/src/cJSON b/nasfaq/trash/api/src/cJSON similarity index 100% rename from nasfaq/api/src/cJSON rename to nasfaq/trash/api/src/cJSON diff --git a/nasfaq/api/src/common.c b/nasfaq/trash/api/src/common.c similarity index 100% rename from nasfaq/api/src/common.c rename to nasfaq/trash/api/src/common.c diff --git a/nasfaq/api/src/common.h b/nasfaq/trash/api/src/common.h similarity index 100% rename from nasfaq/api/src/common.h rename to nasfaq/trash/api/src/common.h diff --git a/nasfaq/api/src/items.c b/nasfaq/trash/api/src/items.c similarity index 100% rename from nasfaq/api/src/items.c rename to nasfaq/trash/api/src/items.c diff --git a/nasfaq/api/src/items.h b/nasfaq/trash/api/src/items.h similarity index 100% rename from nasfaq/api/src/items.h rename to nasfaq/trash/api/src/items.h diff --git a/nasfaq/api/src/mute.c b/nasfaq/trash/api/src/mute.c similarity index 100% rename from nasfaq/api/src/mute.c rename to nasfaq/trash/api/src/mute.c diff --git a/nasfaq/api/src/mute.h b/nasfaq/trash/api/src/mute.h similarity index 100% rename from nasfaq/api/src/mute.h rename to nasfaq/trash/api/src/mute.h diff --git a/nasfaq/api/src/performance.c b/nasfaq/trash/api/src/performance.c similarity index 100% rename from nasfaq/api/src/performance.c rename to nasfaq/trash/api/src/performance.c diff --git a/nasfaq/api/src/performance.h b/nasfaq/trash/api/src/performance.h similarity index 100% rename from nasfaq/api/src/performance.h rename to nasfaq/trash/api/src/performance.h diff --git a/nasfaq/api/src/settings.c b/nasfaq/trash/api/src/settings.c similarity index 100% rename from nasfaq/api/src/settings.c rename to nasfaq/trash/api/src/settings.c diff --git a/nasfaq/api/src/settings.h b/nasfaq/trash/api/src/settings.h similarity index 100% rename from nasfaq/api/src/settings.h rename to nasfaq/trash/api/src/settings.h diff --git a/nasfaq/api/src/userInfo.h b/nasfaq/trash/api/src/userInfo.h similarity index 100% rename from nasfaq/api/src/userInfo.h rename to nasfaq/trash/api/src/userInfo.h diff --git a/nasfaq/api/test/compile.sh b/nasfaq/trash/api/test/compile.sh similarity index 100% rename from nasfaq/api/test/compile.sh rename to nasfaq/trash/api/test/compile.sh diff --git a/nasfaq/api/test/main.c b/nasfaq/trash/api/test/main.c similarity index 100% rename from nasfaq/api/test/main.c rename to nasfaq/trash/api/test/main.c diff --git a/nasfaq/api/test/test b/nasfaq/trash/api/test/test similarity index 100% rename from nasfaq/api/test/test rename to nasfaq/trash/api/test/test diff --git a/nasfaq/ui/test/compile.sh b/nasfaq/trash/ui/test/compile.sh similarity index 100% rename from nasfaq/ui/test/compile.sh rename to nasfaq/trash/ui/test/compile.sh diff --git a/nasfaq/ui/test/nc b/nasfaq/trash/ui/test/nc similarity index 100% rename from nasfaq/ui/test/nc rename to nasfaq/trash/ui/test/nc diff --git a/nasfaq/ui/test/nc.c b/nasfaq/trash/ui/test/nc.c similarity index 100% rename from nasfaq/ui/test/nc.c rename to nasfaq/trash/ui/test/nc.c diff --git a/nasfaq/ui/test/nc.h b/nasfaq/trash/ui/test/nc.h similarity index 100% rename from nasfaq/ui/test/nc.h rename to nasfaq/trash/ui/test/nc.h diff --git a/nasfaq/ui/test/utils.c b/nasfaq/trash/ui/test/utils.c similarity index 100% rename from nasfaq/ui/test/utils.c rename to nasfaq/trash/ui/test/utils.c diff --git a/nasfaq/ui/test/utils.h b/nasfaq/trash/ui/test/utils.h similarity index 100% rename from nasfaq/ui/test/utils.h rename to nasfaq/trash/ui/test/utils.h