Browse Source

Merge remote-tracking branch 'jl777/master'

dev
Satinder Grewal 9 years ago
parent
commit
904f7d512b
  1. 1
      InstantDEX/exchangeparse.h
  2. 2
      InstantDEX/exchanges/coinbase.c
  3. 1
      InstantDEX/exchanges/lakebtc.c
  4. 8
      README.md
  5. 26
      crypto777/OS_portable.h
  6. 4
      crypto777/OS_time.c
  7. 38
      crypto777/bitcoind_RPC.c
  8. 4
      crypto777/cJSON.c
  9. 4
      crypto777/hmac_sha512.c
  10. 52
      crypto777/iguana_OS.c
  11. 26
      crypto777/iguana_serdes.c
  12. 181
      crypto777/iguana_utils.c
  13. 4
      crypto777/nanosrc/transports/utils/base64.c
  14. 247
      deprecated/obsolete.h
  15. 1772
      iguana/BTCD_hdrs.txt
  16. 49
      iguana/BTCD_peers.txt
  17. 195
      iguana/BTC_hdrs.txt
  18. 137
      iguana/BTC_peers.txt
  19. 582
      iguana/InstantDEX/InstantDEX.c
  20. 223
      iguana/InstantDEX/InstantDEX_quote.h
  21. 1407
      iguana/InstantDEX/exchange_trades.h
  22. 1207
      iguana/InstantDEX/exchangeparse.h
  23. 1812
      iguana/InstantDEX/prices777.c
  24. 880
      iguana/InstantDEX/quotes.h
  25. 1016
      iguana/InstantDEX/quotes777.c
  26. 1496
      iguana/InstantDEX/subatomic.h
  27. 323
      iguana/InstantDEX/tradebots.h
  28. 1583
      iguana/InstantDEX/trades.h
  29. 194
      iguana/SuperNET.c
  30. 40
      iguana/SuperNET.h
  31. 166
      iguana/SuperNET_category.c
  32. 7
      iguana/SuperNET_hexmsg.c
  33. 407
      iguana/SuperNET_keys.c
  34. 161
      iguana/app/coin_mgmt.js
  35. 86
      iguana/app/startup.js
  36. 1
      iguana/docs/supernet/docs/about.md
  37. 28
      iguana/docs/supernet/docs/index.md
  38. 5
      iguana/docs/supernet/mkdocs.yml
  39. 147
      iguana/docs/supernet/site/about/index.html
  40. 125
      iguana/docs/supernet/site/css/highlight.css
  41. 12
      iguana/docs/supernet/site/css/theme.css
  42. 126
      iguana/docs/supernet/site/css/theme_extra.css
  43. BIN
      iguana/docs/supernet/site/fonts/fontawesome-webfont.eot
  44. 399
      iguana/docs/supernet/site/fonts/fontawesome-webfont.svg
  45. BIN
      iguana/docs/supernet/site/fonts/fontawesome-webfont.ttf
  46. BIN
      iguana/docs/supernet/site/fonts/fontawesome-webfont.woff
  47. BIN
      iguana/docs/supernet/site/img/favicon.ico
  48. 183
      iguana/docs/supernet/site/index.html
  49. 2
      iguana/docs/supernet/site/js/highlight.pack.js
  50. 4
      iguana/docs/supernet/site/js/jquery-2.1.1.min.js
  51. 1
      iguana/docs/supernet/site/js/modernizr-2.8.3.min.js
  52. 55
      iguana/docs/supernet/site/js/theme.js
  53. 24
      iguana/docs/supernet/site/license/highlight.js/LICENSE
  54. 7
      iguana/docs/supernet/site/mkdocs/js/lunr-0.5.7.min.js
  55. 1
      iguana/docs/supernet/site/mkdocs/js/mustache.min.js
  56. 36
      iguana/docs/supernet/site/mkdocs/js/require.js
  57. 4
      iguana/docs/supernet/site/mkdocs/js/search-results-template.mustache
  58. 88
      iguana/docs/supernet/site/mkdocs/js/search.js
  59. 390
      iguana/docs/supernet/site/mkdocs/js/text.js
  60. 29
      iguana/docs/supernet/site/mkdocs/search_index.json
  61. 138
      iguana/docs/supernet/site/search.html
  62. 20
      iguana/docs/supernet/site/sitemap.xml
  63. 281
      iguana/example.js
  64. 110
      iguana/exchanges/PAX.c
  65. 1280
      iguana/exchanges/bitcoin.c
  66. 42
      iguana/exchanges/bitcoin.h
  67. 251
      iguana/exchanges/bitfinex.c
  68. 157
      iguana/exchanges/bitstamp.c
  69. 268
      iguana/exchanges/bittrex.c
  70. 332
      iguana/exchanges/btc38.c
  71. 204
      iguana/exchanges/btce.c
  72. 53
      iguana/exchanges/checkbalance.c
  73. 216
      iguana/exchanges/coinbase.c
  74. 25
      iguana/exchanges/exchange_supports.h
  75. 32
      iguana/exchanges/exchange_undefs.h
  76. 319
      iguana/exchanges/fxcm.c
  77. 171
      iguana/exchanges/huobi.c
  78. 137
      iguana/exchanges/instaforex.c
  79. 94
      iguana/exchanges/jumblr.c
  80. 266
      iguana/exchanges/lakebtc.c
  81. 749
      iguana/exchanges/nxtae.c
  82. 229
      iguana/exchanges/okcoin.c
  83. 259
      iguana/exchanges/poloniex.c
  84. 172
      iguana/exchanges/quadriga.c
  85. 211
      iguana/exchanges/truefx.c
  86. 94
      iguana/exchanges/unconf.c
  87. 91
      iguana/exchanges777.h
  88. BIN
      iguana/fonts/MaterialIcons-Regular.woff2
  89. BIN
      iguana/fonts/Roboto-Bold.woff2
  90. BIN
      iguana/fonts/Roboto-Light.woff2
  91. BIN
      iguana/fonts/Roboto-Medium.woff2
  92. BIN
      iguana/fonts/Roboto-Regular.woff2
  93. 12
      iguana/footer.html
  94. 13
      iguana/form-widget.html
  95. 4
      iguana/help/agent.md
  96. 6
      iguana/help/bootstrap-theme.min.css
  97. 6
      iguana/help/bootstrap.min.css
  98. 7
      iguana/help/bootstrap.min.js
  99. 0
      iguana/help/field.html
  100. 1
      iguana/help/field.md

1
InstantDEX/exchangeparse.h

@ -694,7 +694,6 @@ double prices777_coinbase(struct prices777 *prices,int32_t maxdepth)
char *lakebtc_parsebalance(struct exchange_info *exchange,double *balancep,char *coinstr)
{
//lakebtc.({"balance":{"BTC":0.1},"locked":{"BTC":0.0},"profile":{"email":"jameslee777@yahoo.com","id":"U137561934","btc_deposit_addres":"1RyKrNJjezeFfvYaicnJEozHfhWfYzbuh"}})
char field[128],*str,*itemstr = 0; cJSON *obj=0,*item=0,*prof=0; double locked = 0;
*balancep = 0.;
strcpy(field,coinstr);

2
InstantDEX/exchanges/coinbase.c

@ -93,7 +93,7 @@ cJSON *SIGNPOST(void **cHandlep,int32_t dotrade,char **retstrp,struct exchange_i
sprintf(hdr2,"CB-ACCESS-SIGN:%s",sig64);
sprintf(hdr3,"CB-ACCESS-TIMESTAMP:%llu",(long long)nonce);
//sprintf(hdr4,"CB-ACCESS-PASSPHRASE:%s; content-type:application/json; charset=utf-8",exchange->userid);
sprintf(hdr4,"CB-ACCESS-PASSPHRASE:%s",exchange->userid);
sprintf(hdr4,"CB-ACCESS-PASSPHRASE:%s",exchange->tradepassword);
sprintf(url,"%s/%s",EXCHANGE_AUTHURL,path);
if ( dotrade == 0 )
data = exchange_would_submit(payload,hdr1,hdr2,hdr3,hdr4);

1
InstantDEX/exchanges/lakebtc.c

@ -147,7 +147,6 @@ if ( (sig= hmac_sha1_str(dest,exchange->apisecret,(int32_t)strlen(exchange->apis
char *PARSEBALANCE(struct exchange_info *exchange,double *balancep,char *coinstr)
{
//lakebtc.({"balance":{"BTC":0.1},"locked":{"BTC":0.0},"profile":{"email":"jameslee777@yahoo.com","id":"U137561934","btc_deposit_addres":"1RyKrNJjezeFfvYaicnJEozHfhWfYzbuh"}})
char field[128],*str,*itemstr = 0; cJSON *obj=0,*item=0,*prof=0; double locked = 0;
*balancep = 0.;
strcpy(field,coinstr);

8
README.md

@ -100,3 +100,11 @@ postCall('{"agent":"iguana","method":"test"}'}
iguana_JSON("{\"agent\":\"iguana",\"method\":\"test\"}"); -> direct C function call
iguana can be invoked with a command line argument. if it is a name of a file, it will load it and check to see if it is valid JSON and if it is, it will use it. Otherwise the command line argument needs to be valid JSON to be used and it will process the JSON to initialize account passphrases, exchange apikeys, etc. A few special keys:
"wallet" -> passphrase used for the persistent privkey
"2fafile" -> secondary part (optional) for the persistent privkey
"numhelpers" -> number of helper threads (need at least 1)
"exchanges" -> { "name":"<name of exchange>", ... }
"apikey", "apisecret", "userid", "tradepassword" these are as expected
"pollgap" -> gap between each access to exchange for getting prices

26
crypto777/OS_portable.h

@ -43,6 +43,9 @@
#include <sys/socket.h>
#define closesocket close
#endif
#ifndef MIN
#define MIN(x, y) ( ((x)<(y))?(x):(y) )
#endif
#include "../includes/libgfshare.h"
#include "../includes/utlist.h"
@ -74,6 +77,10 @@ int32_t ramcoder_decompress(uint8_t *data,int32_t maxlen,uint8_t *bits,uint32_t
int32_t ramcoder_compress(uint8_t *bits,int32_t maxlen,uint8_t *data,int32_t datalen,bits256 seed);
uint64_t hconv_bitlen(uint64_t bitlen);
void _init_HUFF(HUFF *hp,int32_t allocsize,void *buf);
int32_t hgetbit(HUFF *hp);
int32_t hputbit(HUFF *hp,int32_t bit);
uint64_t hconv_bitlen(uint64_t bitlen);
int32_t hseek(HUFF *hp,int32_t offset,int32_t mode);
#define SCRIPT_OPRETURN 0x6a
#define GENESIS_ACCT "1739068987193023818" // NXT-MRCC-2YLS-8M54-3CMAJ
@ -96,6 +103,8 @@ void _init_HUFF(HUFF *hp,int32_t allocsize,void *buf);
#define portable_mutex_unlock pthread_mutex_unlock
#define OS_thread_create pthread_create
#define issue_curl(cmdstr) bitcoind_RPC(0,"curl",cmdstr,0,0,0)
struct allocitem { uint32_t allocsize,type; } __attribute__((packed));
struct queueitem { struct queueitem *next,*prev; uint32_t allocsize,type; } __attribute__((packed));
typedef struct queue
@ -177,7 +186,7 @@ int32_t expand_datenum(char *date,int32_t datenum);
int32_t calc_datenum(int32_t year,int32_t month,int32_t day);
int32_t ecb_decrdate(int32_t *yearp,int32_t *monthp,int32_t *dayp,char *date,int32_t datenum);
int32_t conv_date(int32_t *secondsp,char *buf);
uint64_t OS_conv_datenum(int32_t datenum,int32_t hour,int32_t minute,int32_t second);
uint32_t OS_conv_datenum(int32_t datenum,int32_t hour,int32_t minute,int32_t second);
int32_t OS_conv_unixtime(struct tai *t,int32_t *secondsp,time_t timestamp);
double OS_milliseconds();
@ -245,6 +254,15 @@ int32_t init_hexbytes_noT(char *hexbytes,uint8_t *message,long len);
uint16_t parse_ipaddr(char *ipaddr,char *ip_port);
int32_t bitweight(uint64_t x);
unsigned char _decode_hex(char *hex);
char *uppercase_str(char *buf,char *str);
char *lowercase_str(char *buf,char *str);
int32_t strsearch(char *strs[],int32_t num,char *name);
int32_t OS_getline(int32_t waitflag,char *line,int32_t max,char *dispstr);
int32_t sort64s(uint64_t *buf,uint32_t num,int32_t size);
int32_t revsort64s(uint64_t *buf,uint32_t num,int32_t size);
int decode_base32(uint8_t *token,uint8_t *tokenstr,int32_t len);
int init_base32(char *tokenstr,uint8_t *token,int32_t len);
char *OS_mvstr();
long _stripwhite(char *buf,int accept);
int32_t is_DST(int32_t datenum);
@ -253,9 +271,10 @@ int32_t expand_datenum(char *date,int32_t datenum);
int32_t calc_datenum(int32_t year,int32_t month,int32_t day);
int32_t ecb_decrdate(int32_t *yearp,int32_t *monthp,int32_t *dayp,char *date,int32_t datenum);
int32_t conv_date(int32_t *secondsp,char *buf);
uint64_t OS_conv_datenum(int32_t datenum,int32_t hour,int32_t minute,int32_t second);
uint32_t OS_conv_datenum(int32_t datenum,int32_t hour,int32_t minute,int32_t second);
int32_t OS_conv_unixtime(struct tai *t,int32_t *secondsp,time_t timestamp);
int32_t btc_coinaddr(char *coinaddr,uint8_t addrtype,char *pubkeystr);
int32_t btc_convaddr(char *hexaddr,char *addr58);
uint64_t RS_decode(char *rs);
int32_t RS_encode(char *rsaddr,uint64_t id);
@ -316,7 +335,7 @@ void SaM_PrepareIndices();
struct iguana_msghdr { uint8_t netmagic[4]; char command[12]; uint8_t serdatalen[4],hash[4]; } __attribute__((packed));
int32_t iguana_rwnum(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp);
int32_t iguana_validatehdr(struct iguana_msghdr *H);
int32_t iguana_validatehdr(char *symbol,struct iguana_msghdr *H);
int32_t iguana_rwbignum(int32_t rwflag,uint8_t *serialized,int32_t len,uint8_t *endianedp);
int32_t iguana_sethdr(struct iguana_msghdr *H,const uint8_t netmagic[4],char *command,uint8_t *data,int32_t datalen);
uint8_t *iguana_varint16(int32_t rwflag,uint8_t *serialized,uint16_t *varint16p);
@ -340,6 +359,7 @@ int32_t btc_priv2pub(uint8_t pubkey[33],uint8_t privkey[32]);
extern char *Iguana_validcommands[];
extern bits256 GENESIS_PUBKEY,GENESIS_PRIVKEY;
extern char NXTAPIURL[];
extern int32_t smallprimes[168],Debuglevel;
#endif

4
crypto777/OS_time.c

@ -520,7 +520,7 @@ int32_t extract_datenum(int32_t *yearp,int32_t *monthp,int32_t *dayp,int32_t dat
else return(-1);
}
uint64_t OS_conv_datenum(int32_t datenum,int32_t hour,int32_t minute,int32_t second) // datenum+H:M:S -> unix time
uint32_t OS_conv_datenum(int32_t datenum,int32_t hour,int32_t minute,int32_t second) // datenum+H:M:S -> unix time
{
int32_t year,month,day; struct tai t; struct taitime ct;
if ( 1 )
@ -530,7 +530,7 @@ uint64_t OS_conv_datenum(int32_t datenum,int32_t hour,int32_t minute,int32_t sec
ct = taitime_set(taidate_set(year,month,day),hour,minute,second);
t = taitime2tai(ct);
//char str[65]; printf("conv.(y%d m%d d%d %d:%d:%d) %s\n",year,month,day,hour,minute,second,tai_str(str,t));
return(tai2utc(t));//tai2utime(t)+788250398LL - 4294967296LL);
return((uint32_t)tai2utc(t));//tai2utime(t)+788250398LL - 4294967296LL);
}
return(0);
}

38
crypto777/bitcoind_RPC.c

@ -18,7 +18,6 @@
#include <curl/curl.h>
#include <curl/easy.h>
#define issue_curl(cmdstr) bitcoind_RPC(0,"curl",cmdstr,0,0,0)
// return data from the server
struct return_string {
@ -190,7 +189,7 @@ try_again:
free(s.ptr);
return(0);
}
else if ( numretries >= 2 )
else if ( numretries >= 1 )
{
printf("Maximum number of retries exceeded!\n");
free(s.ptr);
@ -286,6 +285,7 @@ static size_t WriteMemoryCallback(void *ptr,size_t size,size_t nmemb,void *data)
mem->size += realsize;
mem->memory[mem->size] = 0;
}
//printf("got %d bytes\n",(int32_t)(size*nmemb));
return(realsize);
}
@ -296,7 +296,7 @@ void *curl_post(CURL **cHandlep,char *url,char *userpass,char *postfields,char *
*cHandlep = cHandle = curl_easy_init();
else curl_easy_reset(cHandle);
//#ifdef DEBUG
//curl_easy_setopt(cHandle,CURLOPT_VERBOSE, 1);
curl_easy_setopt(cHandle,CURLOPT_VERBOSE, 1);
//#endif
curl_easy_setopt(cHandle,CURLOPT_USERAGENT,"mozilla/4.0");//"Mozilla/4.0 (compatible; )");
curl_easy_setopt(cHandle,CURLOPT_SSL_VERIFYPEER,0);
@ -329,10 +329,10 @@ void *curl_post(CURL **cHandlep,char *url,char *userpass,char *postfields,char *
curl_easy_setopt(cHandle,CURLOPT_WRITEDATA,(void *)&chunk);
curl_easy_perform(cHandle);
curl_easy_getinfo(cHandle,CURLINFO_RESPONSE_CODE,&code);
if ( code != 200 )
printf("error: (%s) server responded with code %ld\n",url,code);
if ( headers != 0 )
curl_slist_free_all(headers);
if ( code != 200 )
printf("(%s) server responded with code %ld (%s)\n",url,code,chunk.memory);
return(chunk.memory);
}
@ -340,31 +340,3 @@ void curlhandle_free(void *curlhandle)
{
curl_easy_cleanup(curlhandle);
}
bits256 issue_getpubkey(int32_t *haspubkeyp,char *acct)
{
cJSON *json; bits256 pubkey; char cmd[4096],*jsonstr; struct destbuf pubkeystr;
sprintf(cmd,"%s?requestType=getAccountPublicKey&account=%s",NXTAPIURL,acct);
jsonstr = issue_curl(cmd);
pubkeystr.buf[0] = 0;
if ( haspubkeyp != 0 )
*haspubkeyp = 0;
memset(&pubkey,0,sizeof(pubkey));
if ( jsonstr != 0 )
{
printf("PUBKEYRPC.(%s)\n",jsonstr);
if ( (json = cJSON_Parse(jsonstr)) != 0 )
{
copy_cJSON(&pubkeystr,cJSON_GetObjectItem(json,"publicKey"));
free_json(json);
if ( strlen(pubkeystr.buf) == sizeof(pubkey)*2 )
{
if ( haspubkeyp != 0 )
*haspubkeyp = 1;
decode_hex(pubkey.bytes,sizeof(pubkey),pubkeystr.buf);
}
}
free(jsonstr);
}
return(pubkey);
}

4
crypto777/cJSON.c

@ -1062,9 +1062,9 @@ uint64_t calc_nxt64bits(const char *NXTaddr)
{
printf("calc_nxt64bits: illegal char.(%c %d) in (%s).%d\n",c,c,NXTaddr,(int32_t)i);
#ifdef __APPLE__
while ( 1 )
//while ( 1 )
{
sleep(60);
//sleep(60);
printf("calc_nxt64bits: illegal char.(%c %d) in (%s).%d\n",c,c,NXTaddr,(int32_t)i);
}
#endif

4
crypto777/hmac_sha512.c

@ -506,8 +506,8 @@ char *hmac_sha512_str(char *dest,char *key,int32_t key_size,char *message)
hmac_memory(&sha512_desc,(void *)key,key_size,(void *)message,strlen(message),checkbuf,&size);
init_hexbytes_noT(dest,mac,SHA512_DIGEST_SIZE);
init_hexbytes_noT(dest2,checkbuf,SHA512_DIGEST_SIZE);
if ( memcmp(checkbuf,mac,SHA512_DIGEST_SIZE) != 0 )
printf("hmac_512 error: %s vs %s\n",dest,dest2);
//if ( memcmp(checkbuf,mac,SHA512_DIGEST_SIZE) != 0 )
printf("hmac_512 : %s vs %s\n",dest,dest2);
return(dest);
}

52
crypto777/iguana_OS.c

@ -19,10 +19,20 @@
#include "OS_portable.h"
#include <sys/stat.h>
#include <sys/select.h>
#ifndef MAP_FILE
#define MAP_FILE 0
#endif
char *OS_mvstr()
{
#ifdef __WIN32
return("rename");
#else
return("mv");
#endif
}
void OS_randombytes(unsigned char *x,long xlen)
{
OS_portable_randombytes(x,xlen);
@ -783,6 +793,7 @@ void *OS_loadfile(char *fname,char **bufp,long *lenp,long *allocsizep)
{
fclose(fp);
*lenp = 0;
printf("OS_loadfile null size.(%s)\n",fname);
return(0);
}
if ( filesize > buflen-1 )
@ -801,7 +812,8 @@ void *OS_loadfile(char *fname,char **bufp,long *lenp,long *allocsizep)
}
fclose(fp);
*lenp = filesize;
}
//printf("loaded.(%s)\n",buf);
} //else printf("OS_loadfile couldnt load.(%s)\n",fname);
return(buf);
}
@ -836,4 +848,40 @@ void OS_init()
decode_hex(GENESIS_PRIVKEY.bytes,sizeof(GENESIS_PRIVKEY),GENESIS_PRIVKEYSTR);
SaM_PrepareIndices();
return(OS_portable_init());
}
}
int32_t OS_getline(int32_t waitflag,char *line,int32_t max,char *dispstr)
{
if ( dispstr != 0 && dispstr[0] != 0 )
fprintf(stderr,"%s",dispstr);
line[0] = 0;
#ifndef _WIN32
if ( waitflag == 0 )
{
static char prevline[1024];
struct timeval timeout;
fd_set fdset;
int32_t s;
line[0] = 0;
FD_ZERO(&fdset);
FD_SET(STDIN_FILENO,&fdset);
timeout.tv_sec = 0, timeout.tv_usec = 10000;
if ( (s= select(1,&fdset,NULL,NULL,&timeout)) < 0 )
fprintf(stderr,"wait_for_input: error select s.%d\n",s);
else
{
if ( FD_ISSET(STDIN_FILENO,&fdset) > 0 && fgets(line,max,stdin) == line )
{
line[strlen(line)-1] = 0;
if ( line[0] == 0 || (line[0] == '.' && line[1] == 0) )
strcpy(line,prevline);
else strcpy(prevline,line);
}
}
return((int32_t)strlen(line));
}
#endif
if ( fgets(line,max,stdin) != 0 )
line[strlen(line)-1] = 0;
return((int32_t)strlen(line));
}

26
crypto777/iguana_serdes.c

@ -52,18 +52,22 @@ int32_t iguana_rwnum(int32_t rwflag,uint8_t *serialized,int32_t len,void *endian
return(len);
}
int32_t iguana_validatehdr(struct iguana_msghdr *H)
int32_t iguana_validatehdr(char *symbol,struct iguana_msghdr *H)
{
int32_t i,len;
for (i=0; Iguana_validcommands[i]!=0&&Iguana_validcommands[i][0]!=0; i++)
if ( strcmp(H->command,Iguana_validcommands[i]) == 0 )
{
iguana_rwnum(0,H->serdatalen,sizeof(H->serdatalen),(uint32_t *)&len);
if ( len > IGUANA_MAXPACKETSIZE )
return(-1);
return(len);
}
return(-1);
int32_t i = 0,len = -1;
if ( strcmp(symbol,"VPN") != 0 )
{
for (i=0; Iguana_validcommands[i]!=0&&Iguana_validcommands[i][0]!=0; i++)
if ( strcmp(H->command,Iguana_validcommands[i]) == 0 )
break;
}
if ( Iguana_validcommands[i][0] != 0 )
{
iguana_rwnum(0,H->serdatalen,sizeof(H->serdatalen),(uint32_t *)&len);
if ( len > IGUANA_MAXPACKETSIZE )
return(-1);
}
return(len);
}
int32_t iguana_rwbignum(int32_t rwflag,uint8_t *serialized,int32_t len,uint8_t *endianedp)

181
crypto777/iguana_utils.c

@ -15,6 +15,27 @@
#include "../iguana/iguana777.h"
int32_t smallprimes[168] =
{
2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
73, 79, 83, 89, 97, 101, 103, 107, 109, 113,
127, 131, 137, 139, 149, 151, 157, 163, 167, 173,
179, 181, 191, 193, 197, 199, 211, 223, 227, 229,
233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
283, 293, 307, 311, 313, 317, 331, 337, 347, 349,
353, 359, 367, 373, 379, 383, 389, 397, 401, 409,
419, 421, 431, 433, 439, 443, 449, 457, 461, 463,
467, 479, 487, 491, 499, 503, 509, 521, 523, 541,
547, 557, 563, 569, 571, 577, 587, 593, 599, 601,
607, 613, 617, 619, 631, 641, 643, 647, 653, 659,
661, 673, 677, 683, 691, 701, 709, 719, 727, 733,
739, 743, 751, 757, 761, 769, 773, 787, 797, 809,
811, 821, 823, 827, 829, 839, 853, 857, 859, 863,
877, 881, 883, 887, 907, 911, 919, 929, 937, 941,
947, 953, 967, 971, 977, 983, 991, 997
};
bits256 bits256_doublesha256(char *hashstr,uint8_t *data,int32_t datalen)
{
bits256 hash,hash2; int32_t i;
@ -338,15 +359,6 @@ int32_t init_hexbytes_noT(char *hexbytes,unsigned char *message,long len)
return((int32_t)len*2+1);
}
void touppercase(char *str)
{
int32_t i;
if ( str == 0 || str[0] == 0 )
return;
for (i=0; str[i]!=0; i++)
str[i] = toupper(((int32_t)str[i]));
}
long _stripwhite(char *buf,int accept)
{
int32_t i,j,c;
@ -463,12 +475,49 @@ static int _increasing_double(const void *a,const void *b)
#undef double_b
}
int _increasing_uint64(const void *a,const void *b)
{
#define uint64_a (*(uint64_t *)a)
#define uint64_b (*(uint64_t *)b)
if ( uint64_b > uint64_a )
return(-1);
else if ( uint64_b < uint64_a )
return(1);
return(0);
#undef uint64_a
#undef uint64_b
}
static int _decreasing_uint64(const void *a,const void *b)
{
#define uint64_a (*(uint64_t *)a)
#define uint64_b (*(uint64_t *)b)
if ( uint64_b > uint64_a )
return(1);
else if ( uint64_b < uint64_a )
return(-1);
return(0);
#undef uint64_a
#undef uint64_b
}
int32_t sortds(double *buf,uint32_t num,int32_t size)
{
qsort(buf,num,size,_increasing_double);
return(0);
}
int32_t sort64s(uint64_t *buf,uint32_t num,int32_t size)
{
qsort(buf,num,size,_increasing_uint64);
return(0);
}
int32_t revsort64s(uint64_t *buf,uint32_t num,int32_t size)
{
qsort(buf,num,size,_decreasing_uint64);
return(0);
}
/*int32_t iguana_sortbignum(void *buf,int32_t size,uint32_t num,int32_t structsize,int32_t dir)
{
int32_t retval = 0;
@ -494,6 +543,15 @@ int32_t sortds(double *buf,uint32_t num,int32_t size)
}
*/
void touppercase(char *str)
{
int32_t i;
if ( str == 0 || str[0] == 0 )
return;
for (i=0; str[i]!=0; i++)
str[i] = toupper(((int32_t)str[i]));
}
void tolowercase(char *str)
{
int32_t i;
@ -503,6 +561,39 @@ void tolowercase(char *str)
str[i] = tolower(((int32_t)str[i]));
}
char *uppercase_str(char *buf,char *str)
{
if ( str != 0 )
{
strcpy(buf,str);
touppercase(buf);
} else buf[0] = 0;
return(buf);
}
char *lowercase_str(char *buf,char *str)
{
if ( str != 0 )
{
strcpy(buf,str);
tolowercase(buf);
} else buf[0] = 0;
return(buf);
}
int32_t strsearch(char *strs[],int32_t num,char *name)
{
int32_t i; char strA[32],refstr[32];
strcpy(refstr,name), touppercase(refstr);
for (i=0; i<num; i++)
{
strcpy(strA,strs[i]), touppercase(strA);
if ( strcmp(strA,refstr) == 0 )
return(i);
}
return(-1);
}
int32_t is_decimalstr(char *str)
{
int32_t i;
@ -810,6 +901,78 @@ int32_t RS_encode(char *rsaddr,uint64_t id)
return(0);
}
uint64_t conv_acctstr(char *acctstr)
{
uint64_t nxt64bits = 0;
int32_t len;
if ( acctstr != 0 )
{
if ( (len= is_decimalstr(acctstr)) > 0 && len < 24 )
nxt64bits = calc_nxt64bits(acctstr);
else if ( strncmp("NXT-",acctstr,4) == 0 )
{
nxt64bits = RS_decode(acctstr);
//nxt64bits = conv_rsacctstr(acctstr,0);
}
}
return(nxt64bits);
}
int32_t base32byte(int32_t val)
{
if ( val < 26 )
return('A' + val);
else if ( val < 32 )
return('2' + val - 26);
else return(-1);
}
int32_t unbase32(char c)
{
if ( c >= 'A' && c <= 'Z' )
return(c - 'A');
else if ( c >= '2' && c <= '7' )
return(c - '2' + 26);
else return(-1);
}
int init_base32(char *tokenstr,uint8_t *token,int32_t len)
{
int32_t i,j,n,val5,offset = 0;
for (i=n=0; i<len; i++)
{
for (j=val5=0; j<5; j++,offset++)
if ( GETBIT(token,offset) != 0 )
SETBIT(&val5,offset);
tokenstr[n++] = base32byte(val5);
}
tokenstr[n] = 0;
return(n);
}
int decode_base32(uint8_t *token,uint8_t *tokenstr,int32_t len)
{
int32_t i,j,n,val5,offset = 0;
for (i=n=0; i<len; i++)
{
if ( (val5= unbase32(tokenstr[i])) >= 0 )
{
for (j=val5=0; j<5; j++,offset++)
{
if ( GETBIT(&val5,j) != 0 )
SETBIT(token,offset);
else CLEARBIT(token,offset);
}
} else return(-1);
}
while ( (offset & 7) != 0 )
{
CLEARBIT(token,offset);
offset++;
}
return(offset);
}
void calc_hexstr(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len)
{
init_hexbytes_noT(hexstr,(void *)msg,len+1);

4
crypto777/nanosrc/transports/utils/base64.c

@ -24,7 +24,7 @@
#include <ctype.h>
int nn_base64_decode (const char *in, size_t in_len,
int _nn_base64_decode (const char *in, size_t in_len,
uint8_t *out, size_t out_len)
{
unsigned ii;
@ -101,7 +101,7 @@ int nn_base64_decode (const char *in, size_t in_len,
return io;
}
int nn_base64_encode (const uint8_t *in, size_t in_len,
int _nn_base64_encode (const uint8_t *in, size_t in_len,
char *out, size_t out_len)
{
unsigned ii;

247
deprecated/obsolete.h

@ -12845,4 +12845,251 @@ len = 0;
printf("ghash.(%s)\n",hashstr);
getchar();
bits256 issue_getpubkey(int32_t *haspubkeyp,char *acct)
{
cJSON *json; bits256 pubkey; char cmd[4096],*jsonstr; struct destbuf pubkeystr;
sprintf(cmd,"%s?requestType=getAccountPublicKey&account=%s",NXTAPIURL,acct);
jsonstr = issue_curl(cmd);
pubkeystr.buf[0] = 0;
if ( haspubkeyp != 0 )
*haspubkeyp = 0;
memset(&pubkey,0,sizeof(pubkey));
if ( jsonstr != 0 )
{
printf("PUBKEYRPC.(%s)\n",jsonstr);
if ( (json = cJSON_Parse(jsonstr)) != 0 )
{
copy_cJSON(&pubkeystr,cJSON_GetObjectItem(json,"publicKey"));
free_json(json);
if ( strlen(pubkeystr.buf) == sizeof(pubkey)*2 )
{
if ( haspubkeyp != 0 )
*haspubkeyp = 1;
decode_hex(pubkey.bytes,sizeof(pubkey),pubkeystr.buf);
}
}
free(jsonstr);
}
return(pubkey);
}
int32_t iguana_rwtxbytes(struct iguana_info *coin,int32_t rwflag,uint8_t *serialized,int32_t maxlen,bits256 *txidp,struct iguana_msgtx *tx)
{
int32_t i,len = 0; char str[65],str2[65],txidstr[65]; uint32_t numvins,numvouts; bits256 txid;
len += iguana_rwnum(rwflag,&serialized[len],sizeof(tx->version),&tx->version);
if ( coin->chain->hastimestamp != 0 )
len += iguana_rwnum(rwflag,&serialized[len],sizeof(tx->timestamp),&tx->timestamp);
numvins = tx->tx_in, numvouts = tx->tx_out;
len += iguana_rwvarint32(rwflag,&serialized[len],&numvins);
for (i=0; i<numvins; i++)
len += iguana_rwvin(rwflag,0,&serialized[len],&tx->vins[i]);
if ( len > maxlen )
return(0);
len += iguana_rwvarint32(rwflag,&serialized[len],&numvouts);
for (i=0; i<numvouts; i++)
len += iguana_rwvout(rwflag,0,&serialized[len],&tx->vouts[i]);
if ( len > maxlen )
return(0);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(tx->lock_time),&tx->lock_time);
txid = bits256_doublesha256(txidstr,serialized,len);
if ( rwflag != 0 )
tx->txid = txid;
else *txidp = txid;
if ( bits256_nonz(*txidp) > 0 && memcmp(txidp,tx->txid.bytes,sizeof(*txidp)) != 0 )
{
printf("iguana_rwtxbytes.rw%d: txid.%s vs %s\n",rwflag,bits256_str(str,tx->txid),bits256_str(str2,*txidp));
return(0);
}
return(len);
}
void pktest()
{
bits256 p,pub; uint8_t *data,*pubkey,sig[128],*sigptr; struct bp_key key; size_t pubk_len;
int32_t s,v,v2,v4=-99,v3=-99,datalen; uint32_t siglen; EC_KEY *KEY;
//bp_key_init(&key);
// bp_key_generate(&key);
OS_randombytes(p.bytes,sizeof(p));
data = (uint8_t *)"hello", datalen = (int32_t)strlen("hello");
//s = bp_sign(key.k,data,datalen,(void **)&sigptr,&siglen);
//sigptr = sig;
//siglen = iguana_sig(sig,sizeof(sig),data,datalen,p);
//const unsigned char *privkey;
//bp_privkey_set(&key,p.bytes,sizeof(p));
//bp_pubkey_get(&key,(void **)&pubkey,&pubk_len);
//memcpy(pub.bytes,pubkey+1,sizeof(pub));
KEY = bitcoin_privkeyset(&pub,p);
siglen = bitcoin_sign(sig,sizeof(sig),data,datalen,p);
s = siglen > 0;
// char str[65]; printf("siglen.%d pk_len.%ld %s\n",siglen,pubk_len,bits256_str(str,*(bits256 *)(pubkey+1)));
//s = ECDSA_sign(0,data,datalen,sig,&siglen,KEY);
v2 = bp_verify(KEY,data,datalen,sig,siglen);
//bp_pubkey_get(&key,(void **)&pubkey,&pubk_len);
//bp_key_init(&key);
v3 = bitcoin_verify(sig,siglen,data,datalen,pub);
//v = iguana_ver(sig,siglen,data,datalen,pub);
printf("s.%d siglen.%d v2.%d v3.%d v4.%d\n",s,siglen,v2,v3,v4);
getchar();
}
http://bitcoin.stackexchange.com/questions/3374/how-to-redeem-a-basic-tx
//msgtx->vins[i].scriptlen = scriptlen;
//printf("VINI.%d (%s)\n",vini,jprint(bitcoin_txjson(coin,msgtx),1));
//decode_hex(privkey.bytes,sizeof(privkey),"18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725");
//printf("privkey.%s\n",bits256_str(str,privkey));
//EC_KEY *KEY = bitcoin_privkeyset(&pkey,privkey);
char *refstr = "01000000\
01\
eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2\
01000000\
8c\
4930460221009e0339f72c793a89e664a8a932df073962a3f84eda0bd9e02084a6a9567f75aa022100bd9cbaca2e5ec195751efdfac164b76250b1e21302e51ca86dd7ebd7020cdc0601410450863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b23522cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6\
ffffffff\
01\
605af40500000000\
19\
76a914097072524438d003d23a2f23edb65aae1bb3e46988ac\
00000000";
char *iguana_txcreate(struct iguana_info *coin,uint8_t *space,int32_t maxlen,char *jsonstr)
{
struct iguana_txid T; struct iguana_msgvin *vins,*vin; struct iguana_msgvout *vouts,*vout;
char *redeemstr;
cJSON *array,*json,*item,*retjson = 0; bits256 scriptPubKey; int32_t i,numvins,numvouts,len = 0;
if ( (json= cJSON_Parse(jsonstr)) != 0 )
{
memset(&T,0,sizeof(T));
if ( (T.version= juint(json,"version")) == 0 )
T.version = 1;
if ( (T.locktime= juint(json,"locktime")) == 0 )
T.locktime = 0xffffffff;
vins = (struct iguana_msgvin *)&space[len];
if ( (array= jarray(&numvins,json,"vins")) != 0 )
{
len += sizeof(*vins) * numvins;
memset(vins,0,sizeof(*vins) * numvins);
//struct iguana_msgvin { bits256 prev_hash; uint8_t *script; uint32_t prev_vout,scriptlen,sequence; };
for (i=0; i<numvins; i++)
{
vin = &vins[i];
item = jitem(array,i);
vin->prev_hash = jbits256(item,"txid");
vin->prev_vout = juint(item,"vout");
vin->sequence = juint(item,"sequence");
scriptPubKey = jbits256(item,"scriptPubKey");
if ( bits256_nonz(scriptPubKey) > 0 )
{
if ( (redeemstr= jstr(item,"redeemScript")) == 0 )
{
vin->scriptlen = (int32_t)strlen(redeemstr);
if ( (vin->scriptlen & 1) != 0 )
{
free_json(json);
return(clonestr("{\"error\":\"odd redeemScript length\"}"));
}
vin->scriptlen >>= 1;
vin->script = &space[len], len += vin->scriptlen;
}
}
}
}
vouts = (struct iguana_msgvout *)&space[len];
if ( (array= jarray(&numvouts,json,"vouts")) != 0 )
{
len += sizeof(*vouts) * numvouts;
memset(vouts,0,sizeof(*vouts) * numvouts);
//struct iguana_msgvout { uint64_t value; uint32_t pk_scriptlen; uint8_t *pk_script; };
for (i=0; i<numvouts; i++)
{
vout = &vouts[i];
item = jitem(array,i);
printf("create vout\n");
}
}
T.numvins = numvins, T.numvouts = numvouts;
T.timestamp = (uint32_t)time(NULL);
if ( (len= iguana_ramtxbytes(coin,space,maxlen-len,&T.txid,&T,-1,vins,vouts)) > 0 )
{
}
free_json(json);
}
if ( retjson == 0 )
retjson = cJSON_Parse("{\"error\":\"couldnt create transaction\"}");
return(jprint(retjson,1));
}
/*
if ( bp_key_init(&key) != 0 && bp_key_secret_set(&key,privkey,32) != 0 )
{
if ( (T= calloc(1,sizeof(*T))) == 0 )
return(0);
*T = *refT; vin = &T->inputs[redeemi];
for (i=0; i<T->numinputs; i++)
strcpy(T->inputs[i].sigs,"00");
strcpy(vin->sigs,redeemscript);
vin->sequence = (uint32_t)-1;
T->nlocktime = 0;
//disp_cointx(&T);
emit_cointx(&hash2,data,sizeof(data),T,oldtx_format,SIGHASH_ALL);
//printf("HASH2.(%llx)\n",(long long)hash2.txid);
if ( bp_sign(&key,hash2.bytes,sizeof(hash2),&sig,&siglen) != 0 )
{
memcpy(sigbuf,sig,siglen);
sigbuf[siglen++] = SIGHASH_ALL;
init_hexbytes_noT(sigs[privkeyind],sigbuf,(int32_t)siglen);
strcpy(vin->sigs,"00");
for (i=0; i<n; i++)
{
if ( sigs[i][0] != 0 )
{
sprintf(vin->sigs + strlen(vin->sigs),"%02x%s",(int32_t)strlen(sigs[i])>>1,sigs[i]);
//printf("(%s).%ld ",sigs[i],strlen(sigs[i]));
}
}
len = (int32_t)(strlen(redeemscript)/2);
if ( len >= 0xfd )
sprintf(&vin->sigs[strlen(vin->sigs)],"4d%02x%02x",len & 0xff,(len >> 8) & 0xff);
else sprintf(&vin->sigs[strlen(vin->sigs)],"4c%02x",len);
sprintf(&vin->sigs[strlen(vin->sigs)],"%s",redeemscript);
//printf("after A.(%s) othersig.(%s) siglen.%02lx -> (%s)\n",hexstr,othersig != 0 ? othersig : "",siglen,vin->sigs);
//printf("vinsigs.(%s) %ld\n",vin->sigs,strlen(vin->sigs));
_emit_cointx(hexstr,sizeof(hexstr),T,oldtx_format);
//disp_cointx(&T);
free(T);
return(clonestr(hexstr));
}
*/
/*static char *validateretstr(struct iguana_info *coin,char *coinaddr)
{
char *retstr,buf[512]; cJSON *json;
if ( iguana_addressvalidate(coin,coinaddr) < 0 )
return(clonestr("{\"error\":\"invalid coin address\"}"));
sprintf(buf,"{\"agent\":\"ramchain\",\"coin\":\"%s\",\"method\":\"validate\",\"address\":\"%s\"}",coin->symbol,coinaddr);
if ( (json= cJSON_Parse(buf)) != 0 )
retstr = ramchain_coinparser(coin,"validate",json);
else return(clonestr("{\"error\":\"internal error, couldnt parse validate\"}"));
free_json(json);
return(retstr);
}
static char *validatepubkey(RPCARGS)
{
char *pubkeystr,coinaddr[128]; cJSON *retjson;
retjson = cJSON_CreateObject();
if ( params[0] != 0 && (pubkeystr= jstr(params[0],0)) != 0 )
{
if ( btc_coinaddr(coinaddr,coin->chain->pubval,pubkeystr) == 0 )
return(validateretstr(coin,coinaddr));
return(clonestr("{\"error\":\"cant convert pubkey\"}"));
}
return(clonestr("{\"error\":\"need pubkey\"}"));
}*/
#endif

1772
iguana/BTCD_hdrs.txt

File diff suppressed because it is too large

49
iguana/BTCD_peers.txt

@ -1,49 +0,0 @@
78.47.58.62
67.212.70.88
94.102.50.69
50.179.58.158
194.135.94.30
109.236.85.42
104.236.127.154
68.45.147.145
37.59.14.7
78.47.115.250
188.40.138.8
62.75.143.120
82.241.71.230
217.23.6.2
73.28.172.128
45.55.149.34
192.0.242.54
81.181.155.53
91.66.185.97
85.25.217.233
144.76.239.66
95.80.9.112
80.162.193.118
173.65.129.85
2.26.173.58
78.14.250.69
188.226.253.77
58.107.67.39
124.191.37.212
176.226.137.238
69.145.25.85
24.168.14.28
73.201.180.47
76.188.171.53
63.247.147.166
121.108.241.247
36.74.36.125
106.186.119.171
188.166.91.37
223.134.228.208
89.248.160.244
178.33.209.212
71.53.156.38
88.198.10.165
24.117.221.0
74.14.104.57
158.69.27.82
110.174.129.213
75.130.163.51

195
iguana/BTC_hdrs.txt

@ -1,195 +0,0 @@
386001
0 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
2000 00000000dfd5d65c9d8561b4b8f60a63018fe3933ecb131fb37f905f87da951a
4000 00000000922e2aa9e84a474350a3555f49f06061fd49df50a9352f156692a842
6000 00000000dbbb79792303bdd1c6c4d7ab9c21bba0667213c2eca955e11230c5a5
8000 0000000094fbacdffec05aea9847000522a258c269ae37a74a818afb96fc27d9
10000 0000000099c744455f58e6c6e98b671e1bf7f37346bfd4cf5d0274ad8ee660cb
12000 0000000011d1d9f1af3e1d038cebba251f933102dbe181d46a7966191b3299ee
14000 000000002d9050318ec8112057423e30b9570b39998aacd00ca648216525fce3
16000 00000000679a1ab3af6da03f13a0bc96d7215e65458b2d2edfa030b5b431e8b3
18000 00000000f914f0d0692e56bd06565ac4de668251b6a29fe0535d1e0031cfd0de
20000 00000000770ebe897270ca5f6d539d8afb4ea4f4e757761a34ca82e17207d886
22000 000000004625a14242beccb38c63a1f770a76ee5788764e6c0abd4129bbc1b9d
24000 00000000f04fccc81f37002707e9501a3f7bdcf25f65531f386a2da8af20122e
26000 000000006d6c151db6d4d67356d590a897a11cd7d8111ee989de6f2f548410bf
28000 00000000172c5ed49d7dfc29bf9a18a53fa2d050fa37aa210d6d4080fd0c7e67
30000 00000000de1250dc2df5cf4d877e055f338d6ed1ab504d5b71c097cdccd00e13
32000 00000000049172ba3ec1b673cf13e3d0049c1c07bb103ed3fa300e3833480055
34000 00000000495968d19210d3be15bd24fdc19805a0ef15026b0bb4482b04a9da3c
36000 0000000080c3deea35dc3df90a5fbe5f27db52f5e01018ae7d62f8b454c71335
38000 000000002dfebce284d1e08b6cf04452530891579b7377669865889498de8f3f
40000 00000000504d5fa0ad2cb90af16052a4eb2aea70fa1cba653b90a4583c5193e4
42000 000000000f80c09687893406279f62da437a6a0b95b8dc096b30c10ce088fc64
44000 000000000122898b31073a770a97cf599c00672fc8d6ae15652235862f8b76d8
46000 000000001dd39771dbe4f9fc6da07327f13f894dd2c1a46cdfcedf930fbbc52b
48000 000000000f3d40ea2bfa8d779010e52cff4720c072ec4b12ed576cf5cf93c947
50000 000000001aeae195809d120b5d66a39c83eb48792e068f8ea1fea19d84a4278a
52000 00000000082bc4398c4aa5bd8d9fc452d60d533ef68baabf594c9e7d6649049f
54000 00000000144197f54afa21ae7db2bc93eee604432101fc0ebe7966a52bb27e61
56000 000000000dfa452ea45e0426dd8914c35e24dfd4399037c5e6deb9f18f58d6d3
58000 0000000013e3791d288d9db814c52fbdf240b2206eb8e19d7dc80013c60c0c00
60000 000000000b554c46f8eb7264d7d5e334382c6fc3098dabf734de37962ccd7495
62000 0000000006dd4bc72daabef992f860e703820de119af3e24a1ea6f6c81521011
64000 0000000003d7055b51d7b9ab693de84c03201fe0396af61dbb30bf31445d3f55
66000 00000000071d7e8a0f4895e60c1073df9311d65a85244be1ee6369c9506281af
68000 0000000000d991791fdfdbccbbc2a73d2f86ccf78e2d0a7ce7675f40b5986b3e
70000 00000000002b8cd0faa58444df3ba2a22af2b5838c7e4a5b687444f913a575c2
72000 0000000000eb357d4c6fef6ad9a6fade126985ad36042a99cf215a4454545977
74000 0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20
76000 0000000000571138ff757a28ddf9b56f28c4a461e170660bb5ae79a556069bb6
78000 00000000001f3fe62641b473673c9ababbe207046a109f0861af95c905a918fa
80000 000000000043a8c0fd1d6f726790caa2a406010d19efd2780db27bdbbd93baf6
82000 00000000000c9d1c4acc114afb58d55db5ec44a963263cf6247220b7a3f85c5c
84000 00000000001385326e30864192ba84ed2f9cbfadf0698655b1c25f93c92f22ad
86000 000000000000ff4e1adb14f07774dad6b34968a5e19d1a2fe1fc9157e7c2b85d
88000 00000000000ae9e98b82b39a912cdc0ebed97c26376780ac996c84d9ec3264a4
90000 0000000000071694daf735a6b5da101d77a04c7e6008c680e461f0025ba7b7af
92000 0000000000001df90b0c523a4d7e4731336b00cf4ba9d8e02d111523df80998c
94000 000000000002a4c42580d51f0ddfd867eaaa790781c484c633a69167d17b48ec
96000 000000000002c86b568cdd2d0f4b0430cccf42bcde3361f63a32e23b5d839e99
98000 000000000002272a6dfb695d9db936d813bf0055ae92e920c2791d4c5f7290f1
100000 000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506
102000 00000000000335c47dd6ae953912d172a4d9839355f2083165043bb6f43c2f58
104000 000000000000a9887c91956b638bb3c0651321fdb24715354c3fc6633f5a16a3
106000 00000000000058d919f52d255f394ed0aa3a344432676fd30f1aab4e10c22fad
108000 00000000000167cea0b43ff7ce22f330d3e302832187eb31c61b15bb1511e118
110000 000000000001bbda3f22ef8e476b470a2d3ae16821c23a6d22db77318d0799a9
112000 0000000000001d69b3899a49f37799c375a7471829953d5470f468f48ff70432
114000 0000000000003195a1e6dc48a540264d37e9ef79b552bd78ea4b93a3b6e7e449
116000 00000000000007ff257fb2edd3fdbd7b00c127a66dae1288fc5e26c402d13bf7
118000 000000000000774a7f8a7a12dc906ddb9e17e75d684f15e00f8767f9e8f36553
120000 0000000000000e07595fca57b37fea8522e95e0f6891779cfd34d7e537524471
122000 0000000000002fe5f29af38282ac1c8f4ea2bf8a0855946150130419491b6c05
124000 00000000000023e9a0523cfac29afe07a07acf81e273cd892c51ff8318846620
126000 000000000000166b7d480aada35af1e6f9a2835d68f9c2fbd272073dc6c9d5fb
128000 00000000000003b8ddd8692769e1965554a8bb030863e0566a28bc0dc952864e
130000 00000000000011906b491883ab0f16f0e690b133ca860b199b775c3cf6581c21
132000 00000000000000a7a0483857f0d951983ff2834a47c38fdcc22563ac0f8f707b
134000 00000000000007e3e442ce1423496a064a7c34342ba98be164ac0c9f9b872213
136000 00000000000004da0d6d69fd474fa08fe2ff3111ff1e9e01f72899dcd9d897f0
138000 0000000000000044c7b6a5511c0b2ae64ec545abccac8053f31cf7bba23bb886
140000 000000000000086e28cf4717a80066def0ec26c53d660582bd997221fef297db
142000 00000000000006379826f5f10cd23739b9c29f87ca10f199f9f4b72006311f85
144000 0000000000000681a73f1bb50454cee419048d24e1091bcddadded89df53fd07
146000 0000000000000188cbeebda87456f040370995dc11eb3a1e76b1577b6e0b588d
148000 00000000000008be94b219a94752bde6a6a1c5b9d72abf2aaab53df7d93c5fa6
150000 0000000000000a3290f20e75860d505ce0e948a1d1d846bec7e39015d242884b
152000 0000000000000aca2b3a267dab498adc48afd15b60cbf21fa58dc26c86a6dc13
154000 0000000000000a7446d1a63b8229670aa02d1d9fdfd729b89107fe5d88dacd8e
156000 00000000000002adfcffbd5f09744ae3b930597dd0ea684cd37b816783ba3762
158000 00000000000000e50d56f13c7ce64183386abcac63462ca745b711be27568f52
160000 000000000000066c6e629b2fb49c7fcc52b82fe9833f328e0c3943856facf231
162000 00000000000001a83f5b20cd132f38f792fc02a17eb14d494c780ea9d1c82acc
164000 00000000000005a38f162cf308edea0a0a5d000bdb2073cba2386ebb1df7a2cf
166000 00000000000003b3402f35327d144a465f3768d6e6cb06cd8a2d8fc1328b2477
168000 000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763
170000 000000000000051f68f43e9d455e72d9c4e4ce52e8a00c5e24c07340632405cb
172000 0000000000000837e82c3a4ebe35a1d1d943e056234dba7c629922c6d4052d4c
174000 0000000000000504d3e701deb624eee4370f50c3d688fd1c27be5bbef07d76dd
176000 00000000000004659b5b8602b2132b62973994079a1c828df6ef8d6427e4686b
178000 00000000000009eae2697a7aaf57e730b707b9f4530449c16d924d534d41f297
180000 00000000000004ff83b6c10460b239ef4a6aa320e5fffd6c7bcedefa8c78593c
182000 000000000000068dce12903c1447e4c5b60311b61e443a25d5fc82c77f4f9a8f
184000 000000000000060405a235c6b968ccb18fd6b3800ae9742c2524e28863367359
186000 000000000000072ede9629fd1fd1af3cc2baa0e637f1959f34884be0e160dd1c
188000 000000000000004cf0c72d6dedfde88ca4c3dae129563210072ee68acded0ab1
190000 0000000000000708bf3b261ffc963b6a768d915f9cfc9ec0a6c2a09969efad1a
192000 00000000000000af130d565291ba49208c546685c69b48a293aaf06387fc22ef
194000 000000000000046242d4984ecf2217e9afa113f2835bffbff118f2df4d80b216
196000 00000000000006ae59396d4a289e83fe1b9967630752a5799f064620af7836a9
198000 000000000000000f2ad431ff18ab1673d911395c8fa1f6801e054c5dcb54f8fb
200000 000000000000034a7dedef4a161fa058a2d67a173a90155f3a2fe6fc132e0ebf
202000 00000000000003282fe1d5533e4275fd9f51e6ba0352ec01f32914e9fbaeaf55
204000 0000000000000423eb625dc140272ab97fea3ba6baf1dc56de77deabcc492872
206000 0000000000000130b815d40fd6d8851438cd21ac9e428615ba03a1285ef1374c
208000 000000000000001db5a1515a5f8534c941b1628f60466e6b709b3b320254afff
210000 000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e
212000 00000000000003d906e4131c39f7655b72df40146d2967f5d75113a09610de61
214000 00000000000003e6427f9fafa8b0e1af0859f15cea90d911f64445d296a2781a
216000 00000000000001f79a2db15d0ec6d951729e044749372caf504679bba5b1e65e
218000 0000000000000569070e338293af66258adba29dcdd5f33212314dff752ff458
220000 000000000000002fdd2c741ed50bc3975a640ca419081711f30f553939641303
222000 00000000000002c752a481ce0c45450ab046e640d38d6532178721e7700d8148
224000 0000000000000107ee276d037218bf1780dbf6d4256bd7e05c66ca133bbc9ac5
226000 000000000000012c614cf477c3b155d339f29d565c0258f9846c2f4dd402ff9b
228000 00000000000000efc4311c93fafbccedb6fdc682b566cba9519f1736b9788a67
230000 000000000000012cfb19f5662707816e122ad60dd9b1cd646c6c9899be2c9667
232000 000000000000018f47636e1c3a946db77624880ae484ffb0233f5aac6316b3bb
234000 00000000000000597f9263ea97bed4d3b10fbd55733a73bd1027f1a9b6c1451a
236000 00000000000000f2f5e55e89dde082cecc9b4a46a10bbb4197f5e35b16612db5
238000 000000000000010014007d4b51ab60063684665401e448c6b0b1971a7398a442
240000 000000000000000e7ad69c72afc00dc4e05fc15ae3061c47d3591d07c09f2928
242000 00000000000000c95233d37a8c78dff10afecb14060347151b7eb7a04a2a5a3c
244000 000000000000006ded1526017d5b87ca22e1bd0da3921872cc99e9ec77ee5166
246000 000000000000004c318a3ad2ebac28d140fada215b11f5b7d8e9151ff0b000af
248000 000000000000004d945017c14b75a3a58a2aa6772cacbfcaf907b3bee6d7f344
250000 000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214
252000 00000000000000200e99940b296ded4ce16462bba1950453b29abf313ba7cc47
254000 000000000000004753be91559a2c74c6cb8a5d2be6db1df2ca0b2385697e53ff
256000 00000000000000252b217c0ce5c4d96b825b90dacbe8e4dcf5f6a8ba6749f3c2
258000 00000000000000159f682a983465761f471dd24300746efe8db5642411f1b631
260000 000000000000001fb91fbcebaaba0e2d926f04908d798a8b598c3bd962951080
262000 000000000000001002ac67e026c523c3779b1ff2e3b9e2b7bfa6022ee1afae2a
264000 000000000000000d05c31485c532503939ca0b88d7e322dff79900ee6cdd5ed4
266000 0000000000000009d755c65d58c7c1fde9167ba632a85574de3bb11c8a862e35
268000 000000000000000048974ba0669938f7f8463650cd5c48c027aafd88c00a46af
270000 0000000000000002a775aec59dc6a9e4bb1c025cf1b8c2195dd9dc3998c827c5
272000 00000000000000050a89e2ffb28757d35e14615f23b981eca68906c8c71f65f2
274000 0000000000000003fe2d3425e9f9b906f02f40b3db90d908ba0fbd1e44cf43f8
276000 0000000000000004b8ed801f8a09ba8c1248a5b1dd1533a35124a80438573f59
278000 0000000000000001bcadd1e4b4d01063a17347dfca126c63893d2aa37d82eb7f
280000 0000000000000001c091ada69f444dc0282ecaabe4808ddbb2532e5555db0c03
282000 0000000000000002337ad25e6a9767420766309cfea79f13dd9c910bcf5ca063
284000 0000000000000000eac86582f121e5431734e2ea36bf73347022c99c1adae37f
286000 00000000000000004388ae444347bde423f2f3aa6ef335b50909f5bc27d31ea3
288000 00000000000000003c395f08779c3ac1301488b8a18c0999c008129a55610785
290000 0000000000000000fa0b2badd05db0178623ebf8dd081fe7eb874c26e27d0b3b
292000 0000000000000000620671231acb6a68134a0396235dcb0e53f4fc82bbaa1184
294000 0000000000000000cb2540b3f00ce422887904c75b24bf75b8a73817302a4138
296000 00000000000000009570102278e59ecf045c16ec8c8a5ea85bf823d0ec72e3d0
298000 000000000000000047d2f2eb7278e3f4aded9acaf502f5ec27bab5018b5871f2
300000 000000000000000082ccf8f1557c5d40b21edabb18d2d691cfbf87118bac7254
302000 0000000000000000072268c9bb18603566ed5012378c29bb4d37e34cead7448d
304000 00000000000000003558a1ceec3f5338c0e887b4171410195a7fa0a81bcaa628
306000 00000000000000002bb3265a8bf67ec2aa436c297ac7e56fcedd4dbaecccacc0
308000 00000000000000001d55aa114bddd81938d09e2dccd432dec59a4078ca0bc0f4
310000 0000000000000000125a28cc9e9209ddb75718f599a8039f6c9e7d9f1fb021e0
312000 00000000000000002bd1fa27964e31fe9861b40940e7ece2cfa359765b219a49
314000 000000000000000008ae6cb20997f3c4aacc50ee2f0d08a0c3691907fe7357a3
316000 00000000000000000d77a89ab1069e47d1213ae509de95ee0d9ab095a725f7d7
318000 00000000000000002583a647dc5f084a312e12bb90a70c3fe1eb1e4d419f35b6
320000 000000000000000015aab005b28a326ade60f07515c33517ea5cb598f28fb7ea
322000 0000000000000000177da809382f93ca1c4336811e4a910050689d317d62264e
324000 00000000000000000b9880c40075d763b2a5f04fc01444a6278c5d2d442cda0b
326000 00000000000000001e95e7216072cd53353b964054b592f7ce84d3743aab125a
328000 000000000000000009cb9a303d105e7b96b36546a3196f6f79ece4b43712cbb2
330000 00000000000000000faabab19f17c0178c754dbed023e6c871dcaf74159c5f02
332000 00000000000000001799255bc0c35f91f7d4fddfbf7e84dedf94fc59cde9b7f2
334000 000000000000000008d1ff7b7673837e9d7e1324dc7ab8498405ea583f43f53d
336000 0000000000000000125e3e6f327edcd7163b486efc16e79b8a996270127b54df
338000 00000000000000001983dc4a87df627b63cdce28e5321cb867fbbb74c0e87e8e
340000 00000000000000000d9b2508615d569e18f00c034d71474fc44a43af8d4a5003
342000 0000000000000000007220892af98a563a1c891c756e94be3f14edddcf637c3e
344000 000000000000000005f0a16f5a9f95eeb95c5eed0eb221e8f5dc5a9943a03aee
346000 0000000000000000068d33fd865621cb7eedbf05c6b235191fa1cb8ee2c797d7
348000 00000000000000001598a651988bb3a45237c4f801cf8049be20f74aed8e827a
350000 0000000000000000053cf64f0400bb38e0c4b3872c38795ddde27acb40a112bb
352000 00000000000000001635a4b5f27d2ec458f7bca550d71f490b93e98e7a07cbca
354000 00000000000000000cf8af9be2709e9d7adf2c33b3789aeeff517987f4be22e8
356000 0000000000000000138ce5493b612b0e90b66e2a76714088d6b3e6a4770215af
358000 0000000000000000073aceefab8c381c3c4edb4f87a6d5d2ae32184278218429
360000 00000000000000000ca6e07cf681390ff888b7f96790286a440da0f2b87c8ea6
362000 00000000000000000bfcad6c331dd152cfc713e9e0790978a10e0bfda3e030d5
364000 00000000000000000e20bcf213a0bbd6be88d5fede6b060c737f7f8b7f1df504
366000 0000000000000000138e108e780fdb71eb4cad533b46445ab6befbf9687f561f
368000 00000000000000000d39970aac12754eb89c2dcfda539b65562e5c3fec102c24
370000 000000000000000002cad3026f68357229dd6eaa6bcef6fe5166e1e53b039b8c
372000 0000000000000000028093cc8035a6bc4e0d1b40932c2f8b50312a3fc86bf3da
374000 00000000000000001016aa3783721673bebbcd1efa49946b52cceb09a81465a6
376000 0000000000000000106e9e99cf4fce4e8a4abc97f3e883956e26d76b3a1133ce
378000 00000000000000000516cd5b5f4b7e528d6e61c643595cc818f1d02f53da4281
380000 00000000000000000b06cee3cee10d2617e2024a996f5c613f7d786b15a571ff
382000 000000000000000003cf98590769bde40ffcd6800733ab47dd406d8203e65a89
384000 000000000000000005dc7ea53e2f6eeb09798cc9d2214f09d249661c36c288b3
386000 00000000000000000d94c8c0b0ddec874d2a597e988154733d9ea614292c08bb

137
iguana/BTC_peers.txt

@ -1,137 +0,0 @@
108.58.252.82
74.207.233.193
130.211.146.81
71.193.19.234
173.66.1.180
104.158.113.201
108.207.245.69
107.4.134.66
96.231.100.124
209.6.208.31
69.141.89.74
82.20.129.167
5.9.222.226
149.210.234.41
168.235.85.242
52.91.247.30
191.237.64.28
173.236.101.34
73.189.2.240
106.186.113.184
173.64.13.6
73.166.27.56
70.106.255.189
168.62.188.213
71.234.225.255
24.41.10.204
72.175.146.90
184.107.155.82
162.220.47.150
12.23.127.150
169.228.66.43
192.227.137.5
71.205.232.181
207.182.151.130
46.4.22.45
198.50.238.171
174.59.182.120
66.172.10.4
75.73.82.209
91.121.108.61
24.6.74.4
37.187.78.27
96.32.46.235
107.170.13.184
148.251.151.48
178.62.70.16
144.76.185.151
144.76.92.199
91.121.210.159
76.105.242.7
54.84.231.113
89.187.134.220
64.15.77.36
212.51.147.153
216.15.33.203
74.100.90.30
185.18.6.3
104.131.65.197
89.248.174.54
128.8.124.7
54.232.245.146
67.205.101.120
72.207.119.149
192.95.27.144
69.61.93.240
209.91.190.202
50.35.82.152
66.175.220.212
23.239.22.219
73.229.104.201
207.244.73.8
78.129.251.170
139.162.211.181
172.245.5.156
98.144.123.251
177.238.90.180
198.71.92.236
73.254.38.48
75.189.201.141
52.24.104.64
71.231.209.66
87.224.35.189
73.162.143.196
82.204.103.94
91.148.210.17
94.242.229.158
188.121.252.243
70.39.8.97
95.97.112.190
109.228.152.9
91.209.77.101
217.76.121.251
79.136.29.43
178.212.136.92
178.255.41.123
84.212.200.24
91.145.49.56
162.220.246.101
95.167.109.125
153.163.32.61
78.67.29.111
92.247.229.163
210.195.201.103
95.84.162.95
106.38.234.67
186.88.0.18
121.208.106.80
120.55.193.136
124.171.128.201
54.94.163.92
98.217.125.225
104.156.97.121
162.255.117.230
129.13.252.36
79.120.12.63
108.5.176.30
69.144.244.229
76.22.18.34
115.29.186.22
78.46.193.75
213.91.211.17
164.177.179.162
134.249.141.40
69.140.88.12
178.212.136.108
109.120.250.3
154.127.61.55
123.120.167.101
73.210.74.120
82.136.95.220
124.122.212.150
81.191.80.160
96.58.196.51
77.23.111.25
14.175.245.51
76.164.234.12
92.156.214.192

582
iguana/InstantDEX/InstantDEX.c

@ -0,0 +1,582 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#define _issue_curl(curl_handle,label,url) bitcoind_RPC(curl_handle,label,url,0,0,0)
#define INSTANTDEX_MINVOL 75
#define INSTANTDEX_MINVOLPERC ((double)INSTANTDEX_MINVOL / 100.)
#define INSTANTDEX_PRICESLIPPAGE 0.001
#define FINISH_HEIGHT 7
#define INSTANTDEX_TRIGGERDEADLINE 120
#define JUMPTRADE_SECONDS 100
#define INSTANTDEX_ACCT "4383817337783094122"
#define INSTANTDEX_FEE ((long)(2.5 * SATOSHIDEN))
#include "../iguana777.h"
#include "InstantDEX_quote.h"
#define INSTANTDEX_LOCALAPI "allorderbooks", "orderbook", "lottostats", "LSUM", "makebasket", "disable", "enable", "peggyrates", "tradesequence", "placebid", "placeask", "orderstatus", "openorders", "cancelorder", "tradehistory", "balance", "allexchanges",
typedef char *(*json_handler)(int32_t localaccess,int32_t valid,char *sender,cJSON **objs,int32_t numobjs,char *origargstr);
queue_t InstantDEXQ,TelepathyQ,Pending_offersQ;
cJSON *InstantDEX_lottostats();
//#include "NXT_tx.h"
#include "trades.h"
#include "quotes.h"
#include "subatomic.h"
#include "orderbooks.h"
#include "exchangeparse.h"
#include "exchange_trades.h"
#include "exchanges/poloniex.c"
#include "exchanges/bittrex.c"
#include "exchanges/btce.c"
#include "exchanges/bitfinex.c"
#include "exchanges/btc38.c"
#include "exchanges/huobi.c"
#include "exchanges/lakebtc.c"
#include "exchanges/quadriga.c"
#include "exchanges/okcoin.c"
#include "exchanges/coinbase.c"
#include "exchanges/bitstamp.c"
// {"plugin":"InstantDEX","method":"orderbook","baseid":"8688289798928624137","rel":"USD","exchange":"active","allfields":1}
// {"plugin":"InstantDEX","method":"orderbook","baseid":"17554243582654188572","rel":"12071612744977229797","exchange":"active","allfields":1}
// {"plugin":"InstantDEX","method":"orderbook","baseid":"6918149200730574743","rel":"XMR","exchange":"active","allfields":1}
void idle()
{
char *jsonstr,*str; cJSON *json; int32_t n = 0; uint32_t nonce;
/*printf("INSTANTDEX.readyflag.%d\n",INSTANTDEX.readyflag);
while ( INSTANTDEX.readyflag == 0 )
sleep(1);
printf("INSTANTDEX.readyflag.%d\n",INSTANTDEX.readyflag);*/
while ( 1 )
{
if ( n == 0 )
sleep(1);
n = 0;
if ( (jsonstr= queue_dequeue(&InstantDEXQ,1)) != 0 )
{
printf("Dequeued InstantDEX.(%s)\n",jsonstr);
if ( (json= cJSON_Parse(jsonstr)) != 0 )
{
//fprintf(stderr,"dequeued\n");
if ( (str= busdata_sync(&nonce,jsonstr,"allnodes",0)) != 0 )
{
//fprintf(stderr,"busdata.(%s)\n",str);
free(str);
}
free_json(json);
n++;
} else printf("error parsing (%s) from InstantDEXQ\n",jsonstr);
free_queueitem(jsonstr);
}
}
}
uint32_t _get_NXTheight(uint32_t *firsttimep)
{
static uint32_t last,lastheight,lastNXTtime;
cJSON *json; uint32_t height = 0; char cmd[256],*jsonstr;
if ( time(NULL) > last+10 )
{
sprintf(cmd,"requestType=getState");
if ( (jsonstr= issue_NXTPOST(cmd)) != 0 )
{
//printf("(%s) -> (%s)\n",cmd,jsonstr);
if ( (json= cJSON_Parse(jsonstr)) != 0 )
{
if ( firsttimep != 0 )
lastNXTtime = *firsttimep = (uint32_t)get_cJSON_int(json,"time");
height = (int32_t)get_cJSON_int(json,"numberOfBlocks");
if ( height > 0 )
height--;
lastheight = height;
free_json(json);
}
free(jsonstr);
}
last = (uint32_t)time(NULL);
}
else
{
height = lastheight;
if ( firsttimep != 0 )
*firsttimep = lastNXTtime;
}
return(height);
}
void idle2()
{
static double lastmilli;
uint32_t NXTblock;
//while ( INSTANTDEX.readyflag == 0 )
// sleep(1);
while ( 1 )
{
if ( milliseconds() < (lastmilli + 5000) )
sleep(1);
NXTblock = _get_NXTheight(0);
if ( 1 && NXTblock != prices777_NXTBLOCK )
{
prices777_NXTBLOCK = NXTblock;
InstantDEX_update(IGUANA_NXTADDR,IGUANA_NXTACCTSECRET);//,SUPERNET.);
//fprintf(stderr,"done idle NXT\n");
}
lastmilli = milliseconds();
}
}
cJSON *InstantDEX_lottostats()
{
char cmdstr[1024],NXTaddr[64],buf[1024],*jsonstr; struct destbuf receiverstr;
cJSON *json,*array,*txobj; int32_t i,n,totaltickets = 0; uint64_t amount,senderbits; uint32_t timestamp = 0;
if ( timestamp == 0 )
timestamp = 38785003;
sprintf(cmdstr,"requestType=getBlockchainTransactions&account=%s&timestamp=%u&type=0&subtype=0",INSTANTDEX_ACCT,timestamp);
//printf("cmd.(%s)\n",cmdstr);
if ( (jsonstr= issue_NXTPOST(cmdstr)) != 0 )
{
// printf("jsonstr.(%s)\n",jsonstr);
// mm string.({"requestProcessingTime":33,"transactions":[{"fullHash":"2a2aab3b84dadf092cf4cedcd58a8b5a436968e836338e361c45651bce0ef97e","confirmations":203,"signatureHash":"52a4a43d9055fe4861b3d13fbd03a42fecb8c9ad4ac06a54da7806a8acd9c5d1","transaction":"711527527619439146","amountNQT":"1100000000","transactionIndex":2,"ecBlockHeight":360943,"block":"6797727125503999830","recipientRS":"NXT-74VC-NKPE-RYCA-5LMPT","type":0,"feeNQT":"100000000","recipient":"4383817337783094122","version":1,"sender":"423766016895692955","timestamp":38929220,"ecBlockId":"10121077683890606382","height":360949,"subtype":0,"senderPublicKey":"4e5bbad625df3d536fa90b1e6a28c3f5a56e1fcbe34132391c8d3fd7f671cb19","deadline":1440,"blockTimestamp":38929430,"senderRS":"NXT-8E6V-YBWH-5VMR-26ESD","signature":"4318f36d9cf68ef0a8f58303beb0ed836b670914065a868053da5fe8b096bc0c268e682c0274e1614fc26f81be4564ca517d922deccf169eafa249a88de58036"}]})
if ( (json= cJSON_Parse(jsonstr)) != 0 )
{
if ( (array= cJSON_GetObjectItem(json,"transactions")) != 0 && is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 )
{
for (i=0; i<n; i++)
{
txobj = cJSON_GetArrayItem(array,i);
copy_cJSON(&receiverstr,cJSON_GetObjectItem(txobj,"recipient"));
if ( strcmp(receiverstr.buf,INSTANTDEX_ACCT) == 0 )
{
if ( (senderbits = get_API_nxt64bits(cJSON_GetObjectItem(txobj,"sender"))) != 0 )
{
expand_nxt64bits(NXTaddr,senderbits);
amount = get_API_nxt64bits(cJSON_GetObjectItem(txobj,"amountNQT"));
if ( amount == INSTANTDEX_FEE )
totaltickets++;
else if ( amount >= 2*INSTANTDEX_FEE )
totaltickets += 2;
}
}
}
}
free_json(json);
}
free(jsonstr);
}
sprintf(buf,"{\"result\":\"lottostats\",\"totaltickets\":\"%d\"}",totaltickets);
return(cJSON_Parse(buf));
}
void set_best_amounts(int64_t *baseamountp,int64_t *relamountp,double price,double volume)
{
double checkprice,checkvol,distA,distB,metric,bestmetric = (1. / SMALLVAL);
uint64_t baseamount,relamount,bestbaseamount = 0,bestrelamount = 0;
int32_t i,j;
baseamount = volume * SATOSHIDEN;
relamount = ((price * volume) * SATOSHIDEN);
//*baseamountp = baseamount, *relamountp = relamount;
//return;
for (i=-1; i<=1; i++)
for (j=-1; j<=1; j++)
{
checkprice = prices777_price_volume(&checkvol,baseamount+i,relamount+j);
distA = (checkprice - price);
distA *= distA;
distB = (checkvol - volume);
distB *= distB;
metric = sqrt(distA + distB);
if ( metric < bestmetric )
{
bestmetric = metric;
bestbaseamount = baseamount + i;
bestrelamount = relamount + j;
//printf("i.%d j.%d metric. %f\n",i,j,metric);
}
}
*baseamountp = bestbaseamount;
*relamountp = bestrelamount;
}
int32_t bidask_parse(int32_t localaccess,struct destbuf *exchangestr,struct destbuf *name,struct destbuf *base,struct destbuf *rel,struct destbuf *gui,struct InstantDEX_quote *iQ,cJSON *json)
{
uint64_t basemult,relmult,baseamount,relamount; double price,volume; int32_t exchangeid,keysize,flag; char key[1024],buf[64],*methodstr;
memset(iQ,0,sizeof(*iQ));
iQ->s.baseid = j64bits(json,"baseid"); iQ->s.relid = j64bits(json,"relid");
iQ->s.baseamount = j64bits(json,"baseamount"), iQ->s.relamount = j64bits(json,"relamount");
iQ->s.vol = jdouble(json,"volume"); iQ->s.price = jdouble(json,"price");
copy_cJSON(exchangestr,jobj(json,"exchange"));
if ( exchangestr->buf[0] == 0 || find_exchange(&exchangeid,exchangestr->buf) == 0 )
exchangeid = -1;
iQ->exchangeid = exchangeid;
copy_cJSON(base,jobj(json,"base"));
copy_cJSON(rel,jobj(json,"rel"));
copy_cJSON(name,jobj(json,"name"));
methodstr = jstr(json,"method");
if ( methodstr != 0 && (strcmp(methodstr,"placeask") == 0 || strcmp(methodstr,"ask") == 0) )
iQ->s.isask = 1;
if ( iQ->s.vol < 0. )
{
iQ->s.vol = -iQ->s.vol;
iQ->s.isask ^= 1;
}
if ( methodstr != 0 && strcmp(exchangestr->buf,"wallet") == 0 && (iQ->s.baseid == NXT_ASSETID || strcmp(base->buf,"NXT") == 0) )
{
flag = 1;
if ( strcmp(methodstr,"placeask") == 0 )
methodstr = "placebid";
else if ( strcmp(methodstr,"placebid") == 0 )
methodstr = "placeask";
else if ( strcmp(methodstr,"ask") == 0 )
methodstr = "bid";
else if ( strcmp(methodstr,"bid") == 0 )
methodstr = "ask";
else flag = 0;
if ( flag != 0 )
{
iQ->s.baseid = iQ->s.relid, iQ->s.relid = NXT_ASSETID;
strcpy(base->buf,rel->buf), strcpy(rel->buf,"NXT");
baseamount = iQ->s.baseamount;
iQ->s.baseamount = iQ->s.relamount, iQ->s.relamount = baseamount;
name->buf[0] = 0;
if ( iQ->s.vol > SMALLVAL && iQ->s.price > SMALLVAL )
{
iQ->s.vol *= iQ->s.price;
iQ->s.price = 1. / iQ->s.price;
}
iQ->s.isask ^= 1;
printf("INVERT\n");
}
}
if ( (iQ->s.timestamp= juint(json,"timestamp")) == 0 )
iQ->s.timestamp = (uint32_t)time(NULL);
copy_cJSON(gui,jobj(json,"gui")), strncpy(iQ->gui,gui->buf,sizeof(iQ->gui)-1);
iQ->s.automatch = juint(json,"automatch");
iQ->s.minperc = juint(json,"minperc");
if ( (iQ->s.duration= juint(json,"duration")) == 0 || iQ->s.duration > ORDERBOOK_EXPIRATION )
iQ->s.duration = ORDERBOOK_EXPIRATION;
InstantDEX_name(key,&keysize,exchangestr->buf,name->buf,base->buf,&iQ->s.baseid,rel->buf,&iQ->s.relid);
//printf(">>>>>>>>>>>> BASE.(%s) REL.(%s)\n",base->buf,rel->buf);
iQ->s.basebits = stringbits(base->buf);
iQ->s.relbits = stringbits(rel->buf);
safecopy(iQ->base,base->buf,sizeof(iQ->base));
safecopy(iQ->rel,rel->buf,sizeof(iQ->rel));
iQ->s.offerNXT = j64bits(json,"offerNXT");
iQ->s.quoteid = j64bits(json,"quoteid");
if ( strcmp(exchangestr->buf,"jumblr") == 0 || strcmp(exchangestr->buf,"pangea") == 0 )
{
if ( strcmp(exchangestr->buf,"pangea") == 0 )
{
if ( juint(json,"rakemillis") != 0 )
iQ->s.minperc = juint(json,"rakemillis");
if ( j64bits(json,"bigblind") != 0 )
{
iQ->s.baseamount = j64bits(json,"bigblind");
iQ->s.vol = ((double)iQ->s.baseamount / SATOSHIDEN);
}
if ( j64bits(json,"ante") != 0 )
iQ->s.relamount = j64bits(json,"ante");
iQ->s.minbuyin = juint(json,"minbuyin");
iQ->s.maxbuyin = juint(json,"maxbuyin");
/*if ( (iQ->s.maxrake= j64bits(json,"maxrake")) != 0 )
{
if ( strcmp(base->buf,"BTC") == 0 && iQ->s.maxrake < SATOSHIDEN/10 )
iQ->s.maxrake = SATOSHIDEN/10;
else if ( iQ->s.maxrake < 10*SATOSHIDEN )
iQ->s.maxrake = 10*SATOSHIDEN;
}*/
}
if ( iQ->s.price == 0. )
iQ->s.price = 1.;
if ( iQ->s.vol == 0. )
iQ->s.vol = 1.;
if ( iQ->s.baseamount == 0 )
iQ->s.baseamount = iQ->s.vol * SATOSHIDEN;
if ( localaccess != 0 && strcmp(exchangestr->buf,"jumblr") == 0 )
{
#ifdef later
struct coin777 *coin; int32_t maxamount;
if ( (coin= coin777_find(base->buf,0)) != 0 )
{
if ( coin->jvin == 0 && coin->jvinaddr[0] == 0 )
{
coin->jvin = -1;
printf("initial state for jumblr.%s detected\n",coin->name);
sleep(5);
}
if ( coin->jvin < 0 )
{
printf("no %s unspents available for jumblr/pangea jvin.%d %.8f\n",coin->name,coin->jvin,dstr(coin->junspent));
return(-1);
}
maxamount = coin->junspent - coin->mgw.txfee*2 - (coin->junspent>>10);
if ( iQ->s.baseamount > maxamount )
iQ->s.baseamount = maxamount;
else if ( iQ->s.baseamount < coin->mgw.txfee )
{
printf("jumblr/pangea amount %.8f less than txfee %.8f\n",dstr(iQ->s.baseamount),dstr(coin->mgw.txfee));
return(-1);
}
}
else
{
printf("%s not initialized for jumblr\n",base->buf);
return(-1);
}
#endif
}
}
else
{
if ( iQ->s.baseamount == 0 || iQ->s.relamount == 0 )
{
if ( iQ->s.price <= SMALLVAL || iQ->s.vol <= SMALLVAL )
return(-1);
set_best_amounts(&iQ->s.baseamount,&iQ->s.relamount,iQ->s.price,iQ->s.vol);
}
}
if ( iQ->s.quoteid == 0 )
iQ->s.quoteid = calc_quoteid(iQ);
else if ( iQ->s.quoteid != calc_quoteid(iQ) )
{
printf("bidask_parse quoteid.%llu != calc.%llu\n",(long long)iQ->s.quoteid,(long long)calc_quoteid(iQ));
return(-1);
}
if ( iQ->s.price > SMALLVAL && iQ->s.vol > SMALLVAL && iQ->s.baseid != 0 && iQ->s.relid != 0 )
{
buf[0] = 0, _set_assetname(&basemult,buf,0,iQ->s.baseid);
printf("baseid.%llu -> %s mult.%llu\n",(long long)iQ->s.baseid,buf,(long long)basemult);
buf[0] = 0, _set_assetname(&relmult,buf,0,iQ->s.relid);
printf("relid.%llu -> %s mult.%llu\n",(long long)iQ->s.relid,buf,(long long)relmult);
//basemult = get_assetmult(iQ->baseid), relmult = get_assetmult(iQ->relid);
baseamount = (iQ->s.baseamount + basemult/2) / basemult, baseamount *= basemult;
relamount = (iQ->s.relamount + relmult/2) / relmult, relamount *= relmult;
if ( iQ->s.price != 0. && iQ->s.vol != 0 )
{
price = prices777_price_volume(&volume,baseamount,relamount);
if ( fabs(iQ->s.price - price)/price > 0.001 )
{
printf("cant create accurate price ref.(%f %f) -> (%f %f)\n",iQ->s.price,iQ->s.vol,price,volume);
return(-1);
}
}
}
return(0);
}
char *InstantDEX(char *jsonstr,char *remoteaddr,int32_t localaccess)
{
char *prices777_allorderbooks();
char *InstantDEX_tradehistory(cJSON *json,int32_t firsti,int32_t endi);
char *InstantDEX_cancelorder(cJSON *json,char *activenxt,char *secret,uint64_t sequenceid,uint64_t quoteid);
struct destbuf exchangestr,method,gui,name,base,rel; double balance;
char *retstr = 0,key[512],retbuf[1024],*activenxt,*secret,*coinstr; struct InstantDEX_quote iQ; struct exchange_info *exchange;
cJSON *json; uint64_t assetbits,sequenceid; uint32_t maxdepth; int32_t invert=0,keysize,allfields; struct prices777 *prices = 0;
//printf("INSTANTDEX.(%s)\n",jsonstr);
//if ( INSTANTDEX.readyflag == 0 )
// return(0);
if ( jsonstr != 0 && (json= cJSON_Parse(jsonstr)) != 0 )
{
// test: asset/asset, asset/external, external/external, autofill and automatch
// peggy integration
if ( bidask_parse(localaccess,&exchangestr,&name,&base,&rel,&gui,&iQ,json) < 0 && (strcmp(exchangestr.buf,"jumblr") == 0 || strcmp(exchangestr.buf,"pangea") == 0) )
{
//return(clonestr("{\"error\":\"invalid parameters\"}"));
}
if ( iQ.s.offerNXT == 0 )
iQ.s.offerNXT = IGUANA_MY64BITS;
printf("isask.%d base.(%s) rel.(%s)\n",iQ.s.isask,base.buf,rel.buf);
copy_cJSON(&method,jobj(json,"method"));
if ( (sequenceid= j64bits(json,"orderid")) == 0 )
sequenceid = j64bits(json,"sequenceid");
allfields = juint(json,"allfields");
if ( (maxdepth= juint(json,"maxdepth")) <= 0 )
maxdepth = MAX_DEPTH;
if ( exchangestr.buf[0] == 0 )
{
if ( iQ.s.baseid != 0 && iQ.s.relid != 0 )
strcpy(exchangestr.buf,"nxtae");
else strcpy(exchangestr.buf,"basket");
}
assetbits = InstantDEX_name(key,&keysize,exchangestr.buf,name.buf,base.buf,&iQ.s.baseid,rel.buf,&iQ.s.relid);
//printf("2nd isask.%d base.(%s) rel.(%s)\n",iQ.s.isask,base.buf,rel.buf);
exchange = exchange_find(exchangestr.buf);
secret = jstr(json,"secret"), activenxt = jstr(json,"activenxt");
if ( secret == 0 )
{
secret = IGUANA_NXTACCTSECRET;
activenxt = IGUANA_NXTADDR;
}
if ( strcmp(method.buf,"exit") == 0 )
{
printf("getchar and then exit\n");
getchar();
exit(0);
}
if ( strcmp(method.buf,"orderstatus") == 0 )
retstr = InstantDEX_orderstatus(json,sequenceid,iQ.s.quoteid);
else if ( strcmp(method.buf,"cancelorder") == 0 )
retstr = InstantDEX_cancelorder(json,jstr(json,"activenxt"),jstr(json,"secret"),sequenceid,iQ.s.quoteid);
else if ( strcmp(method.buf,"openorders") == 0 )
retstr = InstantDEX_openorders(json,IGUANA_NXTADDR,juint(json,"allorders"));
else if ( strcmp(method.buf,"tradehistory") == 0 )
retstr = InstantDEX_tradehistory(json,juint(json,"firsti"),juint(json,"endi"));
else if ( strcmp(method.buf,"withdraw") == 0 )
retstr = InstantDEX_withdraw(json);
else if ( strcmp(method.buf,"balance") == 0 )
{
if ( exchange != 0 && exchange->issue.trade != 0 )
{
if ( exchange->issue.balances != 0 )
{
if ( exchange->balancejson != 0 )
free_json(exchange->balancejson), exchange->balancejson = 0;
exchange->lastbalancetime = (uint32_t)time(NULL);
if ( (exchange->balancejson= (*exchange->issue.balances)(&exchange->cHandle,exchange)) != 0 )
{
if ( (coinstr= jstr(json,"base")) != 0 )
retstr = (*exchange->issue.parsebalance)(exchange,&balance,coinstr);
else retstr = jprint(exchange->balancejson,0);
} else retstr = clonestr("{\"error\":\"balances null return\"}");
} else retstr = clonestr("{\"error\":\"no balances function\"}");
} else retstr = clonestr("{\"error\":\"cant find exchange trade or balances function\"}");
printf("%s ptr.%p trade.%p\n",exchangestr.buf,exchange,exchange!=0?exchange->issue.trade:0);
}
else if ( strcmp(method.buf,"allorderbooks") == 0 )
retstr = prices777_allorderbooks();
else if ( strcmp(method.buf,"allexchanges") == 0 )
retstr = jprint(exchanges_json(),1);
else if ( strcmp(method.buf,"lottostats") == 0 )
retstr = jprint(InstantDEX_lottostats(),1);
/* else if ( strcmp(method.buf,"tradesequence") == 0 )
{
//printf("call tradesequence.(%s)\n",jsonstr);
int32_t dotrade,numtrades; struct prices777_order trades[256]; struct pending_trade *pend;
dotrade = juint(json,"dotrade");
retstr = InstantDEX_tradesequence(0,0,0,&numtrades,trades,(int32_t)(sizeof(trades)/sizeof(*trades)),dotrade,activenxt,secret,json);
if ( dotrade != 0 )
{
pend = calloc(1,sizeof(*pend));
pend->dir = iQ.s.isask == 0 ? 1 : -1, pend->price = iQ.s.price, pend->volume = iQ.s.vol, pend->orderid = iQ.s.quoteid;
pend->tradesjson = json;
pend->type = 'S';
pend->timestamp = (uint32_t)time(NULL);
//InstantDEX_history(0,pend,0);
queue_enqueue("PendingQ",&Pending_offersQ.pingpong[0],&pend->DL,0);
}
}*/
else if ( strcmp(method.buf,"makebasket") == 0 )
{
if ( (prices= prices777_makebasket(0,json,1,"basket",0,0)) != 0 )
retstr = clonestr("{\"result\":\"basket made\"}");
else retstr = clonestr("{\"error\":\"couldnt make basket\"}");
}
else if ( strcmp(method.buf,"peggyrates") == 0 )
{
//if ( SUPERNET.peggy != 0 )
// retstr = peggyrates(juint(json,"timestamp"),jstr(json,"name"));
//else retstr = clonestr("{\"error\":\"peggy disabled\"}");
}
else if ( strcmp(method.buf,"LSUM") == 0 )
{
sprintf(retbuf,"{\"result\":\"%s\",\"amount\":%d}",(rand() & 1) ? "BUY" : "SELL",(rand() % 100) * 100000);
retstr = clonestr(retbuf);
}
else if ( strcmp(method.buf,"placebid") == 0 || strcmp(method.buf,"placeask") == 0 )
return(InstantDEX_placebidask(0,sequenceid,exchangestr.buf,name.buf,base.buf,rel.buf,&iQ,jstr(json,"extra"),secret,activenxt,json));
else if ( strcmp(exchangestr.buf,"active") == 0 && strcmp(method.buf,"orderbook") == 0 )
retstr = prices777_activebooks(name.buf,base.buf,rel.buf,iQ.s.baseid,iQ.s.relid,maxdepth,allfields,strcmp(exchangestr.buf,"active") == 0 || juint(json,"tradeable"));
else if ( (prices= prices777_find(&invert,iQ.s.baseid,iQ.s.relid,exchangestr.buf)) == 0 )
{
if ( (prices= prices777_poll(exchangestr.buf,name.buf,base.buf,iQ.s.baseid,rel.buf,iQ.s.relid)) != 0 )
{
if ( prices777_equiv(prices->baseid) == prices777_equiv(iQ.s.baseid) && prices777_equiv(prices->relid) == prices777_equiv(iQ.s.relid) )
invert = 0;
else if ( prices777_equiv(prices->baseid) == prices777_equiv(iQ.s.relid) && prices777_equiv(prices->relid) == prices777_equiv(iQ.s.baseid) )
invert = 1;
else invert = 0, printf("baserel not matching (%s %s) %llu %llu vs (%s %s) %llu %llu\n",prices->base,prices->rel,(long long)prices->baseid,(long long)prices->relid,base.buf,rel.buf,(long long)iQ.s.baseid,(long long)iQ.s.relid);
}
}
if ( retstr == 0 && prices != 0 )
{
if ( strcmp(method.buf,"disablequotes") == 0 )
{
if ( prices != 0 )
{
if ( strcmp(prices->exchange,"unconf") == 0 )
return(clonestr("{\"error\":\"cannot disable unconf\"}"));
prices->disabled = 1;
return(clonestr("{\"result\":\"success\"}"));
}
else return(clonestr("{\"error\":\"no prices to disable\"}"));
}
else if ( strcmp(method.buf,"enablequotes") == 0 )
{
if ( prices != 0 )
{
prices->disabled = 0;
return(clonestr("{\"result\":\"success\"}"));
}
else return(clonestr("{\"error\":\"no prices to enable\"}"));
}
else if ( strcmp(method.buf,"orderbook") == 0 )
{
if ( maxdepth < MAX_DEPTH )
return(prices777_orderbook_jsonstr(invert,IGUANA_MY64BITS,prices,&prices->O,maxdepth,allfields));
else if ( (retstr= prices->orderbook_jsonstrs[invert][allfields]) == 0 )
{
retstr = prices777_orderbook_jsonstr(invert,IGUANA_MY64BITS,prices,&prices->O,MAX_DEPTH,allfields);
portable_mutex_lock(&prices->mutex);
if ( prices->orderbook_jsonstrs[invert][allfields] != 0 )
free(prices->orderbook_jsonstrs[invert][allfields]);
prices->orderbook_jsonstrs[invert][allfields] = retstr;
portable_mutex_unlock(&prices->mutex);
if ( retstr == 0 )
retstr = clonestr("{}");
}
if ( retstr != 0 )
retstr = clonestr(retstr);
}
//else if ( strcmp(method.buf,"tradebot") == 0 )
// retstr = InstantDEX_tradebot(prices,json,&iQ,invert);
}
//if ( Debuglevel > 2 )
printf("(%s) %p exchange.(%s) base.(%s) %llu rel.(%s) %llu | name.(%s) %llu\n",retstr!=0?retstr:"",prices,exchangestr.buf,base.buf,(long long)iQ.s.baseid,rel.buf,(long long)iQ.s.relid,name.buf,(long long)assetbits);
}
return(retstr);
}
char *bidask_func(int32_t localaccess,int32_t valid,char *sender,cJSON *json,char *origargstr)
{
struct destbuf gui,exchangestr,name,base,rel,offerNXT; struct InstantDEX_quote iQ;
copy_cJSON(&offerNXT,jobj(json,"offerNXT"));
//printf("got (%s)\n",origargstr);
if ( strcmp(IGUANA_NXTADDR,offerNXT.buf) != 0 )
{
if ( bidask_parse(localaccess,&exchangestr,&name,&base,&rel,&gui,&iQ,json) == 0 )
return(InstantDEX_placebidask(sender,j64bits(json,"orderid"),exchangestr.buf,name.buf,base.buf,rel.buf,&iQ,jstr(json,"extra"),jstr(json,"secret"),jstr(json,"activenxt"),json));
else printf("error with incoming bidask\n");
} else fprintf(stderr,"got my bidask from network (%s)\n",origargstr);
return(clonestr("{\"result\":\"got loopback bidask\"}"));
}

223
iguana/InstantDEX/InstantDEX_quote.h

@ -0,0 +1,223 @@
//
// sha256.h
// crypto777
//
// Created by James on 4/9/15.
// Copyright (c) 2015 jl777. All rights reserved.
//
#ifndef crypto777_InstantDEX_quote_h
#define crypto777_InstantDEX_quote_h
#include <stdint.h>
#include "../includes/uthash.h"
#define NXT_ASSETID ('N' + ((uint64_t)'X'<<8) + ((uint64_t)'T'<<16)) // 5527630
#define MAX_BUYNXT 10
#define MIN_NQTFEE 100000000
#define NXT_TOKEN_LEN 160
#define GENESISACCT "1739068987193023818" // NXT-MRCC-2YLS-8M54-3CMAJ
#define GENESISPUBKEYSTR "1259ec21d31a30898d7cd1609f80d9668b4778e3d97e941044b39f0c44d2e51b"
#define GENESISPRIVKEYSTR "1259ec21d31a30898d7cd1609f80d9668b4778e3d97e941044b39f0c44d2e51b"
#define GENESIS_SECRET "It was a bright cold day in April, and the clocks were striking thirteen."
#define GENESISBLOCK "2680262203532249785"
#define NXT_GENESISTIME 1385294400
#define DEFAULT_NXT_DEADLINE 720
#define issue_curl(cmdstr) bitcoind_RPC(0,"curl",cmdstr,0,0,0)
#define issue_NXT(cmdstr) bitcoind_RPC(0,"NXT",cmdstr,0,0,0)
#define issue_NXTPOST(cmdstr) bitcoind_RPC(0,"curl",NXTAPIURL,0,0,cmdstr)
#define fetch_URL(url) bitcoind_RPC(0,"fetch",url,0,0,0)
#define INSTANTDEX_TRIGGERDEADLINE 120
#define _issue_curl(curl_handle,label,url) bitcoind_RPC(curl_handle,label,url,0,0,0)
#define ORDERBOOK_EXPIRATION 3600
#define INSTANTDEX_MINVOL 75
#define INSTANTDEX_MINVOLPERC ((double)INSTANTDEX_MINVOL / 100.)
#define INSTANTDEX_PRICESLIPPAGE 0.001
#define INSTANTDEX_TRIGGERDEADLINE 120
#define JUMPTRADE_SECONDS 100
#define INSTANTDEX_ACCT "4383817337783094122"
#define INSTANTDEX_FEE ((long)(2.5 * SATOSHIDEN))
#define INSTANTDEX_NAME "InstantDEX"
#define INSTANTDEX_NXTAENAME "nxtae"
#define INSTANTDEX_NXTAEUNCONF "unconf"
#define INSTANTDEX_BASKETNAME "basket"
#define INSTANTDEX_ACTIVENAME "active"
#define INSTANTDEX_EXCHANGEID 0
#define INSTANTDEX_UNCONFID 1
#define INSTANTDEX_NXTAEID 2
#define MAX_EXCHANGES 64
#define ORDERBOOK_EXPIRATION 3600
#define NXT_ASSETID ('N' + ((uint64_t)'X'<<8) + ((uint64_t)'T'<<16)) // 5527630
#define BTC_ASSETID ('B' + ((uint64_t)'T'<<8) + ((uint64_t)'C'<<16)) // 4412482
#define LTC_ASSETID ('L' + ((uint64_t)'T'<<8) + ((uint64_t)'C'<<16))
#define PPC_ASSETID ('P' + ((uint64_t)'P'<<8) + ((uint64_t)'C'<<16))
#define NMC_ASSETID ('N' + ((uint64_t)'M'<<8) + ((uint64_t)'C'<<16))
#define DASH_ASSETID ('D' + ((uint64_t)'A'<<8) + ((uint64_t)'S'<<16) + ((uint64_t)'H'<<24))
#define BTCD_ASSETID ('B' + ((uint64_t)'T'<<8) + ((uint64_t)'C'<<16) + ((uint64_t)'D'<<24))
#define USD_ASSETID ('U' + ((uint64_t)'S'<<8) + ((uint64_t)'D'<<16))
#define CNY_ASSETID ('C' + ((uint64_t)'N'<<8) + ((uint64_t)'Y'<<16))
#define EUR_ASSETID ('E' + ((uint64_t)'U'<<8) + ((uint64_t)'R'<<16))
#define RUR_ASSETID ('R' + ((uint64_t)'U'<<8) + ((uint64_t)'R'<<16))
struct InstantDEX_shared
{
double price,vol;
uint64_t quoteid,offerNXT,basebits,relbits,baseid,relid; int64_t baseamount,relamount;
uint32_t timestamp;
uint16_t duration:14,wallet:1,a:1,isask:1,expired:1,closed:1,swap:1,responded:1,matched:1,feepaid:1,automatch:1,pending:1,minperc:7;
uint16_t minbuyin,maxbuyin;
};
struct InstantDEX_quote
{
UT_hash_handle hh;
struct InstantDEX_shared s; // must be here
char exchangeid,gui[9],base[8],rel[8];
char walletstr[];
};
struct InstantDEX_quote *delete_iQ(uint64_t quoteid);
struct InstantDEX_quote *find_iQ(uint64_t quoteid);
struct InstantDEX_quote *create_iQ(struct InstantDEX_quote *iQ,char *walletstr);
uint64_t calc_quoteid(struct InstantDEX_quote *iQ);
cJSON *set_walletstr(cJSON *walletitem,char *walletstr,struct InstantDEX_quote *iQ);
cJSON *InstantDEX_specialorders(uint64_t *quoteidp,uint64_t nxt64bits,char *base,char *special,uint64_t baseamount,int32_t addrtype);
int32_t bidask_parse(int32_t localaccess,struct destbuf *exchangestr,struct destbuf *name,struct destbuf *base,struct destbuf *rel,struct destbuf *gui,struct InstantDEX_quote *iQ,cJSON *json);
int32_t coin777_addrtype(uint8_t *p2shtypep,char *coinstr);
struct prices777_order
{
struct InstantDEX_shared s; cJSON *retitem; struct prices777 *source; struct pending_trade *pend;
uint64_t id; double wt,ratio; uint16_t slot_ba;
};
struct prices777_basket
{
struct prices777 *prices; double wt;
int32_t groupid,groupsize,aski,bidi;
char base[64],rel[64];
};
struct prices777_orderentry { struct prices777_order bid,ask; };
#define MAX_GROUPS 8
#define _MAX_DEPTH 100
struct prices777_basketinfo
{
int32_t numbids,numasks; uint32_t timestamp;
struct prices777_orderentry book[MAX_GROUPS+1][_MAX_DEPTH];
};
struct NXTtx { uint64_t txid; char fullhash[MAX_JSON_FIELD],utxbytes[MAX_JSON_FIELD],utxbytes2[MAX_JSON_FIELD],txbytes[MAX_JSON_FIELD],sighash[MAX_JSON_FIELD]; };
struct pending_trade
{
struct queueitem DL;
struct NXTtx trigger; struct prices777_order order;
uint64_t triggertxid,txid,quoteid,orderid,my64bits;
struct prices777 *prices; void *cHandlep; struct exchange_info *exchange; void *bot;
char *triggertx,*txbytes,extra[128]; uint8_t nxtsecret[2048]; cJSON *tradesjson,*item;
double price,volume; uint32_t timestamp,finishtime,expiration;
int32_t dir,type,version,size,dotrade,queueflag,*curlingp;
};
struct prices777
{
char url[512],exchange[64],base[64],rel[64],lbase[64],lrel[64],key[512],oppokey[512],contract[64],origbase[64],origrel[64];
uint64_t contractnum,ap_mult,baseid,relid,basemult,relmult; double lastupdate,decay,oppodecay,lastprice,lastbid,lastask;
uint32_t pollnxtblock,exchangeid,numquotes,updated,lasttimestamp,RTflag,disabled,dirty; int32_t keysize,oppokeysize;
portable_mutex_t mutex;
char *orderbook_jsonstrs[2][2];
struct prices777_basketinfo O,O2; double groupwts[MAX_GROUPS + 1];
uint8_t changed,type; uint8_t **dependents; int32_t numdependents,numgroups,basketsize; double commission;
void *tradebot;
struct prices777_basket basket[];
};
struct exchange_info;
struct exchange_funcs
{
char *exchange;
double (*update)(struct prices777 *prices,int32_t maxdepth);
int32_t (*supports)(char *base,char *rel);
uint64_t (*trade)(void **cHandlep,int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *base,char *rel,int32_t dir,double price,double volume);
char *(*orderstatus)(void **cHandlep,struct exchange_info *exchange,cJSON *argjson,uint64_t quoteid);
char *(*cancelorder)(void **cHandlep,struct exchange_info *exchange,cJSON *argjson,uint64_t quoteid);
char *(*openorders)(void **cHandlep,struct exchange_info *exchange,cJSON *argjson);
char *(*tradehistory)(void **cHandlep,struct exchange_info *exchange,cJSON *argjson);
cJSON *(*balances)(void **cHandlep,struct exchange_info *exchange);
char *(*parsebalance)(struct exchange_info *exchange,double *balancep,char *coinstr);
char *(*withdraw)(void **cHandlep,struct exchange_info *exchange,cJSON *argjson);
};
#define EXCHANGE_FUNCS(xchg,name) { name, prices777_ ## xchg, xchg ## _supports, xchg ## _trade, xchg ## _orderstatus, xchg ## _cancelorder, xchg ## _openorders, xchg ## _tradehistory, xchg ## _balances, xchg ## _parsebalance, xchg ## _withdraw }
struct exchange_info
{
struct exchange_funcs issue;
char name[16],apikey[MAX_JSON_FIELD],apisecret[MAX_JSON_FIELD],userid[MAX_JSON_FIELD];
cJSON *balancejson;
uint32_t num,exchangeid,pollgap,refcount,polling,lastbalancetime;
uint64_t nxt64bits,lastnonce; double lastupdate,commission;
void *cHandle;
portable_mutex_t mutex;
};
#define calc_predisplinex(startweekind,clumpsize,weekind) (((weekind) - (startweekind))/(clumpsize))
#define _extrapolate_Spline(Splines,gap) ((double)(Splines)[0] + ((gap) * ((double)(Splines)[1] + ((gap) * ((double)(Splines)[2] + ((gap) * (double)(Splines)[3]))))))
#define _extrapolate_Slope(Splines,gap) ((double)(Splines)[1] + ((gap) * ((double)(Splines)[2] + ((gap) * (double)(Splines)[3]))))
#define PRICE_BLEND(oldval,newval,decay,oppodecay) ((oldval == 0.) ? newval : ((oldval * decay) + (oppodecay * newval)))
#define PRICE_BLEND64(oldval,newval,decay,oppodecay) ((oldval == 0) ? newval : ((oldval * decay) + (oppodecay * newval) + 0.499))
struct prices777 *prices777_initpair(int32_t needfunc,char *exchange,char *base,char *rel,double decay,char *name,uint64_t baseid,uint64_t relid,int32_t basketsize);
struct exchange_info *get_exchange(int32_t exchangeid);
char *exchange_str(int32_t exchangeid);
struct exchange_info *exchange_find(char *exchangestr);
void prices777_exchangeloop(void *ptr);
uint64_t InstantDEX_name(char *key,int32_t *keysizep,char *exchange,char *name,char *base,uint64_t *baseidp,char *rel,uint64_t *relidp);
struct prices777 *prices777_find(int32_t *invertedp,uint64_t baseid,uint64_t relid,char *exchange);
struct exchange_info *find_exchange(int32_t *exchangeidp,char *exchangestr);
double prices777_InstantDEX(struct prices777 *prices,int32_t maxdepth);
uint64_t prices777_equiv(uint64_t assetid);
char *prices777_trade(int32_t *curlingp,void *bot,struct pending_trade **pendp,void **cHandlep,int32_t dotrade,cJSON *item,char *activenxt,char *secret,struct prices777 *prices,int32_t dir,double price,double volume,struct InstantDEX_quote *iQ,struct prices777_order *order,uint64_t orderid,char *extra);
double prices777_price_volume(double *volumep,uint64_t baseamount,uint64_t relamount);
struct prices777 *prices777_poll(char *exchangestr,char *name,char *base,uint64_t refbaseid,char *rel,uint64_t refrelid);
void set_best_amounts(int64_t *baseamountp,int64_t *relamountp,double price,double volume);
int32_t _set_assetname(uint64_t *multp,char *buf,char *jsonstr,uint64_t assetid);
char *InstantDEX_withdraw(cJSON *argjson);
cJSON *exchanges_json();
char *InstantDEX_tradesequence(int32_t curlings[],void *bot,void *cHandles[],int32_t *nump,struct prices777_order *trades,int32_t maxtrades,int32_t dotrade,char *activenxt,char *secret,cJSON *json);
struct prices777 *prices777_makebasket(char *basketstr,cJSON *_basketjson,int32_t addbasket,char *typestr,struct prices777 *ptrs[],int32_t num);
char *prices777_activebooks(char *name,char *_base,char *_rel,uint64_t baseid,uint64_t relid,int32_t maxdepth,int32_t allflag,int32_t tradeable);
char *prices777_orderbook_jsonstr(int32_t invert,uint64_t nxt64bits,struct prices777 *prices,struct prices777_basketinfo *OB,int32_t maxdepth,int32_t allflag);
int32_t get_assetname(char *name,uint64_t assetid);
int32_t is_mscoin(char *assetidstr);
uint32_t _get_NXTheight(uint32_t *firsttimep);
char *fill_nxtae(int32_t dotrade,uint64_t *txidp,uint64_t nxt64bits,char *secret,int32_t dir,double price,double volume,uint64_t baseid,uint64_t relid);
uint64_t get_assetmult(uint64_t assetid);
int32_t InstantDEX_verify(uint64_t destNXTaddr,uint64_t sendasset,uint64_t sendqty,cJSON *txobj,uint64_t recvasset,uint64_t recvqty);
int32_t verify_NXTtx(cJSON *json,uint64_t refasset,uint64_t qty,uint64_t destNXTbits);
uint64_t assetmult(char *assetidstr);
int64_t get_asset_quantity(int64_t *unconfirmedp,char *NXTaddr,char *assetidstr);
uint64_t calc_asset_qty(uint64_t *availp,uint64_t *priceNQTp,char *NXTaddr,int32_t checkflag,uint64_t assetid,double price,double vol);
cJSON *InstantDEX_orderbook(struct prices777 *prices);
char *hmac_sha512_str(char dest[(512>>3)*2 + 1],char *key,unsigned int key_size,char *message);
char *hmac_sha384_str(char *dest,char *key,int32_t key_size,char *message);
char *hmac_sha1_str(char *dest,char *key,int32_t key_size,char *message);
char *hmac_sha256_str(char *dest,char *key,int32_t key_size,char *message);
extern uint32_t MAX_DEPTH;
extern char NXTAPIURL[],IGUANA_NXTACCTSECRET[],IGUANA_NXTADDR[];
extern int32_t FIRST_EXTERNAL,IGUANA_disableNXT,Debuglevel,prices777_NXTBLOCK;
extern uint64_t IGUANA_MY64BITS;
#endif

1407
iguana/InstantDEX/exchange_trades.h

File diff suppressed because it is too large

1207
iguana/InstantDEX/exchangeparse.h

File diff suppressed because it is too large

1812
iguana/InstantDEX/prices777.c

File diff suppressed because it is too large

880
iguana/InstantDEX/quotes.h

@ -0,0 +1,880 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#ifndef xcode_quotes_h
#define xcode_quotes_h
#ifdef oldway
int32_t make_jumpiQ(uint64_t refbaseid,uint64_t refrelid,int32_t flip,struct InstantDEX_quote *iQ,struct InstantDEX_quote *baseiQ,struct InstantDEX_quote *reliQ,char *gui,int32_t duration)
{
uint64_t baseamount,relamount,frombase,fromrel,tobase,torel;
double vol;
char exchange[64];
uint32_t timestamp;
frombase = baseiQ->baseamount, fromrel = baseiQ->relamount;
tobase = reliQ->baseamount, torel = reliQ->relamount;
if ( make_jumpquote(refbaseid,refrelid,&baseamount,&relamount,&frombase,&fromrel,&tobase,&torel) == 0. )
return(0);
if ( (timestamp= reliQ->timestamp) > baseiQ->timestamp )
timestamp = baseiQ->timestamp;
iQ_exchangestr(exchange,iQ);
create_InstantDEX_quote(iQ,timestamp,0,calc_quoteid(baseiQ) ^ calc_quoteid(reliQ),0.,0.,refbaseid,baseamount,refrelid,relamount,exchange,0,gui,baseiQ,reliQ,duration);
if ( Debuglevel > 2 )
printf("jump%s: %f (%llu/%llu) %llu %llu (%f %f) %llu %llu\n",flip==0?"BID":"ASK",calc_price_volume(&vol,iQ->baseamount,iQ->relamount),(long long)baseamount,(long long)relamount,(long long)frombase,(long long)fromrel,calc_price_volume(&vol,frombase,fromrel),calc_price_volume(&vol,tobase,torel),(long long)tobase,(long long)torel);
iQ->isask = flip;
iQ->minperc = baseiQ->minperc;
if ( reliQ->minperc > iQ->minperc )
iQ->minperc = reliQ->minperc;
return(1);
}
#else
struct InstantDEX_quote *AllQuotes;
void clear_InstantDEX_quoteflags(struct InstantDEX_quote *iQ)
{
//duration:14,wallet:1,a:1,isask:1,expired:1,closed:1,swap:1,responded:1,matched:1,feepaid:1,automatch:1,pending:1,minperc:7;
iQ->s.a = iQ->s.expired = iQ->s.swap = iQ->s.feepaid = 0;
iQ->s.closed = iQ->s.pending = iQ->s.responded = iQ->s.matched = 0;
}
void cancel_InstantDEX_quote(struct InstantDEX_quote *iQ) { iQ->s.closed = 1; }
int32_t InstantDEX_uncalcsize() { struct InstantDEX_quote iQ; return(sizeof(iQ.hh) + sizeof(iQ.s.quoteid) + sizeof(iQ.s.price) + sizeof(iQ.s.vol)); }
int32_t iQcmp(struct InstantDEX_quote *iQA,struct InstantDEX_quote *iQB)
{
if ( iQA->s.isask == iQB->s.isask && iQA->s.baseid == iQB->s.baseid && iQA->s.relid == iQB->s.relid && iQA->s.baseamount == iQB->s.baseamount && iQA->s.relamount == iQB->s.relamount )
return(0);
else if ( iQA->s.isask != iQB->s.isask && iQA->s.baseid == iQB->s.relid && iQA->s.relid == iQB->s.baseid && iQA->s.baseamount == iQB->s.relamount && iQA->s.relamount == iQB->s.baseamount )
return(0);
return(-1);
}
uint64_t calc_txid(unsigned char *buf,int32_t len)
{
bits256 hash;
vcalc_sha256(0,hash.bytes,buf,len);
return(hash.txid);
}
uint64_t calc_quoteid(struct InstantDEX_quote *iQ)
{
struct InstantDEX_quote Q;
if ( iQ == 0 )
return(0);
if ( iQ->s.duration == 0 || iQ->s.duration > ORDERBOOK_EXPIRATION )
iQ->s.duration = ORDERBOOK_EXPIRATION;
if ( iQ->s.quoteid == 0 )
{
Q = *iQ;
clear_InstantDEX_quoteflags(&Q);
if ( Q.s.isask != 0 )
{
Q.s.baseid = iQ->s.relid, Q.s.baseamount = iQ->s.relamount;
Q.s.relid = iQ->s.baseid, Q.s.relamount = iQ->s.baseamount;
Q.s.isask = Q.s.minperc = 0;
}
return(calc_txid((uint8_t *)((long)&Q + InstantDEX_uncalcsize()),sizeof(Q) - InstantDEX_uncalcsize()));
} return(iQ->s.quoteid);
}
struct InstantDEX_quote *find_iQ(uint64_t quoteid)
{
struct InstantDEX_quote *iQ;
HASH_FIND(hh,AllQuotes,&quoteid,sizeof(quoteid),iQ);
return(iQ);
}
struct InstantDEX_quote *delete_iQ(uint64_t quoteid)
{
struct InstantDEX_quote *iQ;
if ( (iQ= find_iQ(quoteid)) != 0 )
{
HASH_DELETE(hh,AllQuotes,iQ);
}
return(iQ);
}
struct InstantDEX_quote *findquoteid(uint64_t quoteid,int32_t evenclosed)
{
struct InstantDEX_quote *iQ;
if ( (iQ= find_iQ(quoteid)) != 0 )
{
if ( evenclosed != 0 || iQ->s.closed == 0 )
{
if ( calc_quoteid(iQ) == quoteid )
return(iQ);
else printf("calc_quoteid %llu vs %llu\n",(long long)calc_quoteid(iQ),(long long)quoteid);
} //else printf("quoteid.%llu closed.%d\n",(long long)quoteid,iQ->closed);
} else printf("couldnt find %llu\n",(long long)quoteid);
return(0);
}
int32_t cancelquote(char *NXTaddr,uint64_t quoteid)
{
struct InstantDEX_quote *iQ;
if ( (iQ= findquoteid(quoteid,0)) != 0 && iQ->s.offerNXT == calc_nxt64bits(NXTaddr) && iQ->exchangeid == INSTANTDEX_EXCHANGEID )
{
cancel_InstantDEX_quote(iQ);
return(1);
}
return(0);
}
struct InstantDEX_quote *create_iQ(struct InstantDEX_quote *iQ,char *walletstr)
{
struct InstantDEX_quote *newiQ,*tmp; struct prices777 *prices; int32_t inverted; long len = 0;
if ( walletstr != 0 && (len= strlen(walletstr)) > 0 )
iQ->s.wallet = 1, len++;
calc_quoteid(iQ);
printf("createiQ %llu/%llu %f %f quoteid.%llu offerNXT.%llu wallet.%d (%s)\n",(long long)iQ->s.baseid,(long long)iQ->s.relid,iQ->s.price,iQ->s.vol,(long long)iQ->s.quoteid,(long long)iQ->s.offerNXT,iQ->s.wallet,walletstr!=0?walletstr:"");
if ( (newiQ= find_iQ(iQ->s.quoteid)) != 0 )
return(newiQ);
newiQ = calloc(1,sizeof(*newiQ) + len);
*newiQ = *iQ;
if ( len != 0 )
memcpy(newiQ->walletstr,walletstr,len);
HASH_ADD(hh,AllQuotes,s.quoteid,sizeof(newiQ->s.quoteid),newiQ);
if ( (prices= prices777_find(&inverted,iQ->s.baseid,iQ->s.relid,INSTANTDEX_NAME)) != 0 )
prices->dirty++;
{
struct InstantDEX_quote *checkiQ;
if ( (checkiQ= find_iQ(iQ->s.quoteid)) == 0 || iQcmp(iQ,checkiQ) != 0 )//memcmp((uint8_t *)((long)checkiQ + sizeof(checkiQ->hh) + sizeof(checkiQ->quoteid)),(uint8_t *)((long)iQ + sizeof(iQ->hh) + sizeof(iQ->quoteid)),sizeof(*iQ) - sizeof(iQ->hh) - sizeof(iQ->quoteid)) != 0 )
{
int32_t i;
for (i=(sizeof(iQ->hh) - sizeof(iQ->s.quoteid)); i<sizeof(*iQ) - sizeof(iQ->hh) - sizeof(iQ->s.quoteid); i++)
printf("%02x ",((uint8_t *)iQ)[i]);
printf("iQ\n");
for (i=(sizeof(checkiQ->hh) + sizeof(checkiQ->s.quoteid)); i<sizeof(*checkiQ) - sizeof(checkiQ->hh) - sizeof(checkiQ->s.quoteid); i++)
printf("%02x ",((uint8_t *)checkiQ)[i]);
printf("checkiQ\n");
printf("error finding iQ after adding %llu vs %llu\n",(long long)checkiQ->s.quoteid,(long long)iQ->s.quoteid);
}
}
HASH_ITER(hh,AllQuotes,iQ,tmp)
{
if ( iQ->s.expired != 0 )
{
printf("quoteid.%llu expired, purging\n",(long long)iQ->s.expired);
delete_iQ(iQ->s.quoteid);
}
}
return(newiQ);
}
#ifdef later
cJSON *pangea_walletitem(cJSON *walletitem,struct coin777 *coin,int32_t rakemillis,int64_t bigblind,int64_t ante,int32_t minbuyin,int32_t maxbuyin)
{
char *addr; struct destbuf pubkey;
if ( walletitem == 0 )
walletitem = cJSON_CreateObject();
//printf("call get_acct_coinaddr.%s (%s) (%s)\n",coin->name,coin->serverport,coin->userpass);
if ( coin->pangeapubkey[0] == 0 || coin->pangeacoinaddr[0] == 0 )
{
if ( strcmp("NXT",coin->name) == 0 )
{
}
else if ( (addr= get_acct_coinaddr(coin->pangeacoinaddr,coin->name,coin->serverport,coin->userpass,"pangea")) != 0 )
{
//printf("get_pubkey\n");
get_pubkey(&pubkey,coin->name,coin->serverport,coin->userpass,coin->pangeacoinaddr);
strcpy(coin->pangeapubkey,pubkey.buf);
}
}
jaddstr(walletitem,"pubkey",coin->pangeapubkey);
jaddstr(walletitem,"coinaddr",coin->pangeacoinaddr);
jaddnum(walletitem,"rakemillis",rakemillis);
jaddnum(walletitem,"minbuyin",minbuyin);
jaddnum(walletitem,"maxbuyin",maxbuyin);
jadd64bits(walletitem,"bigblind",bigblind);
jadd64bits(walletitem,"ante",ante);
return(walletitem);
}
cJSON *set_walletstr(cJSON *walletitem,char *walletstr,struct InstantDEX_quote *iQ)
{
char pubkeystr[128],pkhash[128],base[64],rel[64],fieldA[64],fieldB[64],fieldpkhash[64],*pubA,*pubB,*pkhashstr,*str,*exchangestr;
struct coin777 *coin; int32_t flip = 0;
if ( walletstr != 0 && walletitem == 0 )
walletitem = cJSON_Parse(walletstr);
if ( walletitem == 0 )
walletitem = cJSON_CreateObject();
unstringbits(base,iQ->s.basebits), unstringbits(rel,iQ->s.relbits);
flip = (iQ->s.offerNXT != IGUANA_MY64BITS);
if ( strcmp(base,"NXT") != 0 )
coin = coin777_find(base,1);
else if ( strcmp(rel,"NXT") != 0 )
coin = coin777_find(rel,1), flip ^= 1;
else coin = 0;
if ( coin != 0 )
{
if ( (exchangestr= exchange_str(iQ->exchangeid)) != 0 && strcmp(exchangestr,"pangea") == 0 )
pangea_walletitem(walletitem,coin,iQ->s.minperc,iQ->s.baseamount,iQ->s.relamount,iQ->s.minbuyin,iQ->s.maxbuyin);
else
{
//printf("START.(%s)\n",jprint(walletitem,0));
if ( (iQ->s.isask ^ flip) == 0 )
{
sprintf(fieldA,"%spubA",coin->name);
if ( (pubA= jstr(walletitem,fieldA)) != 0 )
cJSON_DeleteItemFromObject(walletitem,fieldA);
jaddstr(walletitem,fieldA,coin->atomicsendpubkey);
//printf("replaceA\n");
}
else
{
sprintf(fieldB,"%spubB",coin->name);
if ( (pubB= jstr(walletitem,fieldB)) != 0 )
cJSON_DeleteItemFromObject(walletitem,fieldB);
jaddstr(walletitem,fieldB,coin->atomicrecvpubkey);
sprintf(fieldpkhash,"%spkhash",coin->name);
if ( (pkhashstr= jstr(walletitem,fieldpkhash)) != 0 )
cJSON_DeleteItemFromObject(walletitem,fieldpkhash);
subatomic_pubkeyhash(pubkeystr,pkhash,coin,iQ->s.quoteid);
jaddstr(walletitem,fieldpkhash,pkhash);
//printf("replaceB\n");
}
}
str = jprint(walletitem,0);
strcpy(walletstr,str);
free(str);
return(walletitem);
}
return(0);
}
#endif
char *InstantDEX_str(char *walletstr,char *buf,int32_t extraflag,struct InstantDEX_quote *iQ)
{
cJSON *json; char _buf[4096],base[64],rel[64],*str;
unstringbits(base,iQ->s.basebits), unstringbits(rel,iQ->s.relbits);
if ( buf == 0 )
buf = _buf;
sprintf(buf,"{\"quoteid\":\"%llu\",\"base\":\"%s\",\"baseid\":\"%llu\",\"baseamount\":\"%llu\",\"rel\":\"%s\",\"relid\":\"%llu\",\"relamount\":\"%llu\",\"price\":%.8f,\"volume\":%.8f,\"offerNXT\":\"%llu\",\"timestamp\":\"%u\",\"isask\":\"%u\",\"exchange\":\"%s\",\"gui\":\"%s\"}",(long long)iQ->s.quoteid,base,(long long)iQ->s.baseid,(long long)iQ->s.baseamount,rel,(long long)iQ->s.relid,(long long)iQ->s.relamount,iQ->s.price,iQ->s.vol,(long long)iQ->s.offerNXT,iQ->s.timestamp,iQ->s.isask,exchange_str(iQ->exchangeid),iQ->gui);
if ( extraflag != 0 )
{
sprintf(buf + strlen(buf) - 1,",\"plugin\":\"relay\",\"destplugin\":\"InstantDEX\",\"method\":\"busdata\",\"submethod\":\"%s\"}",(iQ->s.isask != 0) ? "ask" : "bid");
}
//printf("InstantDEX_str.(%s)\n",buf);
if ( (json= cJSON_Parse(buf)) != 0 )
{
#ifdef later
char _buf[4096],_walletstr[256],base[64],rel[64],*exchange,*str; cJSON *walletitem,*json; struct coin777 *coin;
if ( walletstr == 0 )
{
walletstr = _walletstr;
walletstr[0] = 0;
}
if ( (exchange= exchange_str(iQ->exchangeid)) != 0 )
{
coin = coin777_find(base,0);
if ( strcmp(exchange,"wallet") == 0 )
walletitem = set_walletstr(0,walletstr,iQ);
else if ( strcmp(exchange,"pangea") == 0 && walletstr[0] == 0 && coin != 0 )
walletitem = pangea_walletitem(0,coin,iQ->s.minperc,iQ->s.baseamount,iQ->s.relamount,iQ->s.minbuyin,iQ->s.maxbuyin);
else walletitem = 0;
if ( walletitem != 0 )
{
jadd(json,"wallet",walletitem);
strcpy(walletstr,jprint(walletitem,0));
}
//printf("exchange.(%s) iswallet.%d (%s) base.(%s) coin.%p (%s)\n",exchange,iQ->s.wallet,walletstr,base,coin,jprint(json,0));
} else printf("InstantDEX_str cant find exchangeid.%d\n",iQ->exchangeid);
#endif
str = jprint(json,1);
strcpy(buf,str);
//printf("str.(%s) %p\n",buf,buf);
free(str);
} else printf("InstantDEX_str cant parse.(%s)\n",buf);
if ( buf == _buf )
return(clonestr(buf));
else return(buf);
}
uint64_t _get_AEquote(char *str,uint64_t orderid)
{
cJSON *json;
uint64_t nxt64bits = 0;
char cmd[256],*jsonstr;
sprintf(cmd,"requestType=get%sOrder&order=%llu",str,(long long)orderid);
if ( (jsonstr= issue_NXTPOST(cmd)) != 0 )
{
//printf("(%s) -> (%s)\n",cmd,jsonstr);
if ( (json= cJSON_Parse(jsonstr)) != 0 )
{
nxt64bits = get_API_nxt64bits(cJSON_GetObjectItem(json,"account"));
free_json(json);
}
free(jsonstr);
}
return(nxt64bits);
}
char *cancel_NXTorderid(char *NXTaddr,char *nxtsecret,uint64_t orderid)
{
uint64_t nxt64bits; char cmd[1025],secret[8192],*str = "Bid",*retstr = 0;
if ( (nxt64bits= _get_AEquote(str,orderid)) == 0 )
str = "Ask", nxt64bits = _get_AEquote(str,orderid);
if ( nxt64bits == calc_nxt64bits(NXTaddr) )
{
escape_code(secret,nxtsecret);
sprintf(cmd,"requestType=cancel%sOrder&secretPhrase=%s&feeNQT=%lld&deadline=%d&order=%llu",str,secret,(long long)MIN_NQTFEE,DEFAULT_NXT_DEADLINE,(long long)orderid);
retstr = issue_NXTPOST(cmd);
//printf("(%s) -> (%s)\n",cmd,retstr);
}
return(retstr);
}
char *InstantDEX_cancelorder(cJSON *argjson,char *activenxt,char *secret,uint64_t orderid,uint64_t quoteid)
{
struct InstantDEX_quote *iQ; cJSON *json,*array,*item; char numstr[64],*retstr,*exchangestr;
uint64_t quoteids[256]; int32_t i,exchangeid,n=0; struct exchange_info *exchange;
if ( (exchangestr= jstr(argjson,"exchange")) != 0 && (exchange= find_exchange(&exchangeid,exchangestr)) != 0 )
{
if ( exchange->issue.cancelorder != 0 )
{
if ( (retstr= (*exchange->issue.cancelorder)(&exchange->cHandle,exchange,argjson,quoteid)) == 0 )
retstr = clonestr("{\"result\":\"nothing returned from exchange\"}");
return(retstr);
}
else return(clonestr("{\"error\":\"no cancelorder function\"}"));
}
memset(quoteids,0,sizeof(quoteids));
json = cJSON_CreateObject(), array = cJSON_CreateArray();
if ( quoteid != 0 )
quoteids[n++] = quoteid;
//n += InstantDEX_quoteids(quoteids+n,orderid);
for (i=0; i<n; i++)
{
quoteid = quoteids[i];
if ( (retstr= cancel_NXTorderid(activenxt,secret,quoteid)) != 0 )
{
if ( (iQ= findquoteid(quoteid,0)) != 0 && iQ->s.offerNXT == calc_nxt64bits(activenxt) )
cancel_InstantDEX_quote(iQ);
if ( (item= cJSON_Parse(retstr)) != 0 )
jaddi(array,item);
free(retstr);
}
cancelquote(activenxt,quoteid);
}
if ( orderid != 0 )
{
if ( cancelquote(activenxt,orderid) != 0 )
sprintf(numstr,"%llu",(long long)orderid), jaddstr(json,"ordercanceled",numstr);
}
return(jprint(json,1));
}
char *InstantDEX_orderstatus(cJSON *argjson,uint64_t orderid,uint64_t quoteid)
{
struct InstantDEX_quote *iQ = 0; char *exchangestr,*str; struct exchange_info *exchange; int32_t exchangeid;
if ( (exchangestr= jstr(argjson,"exchange")) != 0 && (exchange= find_exchange(&exchangeid,exchangestr)) != 0 )
{
if ( exchange->issue.orderstatus != 0 )
{
if ( (str= (*exchange->issue.orderstatus)(&exchange->cHandle,exchange,argjson,quoteid)) == 0 )
str = clonestr("{\"result\":\"nothing returned from exchange\"}");
return(str);
}
else return(clonestr("{\"error\":\"no orderstatus function\"}"));
}
if ( (iQ= find_iQ(orderid)) != 0 || (iQ= find_iQ(quoteid)) != 0 )
return(InstantDEX_str(0,0,0,iQ));
return(clonestr("{\"error\":\"couldnt find orderid\"}"));
}
char *InstantDEX_openorders(cJSON *argjson,char *NXTaddr,int32_t allorders)
{
struct InstantDEX_quote *iQ,*tmp; char buf[4096],*exchangestr,*jsonstr,*str; uint32_t now,duration;
cJSON *json,*array,*item; uint64_t nxt64bits; struct exchange_info *exchange; int32_t exchangeid;
if ( (exchangestr= jstr(argjson,"exchange")) != 0 && (exchange= find_exchange(&exchangeid,exchangestr)) != 0 )
{
if ( exchange->issue.openorders != 0 )
{
if ( (str= (*exchange->issue.openorders)(&exchange->cHandle,exchange,argjson)) == 0 )
str = clonestr("{\"result\":\"nothing returned from exchange\"}");
return(str);
}
else return(clonestr("{\"error\":\"no orderstatus function\"}"));
}
nxt64bits = calc_nxt64bits(NXTaddr);
now = (uint32_t)time(NULL);
json = cJSON_CreateObject(), array = cJSON_CreateArray();
HASH_ITER(hh,AllQuotes,iQ,tmp)
{
if ( (duration= iQ->s.duration) == 0 )
duration = ORDERBOOK_EXPIRATION;
if ( iQ->s.timestamp > (now + duration) )
iQ->s.expired = iQ->s.closed = 1;
if ( iQ->s.offerNXT == nxt64bits && (allorders != 0 || iQ->s.closed == 0) )
{
if ( (jsonstr= InstantDEX_str(0,buf,0,iQ)) != 0 && (item= cJSON_Parse(jsonstr)) != 0 )
jaddi(array,item);
}
}
jadd(json,"openorders",array);
return(jprint(json,1));
}
cJSON *InstantDEX_specialorders(uint64_t *quoteidp,uint64_t nxt64bits,char *base,char *special,uint64_t baseamount,int32_t addrtype)
{
struct InstantDEX_quote *iQ,*tmp; int32_t exchangeid; uint32_t i,n,now,duration,ismine = 0;
uint64_t basebits; cJSON *item=0,*array = 0; char *coinaddr=0,*pubkey,checkaddr[128];
now = (uint32_t)time(NULL);
basebits = stringbits(base);
if ( special == 0 || find_exchange(&exchangeid,special) == 0 )
exchangeid = 0;
n = 0;
*quoteidp = 0;
HASH_ITER(hh,AllQuotes,iQ,tmp)
{
//printf("iter Q.%llu b.%llu\n",(long long)iQ->s.quoteid,(long long)iQ->s.basebits);
if ( (duration= iQ->s.duration) == 0 )
duration = ORDERBOOK_EXPIRATION;
if ( iQ->s.timestamp > (now + duration) )
{
iQ->s.expired = iQ->s.closed = 1;
printf("expire order %llu\n",(long long)iQ->s.quoteid);
continue;
}
if ( iQ->s.basebits == basebits && (exchangeid == 0 || iQ->exchangeid == exchangeid) )
{
//printf("matched basebits\n");
if ( strcmp(special,"pangea") == 0 )
{
checkaddr[0] = 0;
if ( iQ->s.wallet != 0 && (item= cJSON_Parse(iQ->walletstr)) != 0 && (coinaddr= jstr(item,"coinaddr")) != 0 && coinaddr[0] != 0 && (pubkey= jstr(item,"pubkey")) != 0 && pubkey[0] != 0 )
btc_coinaddr(coinaddr,addrtype,pubkey);
if ( item != 0 )
free_json(item);
if ( coinaddr == 0 || strcmp(coinaddr,checkaddr) != 0 )
{
printf("mismatched pangea coinaddr (%s) vs (%s) or baseamount %.8f vs %.8f\n",coinaddr,checkaddr,dstr(baseamount),dstr(iQ->s.baseamount));
continue;
}
}
if ( n > 0 )
{
for (i=0; i<n; i++)
{
if ( iQ->s.offerNXT == j64bits(jitem(array,i),0) )
break;
}
//printf("found duplicate\n");
} else i = 0;
if ( i == n )
{
if ( iQ->s.offerNXT == nxt64bits )
{
ismine = 1;
if ( *quoteidp == 0 )
*quoteidp = iQ->s.quoteid;
}
if ( array == 0 )
array = cJSON_CreateArray();
jaddi64bits(array,iQ->s.offerNXT);
//printf("add %llu\n",(long long)iQ->s.offerNXT);
}
} //else printf("quote.%llu basebits.%llu\n",(long long)iQ->s.quoteid,(long long)iQ->s.basebits);
}
if ( ismine == 0 )
free_json(array), array = 0;
//printf("ismine.%d n.%d array.%d\n",ismine,n,array==0?0:cJSON_GetArraySize(array));
return(array);
}
int _decreasing_quotes(const void *a,const void *b)
{
#define order_a ((struct InstantDEX_quote *)a)
#define order_b ((struct InstantDEX_quote *)b)
if ( order_b->s.price > order_a->s.price )
return(1);
else if ( order_b->s.price < order_a->s.price )
return(-1);
return(0);
#undef order_a
#undef order_b
}
int _increasing_quotes(const void *a,const void *b)
{
#define order_a ((struct InstantDEX_quote *)a)
#define order_b ((struct InstantDEX_quote *)b)
if ( order_b->s.price > order_a->s.price )
return(-1);
else if ( order_b->s.price < order_a->s.price )
return(1);
return(0);
#undef order_a
#undef order_b
}
cJSON *prices777_orderjson(struct InstantDEX_quote *iQ)
{
cJSON *item = cJSON_CreateArray();
jaddinum(item,iQ->s.price);
jaddinum(item,iQ->s.vol);
jaddi64bits(item,iQ->s.quoteid);
return(item);
}
cJSON *InstantDEX_orderbook(struct prices777 *prices)
{
struct InstantDEX_quote *ptr,iQ,*tmp,*askvals=0,*bidvals=0; cJSON *json,*bids,*asks; uint32_t now,duration;
int32_t i,isask,iter,n,m,numbids,numasks,invert;
json = cJSON_CreateObject(), bids = cJSON_CreateArray(), asks = cJSON_CreateArray();
now = (uint32_t)time(NULL);
for (iter=numbids=numasks=n=m=0; iter<2; iter++)
{
HASH_ITER(hh,AllQuotes,ptr,tmp)
{
iQ = *ptr;
if ( (duration= iQ.s.duration) == 0 )
duration = ORDERBOOK_EXPIRATION;
if ( iQ.s.timestamp > (now + duration) )
{
iQ.s.expired = iQ.s.closed = 1;
continue;
}
if ( Debuglevel > 2 )
printf("iterate quote.%llu\n",(long long)iQ.s.quoteid);
if ( prices777_equiv(ptr->s.baseid) == prices777_equiv(prices->baseid) && prices777_equiv(ptr->s.relid) == prices777_equiv(prices->relid) )
invert = 0;
else if ( prices777_equiv(ptr->s.relid) == prices777_equiv(prices->baseid) && prices777_equiv(ptr->s.baseid) == prices777_equiv(prices->relid) )
invert = 1;
else continue;
if ( ptr->s.pending != 0 )
continue;
isask = iQ.s.isask;
if ( invert != 0 )
isask ^= 1;
if ( invert != 0 )
{
if ( iQ.s.price > SMALLVAL )
iQ.s.vol *= iQ.s.price, iQ.s.price = 1. / iQ.s.price;
else iQ.s.price = prices777_price_volume(&iQ.s.vol,iQ.s.relamount,iQ.s.baseamount);
}
else if ( iQ.s.price <= SMALLVAL )
iQ.s.price = prices777_price_volume(&iQ.s.vol,iQ.s.baseamount,iQ.s.relamount);
if ( iter == 0 )
{
if ( isask != 0 )
numasks++;
else numbids++;
}
else
{
if ( isask == 0 && n < numbids )
bidvals[n++] = iQ;
else if ( isask != 0 && m < numasks )
askvals[m++] = iQ;
}
}
if ( iter == 0 )
{
if ( numbids > 0 )
bidvals = calloc(numbids,sizeof(*bidvals));
if ( numasks > 0 )
askvals = calloc(numasks,sizeof(*askvals));
}
}
if ( numbids > 0 )
{
if ( n > 0 )
{
qsort(bidvals,n,sizeof(*bidvals),_decreasing_quotes);
for (i=0; i<n; i++)
jaddi(bids,prices777_orderjson(&bidvals[i]));
}
free(bidvals);
}
if ( numasks > 0 )
{
if ( m > 0 )
{
qsort(askvals,m,sizeof(*askvals),_increasing_quotes);
for (i=0; i<m; i++)
jaddi(asks,prices777_orderjson(&askvals[i]));
}
free(askvals);
}
jadd(json,"bids",bids), jadd(json,"asks",asks);
return(json);
}
double ordermetric(double price,double vol,int32_t dir,double refprice,double refvol)
{
double metric = 0.;
if ( vol > (refvol * INSTANTDEX_MINVOLPERC) )//&& refvol > (vol * iQ->s.minperc * .01) )
{
if ( vol < refvol )
metric = (vol / refvol);
else metric = 1.;
if ( dir > 0 && price < (refprice * (1. + INSTANTDEX_PRICESLIPPAGE) + SMALLVAL) )
metric *= (1. + (refprice - price)/refprice);
else if ( dir < 0 && price > (refprice * (1. - INSTANTDEX_PRICESLIPPAGE) - SMALLVAL) )
metric *= (1. + (price - refprice)/refprice);
else metric = 0.;
if ( metric != 0. )
{
printf("price %.8f vol %.8f | %.8f > %.8f? %.8f > %.8f?\n",price,vol,vol,(refvol * INSTANTDEX_MINVOLPERC),refvol,(vol * INSTANTDEX_MINVOLPERC));
printf("price %f against %f or %f\n",price,(refprice * (1. + INSTANTDEX_PRICESLIPPAGE) + SMALLVAL),(refprice * (1. - INSTANTDEX_PRICESLIPPAGE) - SMALLVAL));
printf("metric %f\n",metric);
}
}
return(metric);
}
char *autofill(char *remoteaddr,struct InstantDEX_quote *refiQ,char *NXTaddr,char *NXTACCTSECRET)
{
double price,volume,revprice,revvol,metric,bestmetric = 0.; int32_t dir,inverted; uint64_t nxt64bits; char *retstr=0;
struct InstantDEX_quote *iQ,*tmp,*bestiQ; struct prices777 *prices; uint32_t duration,now = (uint32_t)time(NULL);
return(0);
nxt64bits = calc_nxt64bits(NXTaddr);
memset(&bestiQ,0,sizeof(bestiQ));
dir = (refiQ->s.isask != 0) ? -1 : 1;
HASH_ITER(hh,AllQuotes,iQ,tmp)
{
if ( (duration= refiQ->s.duration) == 0 )
duration = ORDERBOOK_EXPIRATION;
if ( iQ->s.timestamp > (now + duration) )
iQ->s.expired = iQ->s.closed = 1;
if ( iQ->s.offerNXT == nxt64bits && iQ->s.closed == 0 && iQ->s.pending == 0 )
{
if ( iQ->s.baseid == refiQ->s.baseid && iQ->s.relid == refiQ->s.relid && iQ->s.isask != refiQ->s.isask && (metric= ordermetric(iQ->s.price,iQ->s.vol,dir,refiQ->s.price,refiQ->s.vol)) > bestmetric )
{
bestmetric = metric;
bestiQ = iQ;
}
else if ( iQ->s.baseid == refiQ->s.relid && iQ->s.relid == refiQ->s.baseid && iQ->s.isask == refiQ->s.isask && iQ->s.price > SMALLVAL )
{
revvol = (iQ->s.price * iQ->s.vol), revprice = (1. / iQ->s.price);
if ( (metric= ordermetric(revprice,revvol,dir,refiQ->s.price,refiQ->s.vol)) > bestmetric )
{
bestmetric = metric;
bestiQ = iQ;
}
}
}
}
if ( bestmetric > 0. )
{
if ( (prices= prices777_find(&inverted,bestiQ->s.baseid,bestiQ->s.relid,exchange_str(bestiQ->exchangeid))) != 0 )
{
printf("isask.%d %f %f -> bestmetric %f inverted.%d autofill dir.%d price %f vol %f\n",bestiQ->s.isask,bestiQ->s.price,bestiQ->s.vol,bestmetric,inverted,dir,refiQ->s.price,refiQ->s.vol);
if ( bestiQ->s.isask != 0 )
dir = -1;
else dir = 1;
if ( inverted != 0 )
{
dir *= -1;
volume = (bestiQ->s.price * bestiQ->s.vol);
price = 1. / bestiQ->s.price;
printf("price inverted (%f %f) -> (%f %f)\n",bestiQ->s.price,bestiQ->s.vol,price,volume);
} else price = bestiQ->s.price, volume = bestiQ->s.vol;
retstr = prices777_trade(0,0,0,0,1,0,NXTaddr,NXTACCTSECRET,prices,dir,price,volume,bestiQ,0,bestiQ->s.quoteid,0);
}
}
return(retstr);
}
char *automatch(struct prices777 *prices,int32_t dir,double refprice,double refvol,char *NXTaddr,char *NXTACCTSECRET)
{
int32_t i,n=0; struct prices777_order order,bestorder; char *retstr = 0; double metric,bestmetric = 0.;
return(0);
memset(&bestorder,0,sizeof(bestorder));
if ( dir > 0 )
n = prices->O.numasks;
else if ( dir < 0 )
n = prices->O.numbids;
if ( n > 0 )
{
for (i=0; i<n; i++)
{
order = (dir > 0) ? prices->O.book[MAX_GROUPS][i].ask : prices->O.book[MAX_GROUPS][i].bid;
if ( (metric= ordermetric(order.s.price,order.s.vol,dir,refprice,refvol)) > bestmetric )
{
bestmetric = metric;
bestorder = order;
}
}
}
//printf("n.%d\n",n);
if ( bestorder.source != 0 )
retstr = prices777_trade(0,0,0,0,1,0,NXTaddr,NXTACCTSECRET,bestorder.source,bestorder.s.isask!=0?-1:1,bestorder.s.price,bestorder.s.vol,0,&bestorder,bestorder.s.quoteid,0);
return(retstr);
}
int offer_checkitem(struct pending_trade *pend,cJSON *item)
{
uint64_t quoteid; struct InstantDEX_quote *iQ;
if ( (quoteid= j64bits(item,"quoteid")) != 0 && (iQ= find_iQ(quoteid)) != 0 && iQ->s.closed != 0 )
return(0);
return(-1);
}
void trades_update()
{
#ifdef later
int32_t iter; struct pending_trade *pend;
for (iter=0; iter<2; iter++)
{
while ( (pend= queue_dequeue(&Pending_offersQ.pingpong[iter],0)) != 0 )
{
if ( time(NULL) > pend->expiration )
{
printf("now.%ld vs timestamp.%u vs expiration %u | ",(long)time(NULL),pend->timestamp,pend->expiration);
printf("offer_statemachine %llu/%llu %d %f %f\n",(long long)pend->orderid,(long long)pend->quoteid,pend->dir,pend->price,pend->volume);
//InstantDEX_history(1,pend,retstr);
if ( pend->bot == 0 )
free_pending(pend);
else pend->finishtime = (uint32_t)time(NULL);
}
else
{
printf("InstantDEX_update requeue %llu/%llu %d %f %f\n",(long long)pend->orderid,(long long)pend->quoteid,pend->dir,pend->price,pend->volume);
queue_enqueue("requeue",&Pending_offersQ.pingpong[iter ^ 1],&pend->DL,0);
}
}
}
#endif
}
void InstantDEX_update(char *NXTaddr,char *NXTACCTSECRET)
{
int32_t dir; double price,volume; uint32_t now; char *retstr = 0;
int32_t inverted; struct InstantDEX_quote *iQ,*tmp; struct prices777 *prices; uint64_t nxt64bits = calc_nxt64bits(NXTaddr);
now = (uint32_t)time(NULL);
HASH_ITER(hh,AllQuotes,iQ,tmp)
{
if ( iQ->s.timestamp > (now + ORDERBOOK_EXPIRATION) )
iQ->s.expired = iQ->s.closed = 1;
if ( iQ->s.offerNXT == nxt64bits && iQ->s.closed == 0 && iQ->s.pending == 0 )
{
if ( (prices= prices777_find(&inverted,iQ->s.baseid,iQ->s.relid,exchange_str(iQ->exchangeid))) != 0 )
{
if ( iQ->s.isask != 0 )
dir = -1;
else dir = 1;
if ( inverted != 0 )
{
dir *= -1;
volume = (iQ->s.price * iQ->s.vol);
price = 1. / iQ->s.price;
printf("price inverted (%f %f) -> (%f %f)\n",iQ->s.price,iQ->s.vol,price,volume);
} else price = iQ->s.price, volume = iQ->s.vol;
if ( (retstr= automatch(prices,dir,price,volume,NXTaddr,NXTACCTSECRET)) != 0 )
{
printf("automatched %s isask.%d %f %f (%s)\n",prices->contract,iQ->s.isask,iQ->s.price,iQ->s.vol,retstr);
free(retstr);
}
}
}
}
trades_update();
}
int32_t is_specialexchange(char *exchangestr)
{
if ( strcmp(exchangestr,"InstantDEX") == 0 || strcmp(exchangestr,"jumblr") == 0 || strcmp(exchangestr,"pangea") == 0 || strcmp(exchangestr,"peggy") == 0 || strcmp(exchangestr,"wallet") == 0 || strcmp(exchangestr,"active") == 0 || strncmp(exchangestr,"basket",strlen("basket")) == 0 )
return(1);
return(0);
}
char *InstantDEX_placebidask(char *remoteaddr,uint64_t orderid,char *exchangestr,char *name,char *base,char *rel,struct InstantDEX_quote *iQ,char *extra,char *secret,char *activenxt,cJSON *origjson)
{
struct exchange_info *exchange; cJSON *obj;
char walletstr[256],*str,*retstr = 0; int32_t inverted,dir; struct prices777 *prices; double price,volume;
if ( secret == 0 || activenxt == 0 )
{
secret = IGUANA_NXTACCTSECRET;
activenxt = IGUANA_NXTADDR;
}
//printf("placebidask.(%s)\n",jprint(origjson,0));
if ( (obj= jobj(origjson,"wallet")) != 0 )
{
str = jprint(obj,1);
safecopy(walletstr,str,sizeof(walletstr));
free(str), str = 0;
}
else walletstr[0] = 0;
if ( exchangestr != 0 && (exchange= exchange_find(exchangestr)) != 0 )
iQ->exchangeid = exchange->exchangeid;
if ( iQ->exchangeid < 0 || (exchangestr= exchange_str(iQ->exchangeid)) == 0 )
{
printf("exchangestr.%s id.%d\n",exchangestr,iQ->exchangeid);
return(clonestr("{\"error\":\"exchange not active, check SuperNET.conf exchanges array\"}\n"));
}
//printf("walletstr.(%s)\n",walletstr);
if ( (prices= prices777_find(&inverted,iQ->s.baseid,iQ->s.relid,exchangestr)) == 0 )
prices = prices777_poll(exchangestr,name,base,iQ->s.baseid,rel,iQ->s.relid);
if ( prices != 0 )
{
price = iQ->s.price, volume = iQ->s.vol;
if ( price < SMALLVAL || volume < SMALLVAL )
{
printf("price %f volume %f error\n",price,volume);
return(clonestr("{\"error\":\"prices777_trade invalid price or volume\"}\n"));
}
if ( iQ->s.isask != 0 )
dir = -1;
else dir = 1;
if ( inverted != 0 )
{
dir *= -1;
volume *= price;
price = 1. / price;
printf("price inverted (%f %f) -> (%f %f)\n",iQ->s.price,iQ->s.vol,price,volume);
}
//printf("dir.%d price %f vol %f isask.%d remoteaddr.%p\n",dir,price,volume,iQ->s.isask,remoteaddr);
if ( remoteaddr == 0 )
{
if ( is_specialexchange(exchangestr) == 0 )
return(prices777_trade(0,0,0,0,1,0,activenxt,secret,prices,dir,price,volume,iQ,0,iQ->s.quoteid,extra));
//printf("check automatch\n");
//if ( strcmp(exchangestr,"wallet") != 0 && strcmp(exchangestr,"jumblr") != 0 && strcmp(exchangestr,"pangea") != 0 && iQ->s.automatch != 0 && (SUPERNET.automatch & 1) != 0 && (retstr= automatch(prices,dir,volume,price,activenxt,secret)) != 0 )
// return(retstr);
if ( strcmp(IGUANA_NXTACCTSECRET,secret) != 0 )
return(clonestr("{\"error\":\"cant do queued requests with non-default accounts\"}"));
retstr = InstantDEX_str(walletstr,0,1,iQ);
//printf("create_iQ.(%llu) quoteid.%llu walletstr.(%s) %p\n",(long long)iQ->s.offerNXT,(long long)iQ->s.quoteid,walletstr,walletstr);
iQ = create_iQ(iQ,walletstr);
printf("local got create_iQ.(%llu) quoteid.%llu wallet.(%s) baseamount %llu iswallet.%d\n",(long long)iQ->s.offerNXT,(long long)iQ->s.quoteid,walletstr,(long long)iQ->s.baseamount,iQ->s.wallet);
prices777_InstantDEX(prices,MAX_DEPTH);
queue_enqueue("InstantDEX",&InstantDEXQ,queueitem(retstr),0);
}
else
{
iQ = create_iQ(iQ,walletstr);
if ( (retstr= autofill(remoteaddr,iQ,activenxt,secret)) == 0 )
{
//printf("create_iQ.(%llu) quoteid.%llu\n",(long long)iQ->s.offerNXT,(long long)iQ->s.quoteid);
if ( strcmp(IGUANA_NXTACCTSECRET,secret) != 0 )
return(clonestr("{\"error\":\"cant do queued requests with non-default accounts\"}"));
prices777_InstantDEX(prices,MAX_DEPTH);
printf("remote got create_iQ.(%llu) quoteid.%llu wallet.(%s) baseamount %llu\n",(long long)iQ->s.offerNXT,(long long)iQ->s.quoteid,walletstr,(long long)iQ->s.baseamount);
}
return(retstr);
}
} else printf("cant find prices\n");
if ( retstr == 0 )
retstr = clonestr("{\"error\":\"cant get prices ptr\"}");
return(retstr);
}
#endif
#endif

1016
iguana/InstantDEX/quotes777.c

File diff suppressed because it is too large

1496
iguana/InstantDEX/subatomic.h

File diff suppressed because it is too large

323
iguana/InstantDEX/tradebots.h

@ -0,0 +1,323 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#ifndef xcode_tradebots_h
#define xcode_tradebots_h
#define TRADEBOT_DEFAULT_DURATION (600)
struct tradebot_info
{
char buf[512],name[64],*prevobookstr,NXTADDR[64],NXTACCTSECRET[64];
uint32_t starttime,expiration,finishtime,startedtrades,apitag;
int32_t numtrades,havetrade,numlinks;
double price,volume;
struct prices777_order trades[256]; void *cHandles[256]; int32_t curlings[256];
struct tradebot_info *linkedbots[8];
struct apitag_info *api;
struct tradebot_info *oppo;
struct InstantDEX_quote iQ;
};
// ./SNapi "{\"allfields\":1,\"agent\":\"InstantDEX\",\"method\":\"orderbook\",\"exchange\":\"active\",\"base\":\"NXT\",\"rel\":\"BTC\"}"
// test balance verifier
// test tradeleg verifier
// test pass through quotes
// user lockin addrs
// atomic swaps using 2of3 msig
// broadcast request to all marketmakers
// pick best response and do BTC <-> NXT and NXT <-> ABC
int32_t tradebot_havealltrades(struct tradebot_info *bot)
{
int32_t i;
if ( bot->havetrade != 0 )
{
if ( bot->numlinks > 0 )
{
for (i=0; i<bot->numlinks; i++)
if ( bot->linkedbots[i] == 0 || bot->linkedbots[i]->havetrade == 0 )
return(0);
}
return(1);
}
return(0);
}
struct tradebot_info *tradebot_compile(cJSON *argjson,struct InstantDEX_quote *iQ,struct apitag_info *api)
{
static uint64_t lastmonce;
uint64_t monce; char *name,*tmp,*tmp2; int32_t duration; struct tradebot_info *bot = calloc(1,sizeof(*bot));
monce = (long long)(1000*time(NULL) + milliseconds());
if ( monce == lastmonce )
monce++;
lastmonce = monce;
bot->iQ = *iQ;
bot->api = api;
if ( (duration= juint(argjson,"duration")) == 0 )
duration = TRADEBOT_DEFAULT_DURATION;
bot->expiration = (uint32_t)time(NULL) + duration;
if ( (name= jstr(argjson,"name")) != 0 )
safecopy(bot->name,name,sizeof(bot->name));
else sprintf(bot->name,"bot.%llu",monce);
if ( (tmp= jstr(argjson,"botnxt")) == 0 || (tmp2= jstr(argjson,"secret")) == 0 )
{
safecopy(bot->NXTADDR,SUPERNET.NXTADDR,sizeof(bot->NXTADDR));
safecopy(bot->NXTACCTSECRET,SUPERNET.NXTACCTSECRET,sizeof(bot->NXTACCTSECRET));
}
else
{
safecopy(bot->NXTADDR,tmp,sizeof(bot->NXTADDR));
safecopy(bot->NXTACCTSECRET,tmp2,sizeof(bot->NXTACCTSECRET));
}
//bot->arbmargin = jdouble(argjson,"arbmargin");
return(bot);
}
int32_t tradebot_acceptable(struct tradebot_info *bot,cJSON *item)
{
double price,volume; int32_t dir,i,n; cJSON *trades,*trade;
if ( bot->iQ.s.isask != 0 )
dir = -1;
else dir = 1;
bot->price = price = jdouble(item,"price");
bot->volume = volume = jdouble(item,"volume");
if ( (trades= jarray(&n,item,"trades")) != 0 )
{
/*{
"plugin": "InstantDEX",
"method": "tradesequence",
"dotrade": 1,
"price": 0.00001858,
"volume": 484.39181916,
"trades": [
{
"basket": "bid",
"price": 0.00001858,
"volume": 484.39181916,
"group": 0,
"exchange": "bittrex",
"base": "NXT",
"rel": "BTC",
"trade": "sell",
"name": "NXT/BTC",
"orderprice": 0.00001858,
"ordervolume": 484.39181916
}
]
}*/
if ( n == 1 && is_cJSON_Array(jitem(trades,0)) != 0 )
{
//printf("NESTED ARRAY DETECTED\n");
trades = jitem(trades,0);
n = cJSON_GetArraySize(trades);
}
sprintf(bot->buf,"[%s %s%s %.8f %.4f] <- ",bot->iQ.s.isask != 0 ? "sell" : "buy ",bot->iQ.base,bot->iQ.rel,price,volume);
for (i=0; i<n; i++)
{
trade = jitem(trades,i);
sprintf(bot->buf+strlen(bot->buf),"[%s %s %.8f %.4f] ",jstr(trade,"exchange"),jstr(trade,"trade"),jdouble(trade,"orderprice"),jdouble(trade,"ordervolume"));
}
sprintf(bot->buf+strlen(bot->buf),"n.%d\n",n);
if ( bot->iQ.s.isask == 0 && bot->oppo != 0 && bot->price > 0. && bot->oppo->price > 0 )
{
//if ( bot->price < bot->oppo->price )
{
printf("%s%s%.8f -> %.8f = gain %.3f%%\n\n",bot->buf,bot->oppo->buf,bot->price,bot->oppo->price,(bot->oppo->price/bot->price - 1)*100);
}
}
}
//printf("%s: dir.%d price %.8f vol %f vs bot price %.8f vol %f\n",bot->name,dir,price,volume,bot->iQ.s.price,bot->iQ.s.vol);
//if ( (dir > 0 && price < bot->iQ.s.price) || (dir < 0 && price >= bot->iQ.s.price) )
return(1);
return(0);
}
int32_t tradebot_isvalidtrade(struct tradebot_info *bot,struct prices777_order *order,cJSON *retjson)
{
cJSON *array,*item; char *resultval; double balance,required; int32_t i,n,valid = 0;
if ( (array= jarray(&n,retjson,"traderesults")) != 0 )
{
for (i=0; i<n; i++)
{
item = jitem(array,i);
if ( jstr(item,"error") == 0 && (resultval= jstr(item,"success")) != 0 )
{
balance = jdouble(item,"balance");
required = jdouble(item,"required");
printf("[%s %f R%f] ",resultval,balance,required);
valid++;
}
}
//printf("valid.%d of %d\n",valid,n);
if ( valid == n )
return(0);
}
return(-1);
}
int32_t tradebot_tradedone(struct tradebot_info *bot,struct prices777_order *order)
{
struct pending_trade *pend;
if ( (pend= order->pend) != 0 && pend->finishtime != 0 )
return(1);
else return(0);
}
int32_t tradebot_haspending(struct tradebot_info *bot)
{
int32_t i,finished;
for (i=finished=0; i<bot->numtrades; i++)
{
if ( tradebot_tradedone(bot,&bot->trades[i]) > 0 )
finished++;
}
return(finished < bot->numtrades);
}
void tradebot_free(struct tradebot_info *bot)
{
int32_t i; struct pending_trade *pend;
for (i=0; i<bot->numtrades; i++)
{
if ( (pend= bot->trades[i].pend) != 0 )
free_pending(pend);
if ( bot->trades[i].retitem != 0 )
free_json(bot->trades[i].retitem);
if ( bot->cHandles[i] != 0 )
{
while ( bot->curlings[i] != 0 )
{
fprintf(stderr,"%s: wait for curlrequest[%d] to finish\n",bot->name,i);
sleep(3);
}
curlhandle_free(bot->cHandles[i]);
}
}
if ( bot->prevobookstr != 0 )
free(bot->prevobookstr);
free(bot);
}
void Tradebot_loop(void *ptr)
{
int32_t i,n,dotrade; char *obookstr,*retstr; cJSON *json,*array,*item,*retjson,*submit;
char jsonstr[1024]; struct tradebot_info *bot = ptr;
printf("START Tradebot.(%s)\n",bot->name);
while ( bot->finishtime == 0 && time(NULL) < bot->expiration )
{
if ( bot->startedtrades == 0 )
{
sprintf(jsonstr,"{\"allfields\":1,\"agent\":\"InstantDEX\",\"method\":\"orderbook\",\"exchange\":\"active\",\"base\":\"%s\",\"rel\":\"%s\"}",bot->iQ.base,bot->iQ.rel);
if ( (json= cJSON_Parse(jsonstr)) == 0 )
{
printf("cant parse.(%s)\n",jsonstr);
exit(-1);
}
obookstr = SuperNET_SNapi(bot->api,json,0,1);
//printf("GOT.(%s)\n",obookstr);
free_json(json);
if ( bot->prevobookstr == 0 || strcmp(obookstr,bot->prevobookstr) != 0 )
{
if ( bot->prevobookstr != 0 )
free(bot->prevobookstr);
bot->prevobookstr = obookstr;
//printf("UPDATE.(%s)\n",obookstr);
submit = 0;
if ( (json= cJSON_Parse(obookstr)) != 0 )
{
array = (bot->iQ.s.isask != 0) ? jarray(&n,json,"bids") : jarray(&n,json,"asks");
if ( array != 0 && n > 0 )
{
dotrade = 0;
for (i=0; i<1; i++)
{
item = jitem(array,i);
if ( tradebot_acceptable(bot,item) > 0 )
{
submit = cJSON_Duplicate(item,1);
if ( jobj(submit,"dotrade") == 0 )
jaddnum(submit,"dotrade",0);
else cJSON_ReplaceItemInObject(submit,"dotrade",cJSON_CreateNumber(0));
retstr = SuperNET_SNapi(bot->api,submit,0,1);
free_json(submit);
//retstr = InstantDEX_tradesequence(bot->curlings,bot,bot->cHandles,&bot->numtrades,bot->trades,(int32_t)( sizeof(bot->trades)/sizeof(*bot->trades)),dotrade,bot->NXTADDR,bot->NXTACCTSECRET,item);
if ( retstr != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
if ( tradebot_isvalidtrade(bot,&bot->trades[i],retjson) > 0 )
bot->havetrade = 1;
free_json(retjson);
}
free(retstr);
if ( bot->havetrade == 0 )
continue;
}
}
break;
}
if ( 0 && submit != 0 && tradebot_havealltrades(bot) != 0 )
{
dotrade = 1;
cJSON_ReplaceItemInObject(submit,"dotrade",cJSON_CreateNumber(1));
bot->startedtrades = (uint32_t)time(NULL);
retstr = InstantDEX_tradesequence(bot->curlings,bot,bot->cHandles,&bot->numtrades,bot->trades,(int32_t)(sizeof(bot->trades)/sizeof(*bot->trades)),dotrade,bot->NXTADDR,bot->NXTACCTSECRET,item);
printf("TRADE RESULT.(%s)\n",retstr);
break;
}
}
free_json(json);
}
}
}
else if ( bot->startedtrades != 0 )
{
if ( tradebot_haspending(bot) > 0 && bot->finishtime == 0 )
bot->finishtime = (uint32_t)time(NULL);
}
usleep(5000000);
}
while ( tradebot_haspending(bot) != 0 )
sleep(60);
printf("FINISHED Tradebot.(%s) at %u finishtime.%u expiration.%u\n",bot->name,(uint32_t)time(NULL),bot->finishtime,bot->expiration);
tradebot_free(bot);
}
char *Tradebot_parser(cJSON *argjson,struct InstantDEX_quote *iQ,struct apitag_info *api)
{
char *submethod,*exchange; struct tradebot_info *bot,*oppobot;
printf("InstantDEX_tradebot.(%s) (%s/%s)\n",jprint(argjson,0),iQ->base,iQ->rel);
if ( (submethod= jstr(argjson,"submethod")) != 0 && (exchange= jstr(argjson,"exchange")) != 0 && strcmp(exchange,"active") == 0 && iQ != 0 )
{
if ( strcmp(submethod,"simplebot") == 0 )
{
if ( (bot= tradebot_compile(argjson,iQ,api)) == 0 )
return(clonestr("{\"error\":\"tradebot compiler error\"}"));
iQ->s.isask ^= 1;
if ( (oppobot= tradebot_compile(argjson,iQ,api)) == 0 )
return(clonestr("{\"error\":\"tradebot compiler error\"}"));
bot->oppo = oppobot;
oppobot->oppo = bot;
iguana_launch("bot",(void *)Tradebot_loop,bot);
iguana_launch("oppobot",(void *)Tradebot_loop,oppobot);
return(clonestr("{\"result\":\"tradebot started\"}"));
} else return(clonestr("{\"error\":\"unrecognized tradebot command\"}"));
return(clonestr("{\"result\":\"tradebot command processed\"}"));
} else return(clonestr("{\"error\":\"no prices777 or no tradebot submethod or not active exchange\"}"));
}
#endif

1583
iguana/InstantDEX/trades.h

File diff suppressed because it is too large

194
iguana/SuperNET.c

@ -564,7 +564,7 @@ char *SuperNET_DHTsend(struct supernet_info *myinfo,uint64_t destipbits,bits256
jaddbits256(json,"subhash",subhash);
if ( SuperNET_hexmsgfind(myinfo,categoryhash,subhash,hexmsg,1) >= 0 )
{
char str[65]; printf("duplicate hex.(%s) for %s\n",hexmsg,bits256_str(str,categoryhash));
//char str[65]; printf("duplicate hex.(%s) for %s\n",hexmsg,bits256_str(str,categoryhash));
return(clonestr("{\"error\":\"duplicate packet rejected\"}"));
}
jsonstr = jprint(json,1);
@ -878,11 +878,53 @@ void SuperNET_parsepeers(struct supernet_info *myinfo,cJSON *array,int32_t n,int
}
}
cJSON *SuperNET_rosettajson(bits256 privkey,int32_t showprivs)
{
uint8_t rmd160[20],pub[33],flag = 0; uint64_t nxt64bits; bits256 pubkey;
char str2[41],wifbuf[64],addr[64],str[128]; cJSON *retjson;
pubkey = acct777_pubkey(privkey);
nxt64bits = acct777_nxt64bits(pubkey);
retjson = cJSON_CreateObject();
jaddbits256(retjson,"pubkey",pubkey);
RS_encode(str,nxt64bits);
jaddstr(retjson,"RS",str);
jadd64bits(retjson,"NXT",nxt64bits);
btc_priv2pub(pub,privkey.bytes);
init_hexbytes_noT(str,pub,33);
jaddstr(retjson,"btcpubkey",str);
calc_OP_HASH160(str2,rmd160,str);
jaddstr(retjson,"rmd160",str2);
if ( btc_coinaddr(addr,0,str) == 0 )
{
jaddstr(retjson,"BTC",addr);
if ( flag != 0 )
{
btc_priv2wif(wifbuf,privkey.bytes,0x80);
jaddstr(retjson,"BTCwif",wifbuf);
}
}
if ( btc_coinaddr(addr,60,str) == 0 )
{
jaddstr(retjson,"BTCD",addr);
if ( flag != 0 )
{
btc_priv2wif(wifbuf,privkey.bytes,0xbc);
jaddstr(retjson,"BTCDwif",wifbuf);
}
}
if ( flag != 0 )
jaddbits256(retjson,"privkey",privkey);
return(retjson);
}
#include "../includes/iguana_apidefs.h"
HASH_ARG(SuperNET,priv2pub,privkey)
{
cJSON *retjson = cJSON_CreateObject(); bits256 pubkey;
cJSON *retjson; bits256 pubkey;
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
retjson = cJSON_CreateObject();
crypto_box_priv2pub(pubkey.bytes,privkey.bytes);
jaddbits256(retjson,"result",pubkey);
return(jprint(retjson,1));
@ -890,7 +932,10 @@ HASH_ARG(SuperNET,priv2pub,privkey)
ZERO_ARGS(SuperNET,keypair)
{
cJSON *retjson = cJSON_CreateObject(); bits256 pubkey,privkey;
cJSON *retjson; bits256 pubkey,privkey;
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
retjson = cJSON_CreateObject();
crypto_box_keypair(pubkey.bytes,privkey.bytes);
jaddstr(retjson,"result","generated keypair");
jaddbits256(retjson,"privkey",privkey);
@ -900,8 +945,11 @@ ZERO_ARGS(SuperNET,keypair)
TWOHASHES_AND_STRING(SuperNET,decipher,privkey,srcpubkey,cipherstr)
{
int32_t cipherlen,msglen; char *retstr; cJSON *retjson; void *ptr = 0; uint8_t *cipher,*message,space[8192];
cipherlen = (int32_t)strlen(cipherstr) >> 1;
int32_t cipherlen=0,msglen; char *retstr; cJSON *retjson; void *ptr = 0; uint8_t *cipher,*message,space[8192];
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
if ( cipherstr != 0 )
cipherlen = (int32_t)strlen(cipherstr) >> 1;
if ( cipherlen < crypto_box_NONCEBYTES )
return(clonestr("{\"error\":\"cipher is too short\"}"));
cipher = calloc(1,cipherlen);
@ -923,6 +971,8 @@ TWOHASHES_AND_STRING(SuperNET,cipher,privkey,destpubkey,message)
{
cJSON *retjson; char *retstr,*hexstr,space[8129]; uint8_t space2[8129];
uint8_t *cipher; int32_t cipherlen,onetimeflag; bits256 origprivkey; void *ptr = 0;
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
if ( (cipher= SuperNET_ciphercalc(&ptr,&cipherlen,&privkey,&destpubkey,(uint8_t *)message,(int32_t)strlen(message)+1,space2,sizeof(space2))) != 0 )
{
if ( cipherlen > sizeof(space)/2 )
@ -934,7 +984,7 @@ TWOHASHES_AND_STRING(SuperNET,cipher,privkey,destpubkey,message)
onetimeflag = memcmp(origprivkey.bytes,privkey.bytes,sizeof(privkey));
if ( onetimeflag != 0 )
{
jaddbits256(retjson,"onetime_privkey",privkey);
//jaddbits256(retjson,"onetime_privkey",privkey);
jaddbits256(retjson,"onetime_pubkey",destpubkey);
if ( onetimeflag == 2 )
jaddstr(retjson,"warning","onetime keypair was used to broadcast");
@ -972,8 +1022,10 @@ bits256 SuperNET_pindecipher(IGUANA_ARGS,char *pin,char *privcipher)
THREE_STRINGS(SuperNET,rosetta,passphrase,pin,showprivkey)
{
uint8_t rmd160[20],pub[33],flag = 0; uint64_t nxt64bits; bits256 check,privkey,pubkey,pinpriv,pinpub;
char str2[41],wifbuf[64],addr[64],str[128],privcipher[512],*privcipherstr,*cstr; cJSON *retjson;
uint8_t flag = 0; uint64_t nxt64bits; bits256 check,privkey,pubkey,pinpriv,pinpub;
char str[128],privcipher[512],*privcipherstr,*cstr; cJSON *retjson;
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
nxt64bits = conv_NXTpassword(privkey.bytes,pubkey.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase));
if ( showprivkey != 0 && strcmp(showprivkey,"yes") == 0 )
flag = 1;
@ -989,40 +1041,8 @@ THREE_STRINGS(SuperNET,rosetta,passphrase,pin,showprivkey)
} else printf("error parsing cipher retstr.(%s)\n",cstr);
free(cstr);
} else printf("error SuperNET_cipher null return\n");
retjson = cJSON_CreateObject();
retjson = SuperNET_rosettajson(privkey,flag);
jaddstr(retjson,"privcipher",privcipher);
jaddbits256(retjson,"pubkey",pubkey);
RS_encode(str,nxt64bits);
jaddstr(retjson,"RS",str);
jadd64bits(retjson,"NXT",nxt64bits);
btc_priv2pub(pub,privkey.bytes);
init_hexbytes_noT(str,pub,33);
jaddstr(retjson,"btcpubkey",str);
calc_OP_HASH160(str2,rmd160,str);
jaddstr(retjson,"rmd160",str2);
if ( btc_coinaddr(addr,0,str) == 0 )
{
jaddstr(retjson,"BTC",addr);
btc_priv2wif(wifbuf,privkey.bytes,0x80);
if ( flag != 0 )
jaddstr(retjson,"BTCwif",wifbuf);
}
if ( btc_coinaddr(addr,60,str) == 0 )
{
jaddstr(retjson,"BTCD",addr);
btc_priv2wif(wifbuf,privkey.bytes,0xbc);
if ( flag != 0 )
jaddstr(retjson,"BTCDwif",wifbuf);
}
if ( btc_coinaddr(addr,5,str) == 0 )
{
jaddstr(retjson,"VPN",addr);
btc_priv2wif(wifbuf,privkey.bytes,0xbc);
if ( flag != 0 )
jaddstr(retjson,"VPNwif",wifbuf);
}
if ( flag != 0 )
jaddbits256(retjson,"privkey",privkey);
check = SuperNET_pindecipher(IGUANA_CALLARGS,pin,privcipher);
if ( memcmp(check.bytes,privkey.bytes,sizeof(check)) != 0 )
{
@ -1039,6 +1059,8 @@ THREE_STRINGS(SuperNET,rosetta,passphrase,pin,showprivkey)
STRING_ARG(SuperNET,broadcastcipher,message)
{
bits256 zero;
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
memset(zero.bytes,0,sizeof(zero));
return(SuperNET_cipher(IGUANA_CALLARGS,zero,zero,message));
}
@ -1046,6 +1068,8 @@ STRING_ARG(SuperNET,broadcastcipher,message)
STRING_ARG(SuperNET,broadcastdecipher,message)
{
bits256 zero;
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
memset(zero.bytes,0,sizeof(zero));
return(SuperNET_decipher(IGUANA_CALLARGS,zero,zero,message));
}
@ -1053,6 +1077,8 @@ STRING_ARG(SuperNET,broadcastdecipher,message)
HASH_AND_STRING(SuperNET,multicastcipher,pubkey,message)
{
bits256 zero;
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
memset(zero.bytes,0,sizeof(zero));
return(SuperNET_cipher(IGUANA_CALLARGS,zero,pubkey,message));
}
@ -1060,6 +1086,8 @@ HASH_AND_STRING(SuperNET,multicastcipher,pubkey,message)
HASH_AND_STRING(SuperNET,multicastdecipher,privkey,cipherstr)
{
bits256 zero;
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
memset(zero.bytes,0,sizeof(zero));
return(SuperNET_decipher(IGUANA_CALLARGS,privkey,zero,cipherstr));
}
@ -1121,17 +1149,23 @@ TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(SuperNET,DHT,hexmsg,destip,categoryhash,sub
HASH_AND_STRING(SuperNET,saveconf,wallethash,confjsonstr)
{
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
return(clonestr("{\"result\":\"saveconf here\"}"));
}
HASH_ARRAY_STRING(SuperNET,layer,mypriv,otherpubs,str)
{
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
return(clonestr("{\"result\":\"layer encrypt here\"}"));
}
TWO_STRINGS(SuperNET,categoryhashes,category,subcategory)
{
bits256 categoryhash,subhash; cJSON *retjson = cJSON_CreateObject();
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
categoryhash = calc_categoryhashes(&subhash,category,subcategory);
jaddstr(retjson,"result","category hashes calculated");
jaddbits256(retjson,"categoryhash",categoryhash);
@ -1142,6 +1176,8 @@ TWO_STRINGS(SuperNET,categoryhashes,category,subcategory)
TWO_STRINGS(SuperNET,subscribe,category,subcategory)
{
bits256 categoryhash,subhash;
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
categoryhash = calc_categoryhashes(&subhash,category,subcategory);
if ( category_subscribe(myinfo,categoryhash,subhash) != 0 )
return(clonestr("{\"result\":\"subscribed\"}"));
@ -1151,6 +1187,8 @@ TWO_STRINGS(SuperNET,subscribe,category,subcategory)
TWO_STRINGS(SuperNET,gethexmsg,category,subcategory)
{
bits256 categoryhash,subhash; struct category_msg *m; char *hexstr; cJSON *retjson;
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
categoryhash = calc_categoryhashes(&subhash,category,subcategory);
if ( (m= category_gethexmsg(myinfo,categoryhash,subhash)) != 0 )
{
@ -1166,6 +1204,8 @@ TWO_STRINGS(SuperNET,gethexmsg,category,subcategory)
THREE_STRINGS(SuperNET,posthexmsg,category,subcategory,hexmsg)
{
bits256 categoryhash,subhash;
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
categoryhash = calc_categoryhashes(&subhash,category,subcategory);
category_posthexmsg(myinfo,categoryhash,subhash,hexmsg,tai_now(),remoteaddr);
return(clonestr("{\"result\":\"posted message\"}"));
@ -1174,6 +1214,8 @@ THREE_STRINGS(SuperNET,posthexmsg,category,subcategory,hexmsg)
THREE_STRINGS(SuperNET,announce,category,subcategory,message)
{
bits256 categoryhash,subhash;
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
categoryhash = calc_categoryhashes(&subhash,category,subcategory);
return(SuperNET_categorymulticast(myinfo,0,categoryhash,subhash,message,juint(json,"maxdelay"),juint(json,"broadcast"),juint(json,"plaintext")));
}
@ -1181,6 +1223,8 @@ THREE_STRINGS(SuperNET,announce,category,subcategory,message)
THREE_STRINGS(SuperNET,survey,category,subcategory,message)
{
bits256 categoryhash,subhash;
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
categoryhash = calc_categoryhashes(&subhash,category,subcategory);
return(SuperNET_categorymulticast(myinfo,1,categoryhash,subhash,message,juint(json,"maxdelay"),juint(json,"broadcast"),juint(json,"plaintext")));
}
@ -1213,4 +1257,72 @@ INT_ARG(SuperNET,utc2utime,utc)
return(jprint(retjson,1));
}
ZERO_ARGS(SuperNET,logout)
{
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
memset(myinfo->persistent_priv.bytes,0,sizeof(myinfo->persistent_priv));
memset(myinfo->myaddr.persistent.bytes,0,sizeof(myinfo->myaddr.persistent));
memset(myinfo->handle,0,sizeof(myinfo->handle));
memset(myinfo->myaddr.NXTADDR,0,sizeof(myinfo->myaddr.NXTADDR));
myinfo->myaddr.nxt64bits = 0;
return(clonestr("{\"result\":\"logged out\"}"));
}
ZERO_ARGS(SuperNET,activehandle)
{
cJSON *retjson;
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
retjson = SuperNET_rosettajson(myinfo->persistent_priv,0);
jaddstr(retjson,"result","success");
jaddstr(retjson,"handle",myinfo->handle);
return(jprint(retjson,1));
}
FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase)
{
char *str,*decryptstr = 0; cJSON *argjson;
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
if ( bits256_nonz(myinfo->persistent_priv) != 0 && (str= SuperNET_logout(IGUANA_CALLARGS)) != 0 )
free(str);
if ( handle != 0 )
safecopy(myinfo->handle,handle,sizeof(myinfo->handle));
if ( (passphrase == 0 || passphrase[0] == 0) && (decryptstr= SuperNET_decryptjson(IGUANA_CALLARGS,password,permanentfile)) != 0 )
{
if ( (argjson= cJSON_Parse(decryptstr)) != 0 )
{
printf("decrypted.(%s)\n",decryptstr);
free(decryptstr);
if ( (passphrase= jstr(argjson,"result")) != 0 )
{
SuperNET_setkeys(myinfo,passphrase,(int32_t)strlen(passphrase),1);
free_json(argjson);
return(SuperNET_activehandle(IGUANA_CALLARGS));
}
else
{
free_json(argjson);
return(clonestr("{\"error\":\"cant find passphrase in decrypted json\"}"));
}
}
else
{
free(decryptstr);
return(clonestr("{\"error\":\"cant parse decrypted json\"}"));
}
}
if ( passphrase != 0 && passphrase[0] != 0 )
{
SuperNET_setkeys(myinfo,passphrase,(int32_t)strlen(passphrase),1);
if ( (str= SuperNET_encryptjson(IGUANA_CALLARGS,password,permanentfile,passphrase)) != 0 )
free(str);
return(SuperNET_activehandle(IGUANA_CALLARGS));
}
else return(clonestr("{\"error\":\"need passphrase\"}"));
printf("logged into (%s) %s %s\n",myinfo->myaddr.NXTADDR,myinfo->myaddr.BTC,myinfo->myaddr.BTCD);
return(SuperNET_activehandle(IGUANA_CALLARGS));
}
#include "../includes/iguana_apiundefs.h"

40
iguana/SuperNET.h

@ -24,6 +24,7 @@
#define SUPERNET_GETPEERSTR "{\"agent\":\"SuperNET\",\"method\":\"getpeers\",\"plaintext\":1}"
#define SUPERNET_STOPSTR "{\"agent\":\"SuperNET\",\"method\":\"stop\",\"plaintext\":1}"
#define SUPERNET_MAXEXCHANGES 64
#define SUPERNET_LBPORT 7770
#define SUPERNET_PUBPORT 7771
#define SUPERNET_PORTP2P 7770
@ -69,7 +70,7 @@ struct supernet_address
{
bits256 pubkey,iphash,persistent;
uint32_t selfipbits,myipbits; int32_t confirmed,totalconfirmed; uint64_t nxt64bits;
char NXTADDR[32];
char NXTADDR[32],BTC[64],BTCD[64];
};
struct supernet_info
@ -77,13 +78,15 @@ struct supernet_info
char ipaddr[64],transport[8]; int32_t APISLEEP; int32_t iamrelay;
int32_t Debuglevel,readyflag,dead,POLLTIMEOUT; char rpcsymbol[16],LBpoint[64],PUBpoint[64];
//int32_t pullsock,subclient,lbclient,lbserver,servicesock,pubglobal,pubrelays,numservers;
bits256 privkey,persistent_priv;
bits256 privkey,persistent_priv; char secret[2048],NXTAPIURL[512];
uint8_t *recvbuf[6];
struct supernet_address myaddr;
int32_t LBsock,PUBsock,reqsock,subsock,networktimeout,maxdelay;
uint16_t LBport,PUBport,reqport,subport;
struct nn_pollfd pfd[SUPERNET_MAXAGENTS]; //struct relay_info active;
struct supernet_agent agents[SUPERNET_MAXAGENTS]; queue_t acceptQ; int32_t numagents;
struct supernet_agent agents[SUPERNET_MAXAGENTS]; queue_t acceptQ; int32_t numagents,numexchanges;
struct exchange_info *tradingexchanges[SUPERNET_MAXEXCHANGES];
char handle[1024];
};
/*struct supernet_endpoint
@ -94,18 +97,29 @@ struct supernet_info
int32_t nnsock,num; struct endpoint eps[];
};*/
struct category_chain
{
bits256 *weights,*blocks,category_hwm,cchainhash;
int32_t hashlen,addrlen,maxblocknum;
struct supernet_info *myinfo;
void *categoryinfo,*subinfo;
int32_t (*blockhash_func)(struct category_chain *cchain,void *blockhashp,void *data,int32_t datalen);
bits256 (*stake_func)(struct category_chain *cchain,void *addr,int32_t addrlen);
bits256 (*hit_func)(struct category_chain *cchain,int32_t height,void *prevgenerator,void *addr,void *blockhashp);
bits256 (*default_func)(struct category_chain *cchain,int32_t func,int32_t height,void *prevgenerator,void *addr,void *blockhashp,bits256 heaviest);
};
struct category_info
{
UT_hash_handle hh; queue_t Q;
int32_t (*process_func)(struct supernet_info *myinfo,void *data,int32_t datalen,char *remoteaddr);
int32_t (*blockhash_func)(void *blockhashp,void *data,int32_t datalen); // returns len of blockhash
uint64_t (*hit_func)(struct supernet_info *myinfo,void *categoryinfo,void *subinfo,void *addr,int32_t addrlen);
int32_t (*ishwm_func)(struct supernet_info *myinfo,void *categoryinfo,void *subinfo,void *blockhashp,int32_t hashlen,int32_t heighthint,uint64_t hwmwt,uint64_t prevwt,uint64_t hit);
char *(*processfunc)(struct supernet_info *myinfo,void *data,int32_t datalen,char *remoteaddr);
struct category_chain *cchain;
bits256 hash; void *info; struct category_info *sub;
};
extern struct category_info *Categories;
struct category_msg { struct queueitem DL; struct tai t; uint64_t remoteipbits; int32_t len; uint8_t msg[]; };
struct exchange_quote { uint64_t satoshis,orderid,offerNXT,exchangebits; double price,volume; uint32_t timestamp,val; };
void expand_epbits(char *endpoint,struct endpoint epbits);
struct endpoint calc_epbits(char *transport,uint32_t ipbits,uint16_t port,int32_t type);
@ -129,8 +143,8 @@ void *category_info(bits256 categoryhash,bits256 subhash);
void *category_infoset(bits256 categoryhash,bits256 subhash,void *info);
struct category_info *category_find(bits256 categoryhash,bits256 subhash);
void SuperNET_hexmsgprocess(struct supernet_info *myinfo,cJSON *json,char *hexmsg,char *remoteaddr);
struct category_info *category_processfunc(bits256 categoryhash,int32_t (*process_func)(struct supernet_info *myinfo,void *data,int32_t datalen,char *remoteaddr));
int32_t pangea_hexmsg(struct supernet_info *myinfo,void *data,int32_t len,char *remoteaddr);
struct category_info *category_processfunc(bits256 categoryhash,char *(*process_func)(struct supernet_info *myinfo,void *data,int32_t datalen,char *remoteaddr));
char *pangea_hexmsg(struct supernet_info *myinfo,void *data,int32_t len,char *remoteaddr);
void pangea_queues(struct supernet_info *myinfo);
int32_t SuperNET_str2hex(uint8_t *hex,char *str);
@ -144,6 +158,14 @@ char *SuperNET_htmlstr(char *fname,char *htmlstr,int32_t maxsize,char *agentstr)
char *SuperNET_categorymulticast(struct supernet_info *myinfo,int32_t surveyflag,bits256 categoryhash,bits256 subcategory,char *message,int32_t maxdelay,int32_t broadcastflag,int32_t plaintext);
bits256 calc_categoryhashes(bits256 *subhashp,char *category,char *subcategory);
struct category_chain *category_chain_functions(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash,int32_t hashlen,int32_t addrlen,void *hash_func,void *stake_func,void *hit_func,void *default_func);
#define category_default_latest() (*cchain->default_func)(cchain,'L',0,0,0,0,zero)
void category_init(struct supernet_info *myinfo);
char *SuperNET_keysinit(struct supernet_info *myinfo,char *jsonstr);
double instantdex_aveprice(struct supernet_info *myinfo,struct exchange_quote *sortbuf,int32_t max,double *totalvolp,char *base,char *rel,double volume,cJSON *argjson);
void SuperNET_setkeys(struct supernet_info *myinfo,void *pass,int32_t passlen,int32_t dosha256);
char *InstantDEX_hexmsg(struct supernet_info *myinfo,void *data,int32_t len,char *remoteaddr);
#endif

166
iguana/SuperNET_category.c

@ -74,46 +74,163 @@ void *category_infoset(bits256 categoryhash,bits256 subhash,void *info)
return(0);
}
struct category_info *category_processfunc(bits256 categoryhash,int32_t (*process_func)(struct supernet_info *myinfo,void *data,int32_t datalen,char *remoteaddr))
struct category_info *category_processfunc(bits256 categoryhash,char *(*process_func)(struct supernet_info *myinfo,void *data,int32_t datalen,char *remoteaddr))
{
struct category_info *cat;
if ( (cat= category_find(categoryhash,GENESIS_PUBKEY)) != 0 )
{
cat->process_func = process_func;
cat->processfunc = process_func;
return(cat);
}
return(0);
}
struct category_info *category_blockhashfunc(bits256 categoryhash,bits256 subhash,int32_t (*blockhash_func)(void *blockhashp,void *data,int32_t datalen))
int32_t category_default_blockhash(struct category_chain *cchain,void *blockhashp,void *data,int32_t datalen)
{
struct category_info *cat;
if ( (cat= category_find(categoryhash,subhash)) != 0 )
bits256 hash;
vcalc_sha256(0,hash.bytes,data,datalen);
vcalc_sha256(0,blockhashp,hash.bytes,sizeof(hash));
return(sizeof(*blockhashp));
}
bits256 category_default_stake(struct category_chain *cchain,void *addr,int32_t addrlen)
{
bits256 stake;
memset(stake.bytes,0,sizeof(stake));
stake.txid = ((uint64_t)1 << 63);
return(stake);
}
bits256 catgory_default_hit(struct category_chain *cchain,int32_t height,void *prevgenerator,void *addr,void *blockhashp)
{
bits256 hash; bits256 rawhit,hit;
memset(rawhit.bytes,0,sizeof(rawhit));
memset(hit.bytes,0,sizeof(hit));
vcalc_sha256cat(hash.bytes,prevgenerator,cchain->addrlen,addr,cchain->addrlen);
hit = (*cchain->stake_func)(cchain,addr,cchain->addrlen);
rawhit.txid = hash.txid % ((uint64_t)1 << 42);
if ( rawhit.txid != 0 )
hit.txid /= rawhit.txid;
return(hit);
}
#define category_default_heaviest() (*cchain->default_func)(cchain,'H',0,0,0,0,zero)
#define category_default_latest() (*cchain->default_func)(cchain,'L',0,0,0,0,zero)
#define category_default_setheaviest(height,blockhashp,heaviest) (*cchain->default_func)(cchain,'S',height,0,0,blockhashp,zero)
#define category_default_weight(height) (*cchain->default_func)(cchain,'W',height,0,0,0,zero)
#define category_default_blockfind(height) (*cchain->default_func)(cchain,'B',height,0,0,0,zero)
bits256 category_default_func(struct category_chain *cchain,int32_t func,int32_t height,void *prevgenerator,void *addr,void *blockhashp,bits256 heaviest)
{
static bits256 zero;
if ( cchain->hashlen != sizeof(bits256) || cchain->addrlen != sizeof(bits256) )
{
cat->blockhash_func = blockhash_func;
return(cat);
printf("unsupported hashlen.%d or addrlen.%d\n",cchain->hashlen,cchain->addrlen);
return(zero);
}
return(0);
if ( height > cchain->maxblocknum + (func == 'S') )
{
printf("error func.%c setting heaviest. skipped %d -> %d?\n",func,cchain->maxblocknum,height);
return(cchain->category_hwm);
}
if ( func == 'H' )
return(cchain->category_hwm);
else if ( func == 'L' )
{
if ( cchain->maxblocknum < 0 )
return(cchain->cchainhash);
else return(cchain->blocks[cchain->maxblocknum]);
}
else if ( func == 'S' )
{
cchain->category_hwm = heaviest;
if ( height > cchain->maxblocknum )
{
cchain->weights = realloc(cchain->weights,(cchain->maxblocknum+1) * sizeof(*cchain->weights));
cchain->blocks = realloc(cchain->blocks,(cchain->maxblocknum+1) * sizeof(*cchain->blocks));
}
cchain->maxblocknum = height;
cchain->weights[height] = heaviest;
if ( blockhashp != 0 )
memcpy(&cchain->blocks[height],blockhashp,sizeof(cchain->blocks[height]));
}
else if ( func == 'B' )
{
if ( height <= cchain->maxblocknum )
return(cchain->blocks[height]);
else
{
printf("error: illegal height.%d vs max.%d\n",height,cchain->maxblocknum);
return(zero);
}
}
else if ( func == 'W' )
{
if ( height >= 0 && height < cchain->maxblocknum )
return(cchain->weights[height]);
else printf("error getting weight for height.%d vs maxblocknum.%d\n",height,cchain->maxblocknum);
}
return(cchain->category_hwm);
}
struct category_info *category_hitfunc(bits256 categoryhash,bits256 subhash,uint64_t (*hit_func)(struct supernet_info *myinfo,void *categoryinfo,void *subinfo,void *addr,int32_t addrlen))
int32_t category_default_ishwm(struct category_chain *cchain,int32_t prevheight,void *prevblockhashp,void *blockhashp,void *prevgenerator,void *addr)
{
struct category_info *cat;
if ( (cat= category_find(categoryhash,subhash)) != 0 )
bits256 checkhash,prevwt,oldhit,hit,heaviest; static bits256 zero;
checkhash = category_default_blockfind(prevheight);
if ( memcmp(checkhash.bytes,prevblockhashp,cchain->hashlen) == 0 )
{
cat->hit_func = hit_func;
return(cat);
}
return(0);
heaviest = category_default_heaviest();
prevwt = category_default_weight(prevheight);
oldhit = category_default_weight(prevheight+1);
hit = (*cchain->hit_func)(cchain,prevheight+1,prevgenerator,addr,blockhashp);
if ( hit.txid > oldhit.txid && prevwt.txid+hit.txid > heaviest.txid )
{
heaviest.txid = (prevwt.txid + hit.txid);
category_default_setheaviest(prevheight+1,blockhashp,heaviest);
return(prevheight+1);
}
} else return(-2);
return(-1);
}
struct category_info *category_ishwmfunc(bits256 categoryhash,bits256 subhash,int32_t (*ishwm_func)(struct supernet_info *myinfo,void *categoryinfo,void *subinfo,void *blockhashp,int32_t hashlen,int32_t heighthint,uint64_t hwmwt,uint64_t prevwt,uint64_t hit))
struct category_chain *category_chain_functions(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash,int32_t hashlen,int32_t addrlen,void *hash_func,void *stake_func,void *hit_func,void *default_func)
{
struct category_info *cat;
struct category_info *cat; struct category_chain *cchain = calloc(1,sizeof(*cchain));
if ( (cat= category_find(categoryhash,subhash)) != 0 )
{
cat->ishwm_func = ishwm_func;
return(cat);
cchain->maxblocknum = -1;
cchain->myinfo = myinfo, cchain->subinfo = cat->info;
if ( bits256_cmp(subhash,GENESIS_PUBKEY) == 0 )
cchain->categoryinfo = cat->info, cchain->cchainhash = categoryhash;
else cchain->categoryinfo = category_find(categoryhash,GENESIS_PUBKEY), cchain->cchainhash = subhash;
if ( cchain->myinfo == 0 || cchain->categoryinfo || cchain->subinfo )
{
printf("error with cchain pointers\n");
return(0);
}
if ( (cchain->addrlen= addrlen) <= 0 || (cchain->hashlen= hashlen) <= 0 )
{
printf("error with cchain lens.%d %d\n",addrlen,hashlen);
return(0);
}
if ( (cchain->blockhash_func= hash_func) == 0 || (cchain->stake_func= stake_func) == 0 || (cchain->hit_func= hit_func) == 0 || (cchain->default_func= default_func) == 0 )
{
if ( addrlen == sizeof(bits256) && hashlen == sizeof(bits256) )
{
cchain->blockhash_func = category_default_blockhash;
cchain->stake_func = category_default_stake;
cchain->hit_func = catgory_default_hit;
cchain->default_func = category_default_func;
}
else
{
printf("no category chain functions and addrlen.%d hashlen.%d not 32\n",addrlen,hashlen);
return(0);
}
}
cat->cchain = cchain;
return(cchain);
}
return(0);
}
@ -212,3 +329,14 @@ char *SuperNET_categorymulticast(struct supernet_info *myinfo,int32_t surveyflag
free(hexmsg);
return(retstr);
}
void category_init(struct supernet_info *myinfo)
{
bits256 pangeahash;
category_subscribe(myinfo,GENESIS_PUBKEY,GENESIS_PUBKEY);
pangeahash = calc_categoryhashes(0,"pangea",0);
category_subscribe(myinfo,pangeahash,GENESIS_PUBKEY);
category_processfunc(pangeahash,pangea_hexmsg);
category_chain_functions(myinfo,pangeahash,GENESIS_PUBKEY,sizeof(bits256),sizeof(bits256),0,0,0,0);
exchanges777_init(myinfo,0,0);
}

7
iguana/SuperNET_hexmsg.c

@ -75,7 +75,7 @@ void SuperNET_hexmsgadd(struct supernet_info *myinfo,bits256 categoryhash,bits25
void SuperNET_hexmsgprocess(struct supernet_info *myinfo,cJSON *json,char *hexmsg,char *remoteaddr)
{
int32_t len,flag=0; uint8_t _buf[8192],*buf = _buf; bits256 categoryhash; struct category_info *cat;
int32_t len,flag=0; char *str; uint8_t _buf[8192],*buf = _buf; bits256 categoryhash; struct category_info *cat;
if ( hexmsg != 0 )
{
len = (int32_t)strlen(hexmsg);
@ -88,9 +88,10 @@ void SuperNET_hexmsgprocess(struct supernet_info *myinfo,cJSON *json,char *hexms
categoryhash = jbits256(json,"categoryhash");
if ( (cat= category_find(categoryhash,GENESIS_PUBKEY)) != 0 )
{
if ( cat->process_func != 0 )
if ( cat->processfunc != 0 )
{
(*cat->process_func)(myinfo,buf,len,remoteaddr);
if ( (str= (*cat->processfunc)(myinfo,buf,len,remoteaddr)) != 0 )
free(str);
flag = 1;
//printf("PROCESSFUNC\n");
}

407
iguana/SuperNET_keys.c

@ -0,0 +1,407 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include "iguana777.h"
bits256 SuperNET_wallet2shared(bits256 wallethash,bits256 wallet2priv)
{
bits256 wallet2shared,seed,wallet2pub;
wallet2pub = curve25519(wallet2priv,curve25519_basepoint9());
seed = curve25519_shared(wallethash,wallet2pub);
vcalc_sha256(0,wallet2shared.bytes,seed.bytes,sizeof(bits256));
return(wallet2shared);
}
bits256 SuperNET_wallet2priv(char *wallet2fname,bits256 wallethash)
{
char *wallet2str; uint32_t r,i,crc; long allocsize; bits256 wallet2priv;
wallet2priv = GENESIS_PRIVKEY;
if ( wallet2fname[0] != 0 && (wallet2str= OS_filestr(&allocsize,wallet2fname)) != 0 )
{
r = crc = calc_crc32(0,wallet2str,(int32_t)allocsize);
r %= 32;
for (i=0; i<allocsize; i++)
wallet2str[i] ^= wallethash.bytes[(i + r) % 32];
vcalc_sha256(0,wallet2priv.bytes,(void *)wallet2str,(int32_t)allocsize);
free(wallet2str);
//char str[65]; printf("wallet2priv.(%s) from.(%s) crc.%u and passphrase r.%d len.%ld\n",bits256_str(str,wallet2priv),wallet2fname,crc,r,allocsize);
} else if ( wallet2fname[0] != 0 )
printf("SuperNET_wallet2priv cant open (%s)\n",wallet2fname);
return(wallet2priv);
}
char *SuperNET_parsemainargs(struct supernet_info *myinfo,bits256 *wallethashp,bits256 *wallet2privp,char *argjsonstr)
{
cJSON *exchanges=0,*json = 0; char *wallet2fname,*coinargs=0,*secret,*filestr;
long allocsize; bits256 wallethash,wallet2priv; int32_t n,len; uint8_t secretbuf[8192];
wallethash = wallet2priv = GENESIS_PRIVKEY;
if ( argjsonstr != 0 )
{
if ( (filestr= OS_filestr(&allocsize,argjsonstr)) != 0 )
{
json = cJSON_Parse(filestr);
free(filestr);
}
if ( json != 0 || (json= cJSON_Parse(argjsonstr)) != 0 )
{
printf("ARGSTR.(%s)\n",argjsonstr);
if ( jobj(json,"numhelpers") != 0 )
IGUANA_NUMHELPERS = juint(json,"numhelpers");
if ( (secret= jstr(json,"passphrase")) != 0 )
{
len = (int32_t)strlen(secret);
if ( is_hexstr(secret,0) != 0 && len == 128 )
{
len >>= 1;
decode_hex(secretbuf,len,secret);
} else vcalc_sha256(0,secretbuf,(void *)secret,len), len = sizeof(bits256);
memcpy(wallethash.bytes,secretbuf,sizeof(wallethash));
//printf("wallethash.(%s)\n",bits256_str(str,wallethash));
if ( (wallet2fname= jstr(json,"permanentfile")) != 0 )
wallet2priv = SuperNET_wallet2priv(wallet2fname,wallethash);
}
exchanges = jarray(&n,json,"exchanges");
if ( jobj(json,"coins") != 0 )
coinargs = argjsonstr;
free_json(json);
}
}
if ( exchanges != 0 )
exchanges777_init(myinfo,exchanges,0);
*wallethashp = wallethash, *wallet2privp = wallet2priv;
return(coinargs);
}
bits256 SuperNET_linehash(char *_line)
{
int32_t i,j; bits256 hash;
/*if ( _line[strlen(_line)-1] == '\'' && strncmp(_line,match,len) == 0 )
{
_line[strlen(_line)-1] = 0;
_line += len;
}
printf("%02x %02x %02x %02x %02x\n",0xff & _line[0],0xff & _line[1],0xff & _line[2],0xff & _line[3],0xff & _line[4]);*/
for (i=j=0; _line[i]!=0; i++)
{
if ( (uint8_t)_line[i] == 0xe2 && (uint8_t)_line[i+1] == 0x80 )
{
if ( (uint8_t)_line[i+2] == 0x99 )
_line[j++] = '\'', i += 2;
else if ( (uint8_t)_line[i+2] == 0x9c || (uint8_t)_line[i+2] == 0x9d )
_line[j++] = '"', i += 2;
else _line[j++] = _line[i];
}
else _line[j++] = _line[i];
//else if ( (uint8_t)_line[i] == 0x9c )
// _line[i] = '"';
}
_line[j++] = 0;
if ( j == sizeof(bits256)*2 && is_hexstr(_line,j) == j )
decode_hex(hash.bytes,sizeof(hash),_line);
else vcalc_sha256(0,hash.bytes,(void *)_line,j);
//char str[65]; printf("line -> (%s)\n",bits256_str(str,hash));
return(hash);
}
int32_t SuperNET_savejsonfile(char *fname,bits256 privkey,bits256 destpubkey,cJSON *json)
{
char *confstr,*ciphered; FILE *fp;
confstr = jprint(json,0);
if ( bits256_nonz(privkey) != 0 && bits256_cmp(privkey,GENESIS_PUBKEY) != 0 )
{
//sprintf(fname,"confs/iguana.%llu",(long long)wallet2shared.txid);
if ( (ciphered= SuperNET_cipher(0,0,json,0,privkey,destpubkey,confstr)) != 0 )
{
printf("save (%s) <- (%s)\n",fname,confstr);
if ( (fp= fopen(fname,"wb")) != 0 )
{
fwrite(ciphered,1,strlen(ciphered)+1,fp);
fclose(fp);
}
free(ciphered);
} else printf("error ciphering.(%s) (%s)\n",fname,confstr);
}
else
{
//sprintf(fname,"confs/iguana.conf");
//printf("save (%s) <- (%s)\n",fname,confstr);
if ( (fp= fopen(fname,"wb")) != 0 )
{
fwrite(confstr,1,strlen(confstr)+1,fp);
fclose(fp);
}
}
free(confstr);
return(0);
}
int32_t SuperNET_userkeys(char *passphrase,int32_t passsize,char *fname2fa,int32_t fnamesize)
{
return(0);
#ifndef __PNACL
//if ( (bits256_nonz(*wallethashp) == 0 || bits256_cmp(*wallethashp,GENESIS_PRIVKEY) == 0) && (bits256_nonz(*wallet2privp) == 0 || bits256_cmp(*wallet2privp,GENESIS_PRIVKEY) == 0) )
{
sleep(1);
printf("\n\n********************************\n");
if ( OS_getline(1,passphrase,passsize-1,"passphrase: ") > 0 )
;
if ( OS_getline(1,fname2fa,fnamesize-1,"enter filename of a file that you will NEVER lose: ") > 0 )
;
return(0);
}
#endif
return(-1);
}
cJSON *SuperNET_decryptedjson(char *passphrase,int32_t passsize,bits256 wallethash,char *fname2fa,int32_t fnamesize,bits256 wallet2priv)
{
long allocsize; cJSON *filejson,*msgjson=0,*json=0; char *confstr=0,*deciphered,fname[512],str[65];
bits256 wallet2shared,wallet2pub; int32_t first,second;
msgjson = 0;
first = (bits256_nonz(wallethash) != 0 && bits256_cmp(wallethash,GENESIS_PRIVKEY) != 0);
second = (bits256_nonz(wallet2priv) != 0 && bits256_cmp(wallet2priv,GENESIS_PRIVKEY) != 0);
if ( first == 0 && second == 0 && passphrase != 0 && fname2fa != 0 )
{
if ( passphrase[0] == 0 && fname2fa[0] == 0 )
SuperNET_userkeys(passphrase,passsize,fname2fa,fnamesize);
wallethash = SuperNET_linehash(passphrase);
SuperNET_linehash(fname2fa); // maps special chars
wallet2priv = SuperNET_wallet2priv(fname2fa,wallethash);
//char str[65],str2[65]; printf("(%s + %s) -> wallethash.%s 2.(%s)\n",passphrase,fname2fa,bits256_str(str,wallethash),bits256_str(str2,wallet2priv));
}
first = (bits256_nonz(wallethash) != 0 && bits256_cmp(wallethash,GENESIS_PRIVKEY) != 0);
second = (bits256_nonz(wallet2priv) != 0 && bits256_cmp(wallet2priv,GENESIS_PRIVKEY) != 0);
if ( first != 0 || second != 0 )
{
if ( bits256_nonz(wallethash) == 0 )
wallethash = GENESIS_PRIVKEY;
wallet2shared = SuperNET_wallet2shared(wallethash,wallet2priv);
wallet2pub = curve25519(wallet2shared,curve25519_basepoint9());
sprintf(fname,"confs/%s",bits256_str(str,wallet2pub));
printf("fname.(%s) wallet2shared.%s\n",fname,bits256_str(str,wallet2pub));
if ( (confstr= OS_filestr(&allocsize,fname)) != 0 )
{
if ( (filejson= cJSON_Parse(confstr)) != 0 )
{
if ( (deciphered= SuperNET_decipher(0,0,0,0,wallet2shared,curve25519(wallethash,curve25519_basepoint9()),jstr(filejson,"result"))) != 0 )
{
if ( (json= cJSON_Parse(deciphered)) == 0 )
printf("cant decipher (%s) [%s]\n",fname,confstr);
else
{
if ( (msgjson= cJSON_Parse(jstr(json,"message"))) == 0 )
printf("no message in (%s)\n",jprint(json,0));
}
free(deciphered);
}
free_json(filejson);
}
} else printf("couldnt load (%s)\n",fname);
}
else
{
sprintf(fname,"confs/iguana.conf");
if ( (confstr= OS_filestr(&allocsize,fname)) != 0 )
{
if ( (json= cJSON_Parse(confstr)) != 0 )
msgjson = json;
} else printf("couldnt open (%s)\n",fname);
}
if ( msgjson != 0 )
msgjson = jduplicate(msgjson);
if ( json != 0 )
free_json(json);
return(msgjson);
}
int32_t _SuperNET_encryptjson(char *destfname,char *passphrase,int32_t passsize,char *fname2fa,int32_t fnamesize,cJSON *argjson)
{
bits256 wallethash,wallet2priv,wallet2shared,wallet2pub; char str[65];
wallethash = wallet2priv = GENESIS_PRIVKEY;
if ( passphrase == 0 || passphrase[0] == 0 || fname2fa == 0 || fname2fa[0] == 0 )
SuperNET_userkeys(passphrase,passsize,fname2fa,fnamesize);
wallethash = SuperNET_linehash(passphrase);
SuperNET_linehash(fname2fa); // maps special chars
wallet2priv = SuperNET_wallet2priv(fname2fa,wallethash);
char str2[65]; printf("ENCRYPT.[%s %s] (%s) 2.%s\n",passphrase,fname2fa,bits256_str(str,wallethash),bits256_str(str2,wallet2priv));
wallet2shared = SuperNET_wallet2shared(wallethash,wallet2priv);
wallet2pub = curve25519(wallet2shared,curve25519_basepoint9());
sprintf(destfname,"confs/%s",bits256_str(str,wallet2pub));
//printf("shared.%llx -> pub.%s\n",(long long)wallet2shared.txid,bits256_str(str,wallet2pub));
SuperNET_savejsonfile(destfname,wallethash,wallet2pub,argjson);
return(0);
}
void SuperNET_setkeys(struct supernet_info *myinfo,void *pass,int32_t passlen,int32_t dosha256)
{
char pubkeystr[128]; uint8_t pubkey33[33]; bits256 hash;
if ( dosha256 != 0 )
{
memcpy(myinfo->secret,pass,passlen+1);
myinfo->myaddr.nxt64bits = conv_NXTpassword(myinfo->persistent_priv.bytes,myinfo->myaddr.persistent.bytes,pass,passlen);
}
else
{
myinfo->myaddr.persistent = curve25519(myinfo->persistent_priv,curve25519_basepoint9());
init_hexbytes_noT(myinfo->secret,myinfo->persistent_priv.bytes,sizeof(myinfo->persistent_priv));
vcalc_sha256(0,hash.bytes,myinfo->myaddr.persistent.bytes,32);
myinfo->myaddr.nxt64bits = hash.txid;
}
RS_encode(myinfo->myaddr.NXTADDR,myinfo->myaddr.nxt64bits);
btc_priv2pub(pubkey33,myinfo->persistent_priv.bytes);
init_hexbytes_noT(pubkeystr,pubkey33,33);
btc_coinaddr(myinfo->myaddr.BTC,0,pubkeystr);
btc_coinaddr(myinfo->myaddr.BTCD,60,pubkeystr);
}
void SuperNET_parsemyinfo(struct supernet_info *myinfo,cJSON *msgjson)
{
char *ipaddr,*secret,str[65]; bits256 checkhash;
if ( msgjson != 0 )
{
if ( (ipaddr= jstr(msgjson,"ipaddr")) != 0 && is_ipaddr(ipaddr) != 0 )
strcpy(myinfo->ipaddr,ipaddr);
if ( (secret= jstr(msgjson,"passphrase")) != 0 )
SuperNET_setkeys(myinfo,secret,(int32_t)strlen(secret),1);
else
{
myinfo->persistent_priv = jbits256(msgjson,"persistent_priv");
SuperNET_setkeys(myinfo,myinfo->persistent_priv.bytes,sizeof(myinfo->persistent_priv),0);
if ( bits256_nonz(myinfo->persistent_priv) == 0 )
{
printf("null persistent_priv? generate new one\n");
OS_randombytes(myinfo->persistent_priv.bytes,sizeof(myinfo->privkey));
}
myinfo->myaddr.persistent = jbits256(msgjson,"persistent_pub");
checkhash = curve25519(myinfo->persistent_priv,curve25519_basepoint9());
}
if ( memcmp(checkhash.bytes,myinfo->myaddr.persistent.bytes,sizeof(checkhash)) != 0 )
{
printf("persistent pubkey mismatches one in iguana.conf\n");
myinfo->myaddr.persistent = checkhash;
} else printf("persistent VALIDATED persistentpub.(%s)\n",bits256_str(str,checkhash));
}
if ( bits256_nonz(myinfo->persistent_priv) == 0 )
OS_randombytes(myinfo->persistent_priv.bytes,sizeof(myinfo->persistent_priv));
SuperNET_setkeys(myinfo,myinfo->persistent_priv.bytes,sizeof(myinfo->persistent_priv),0);
}
char *SuperNET_keysinit(struct supernet_info *myinfo,char *argjsonstr)
{
long allocsize; cJSON *msgjson,*json=0; uint32_t r; bits256 wallethash,wallet2priv; int32_t len,c;
char str[65],str2[65],destfname[1024],fname2fa[2048],passphrase[8192],*ipaddr,*coinargs=0;
passphrase[0] = fname2fa[0] = 0;
wallethash = wallet2priv = GENESIS_PRIVKEY;
coinargs = SuperNET_parsemainargs(myinfo,&wallethash,&wallet2priv,argjsonstr);
//printf("wallethash.%s 2.(%s)\n",bits256_str(str,wallethash),bits256_str(str2,wallet2priv));
if ( (msgjson= SuperNET_decryptedjson(passphrase,sizeof(passphrase),wallethash,fname2fa,sizeof(fname2fa),wallet2priv)) != 0 )
{
SuperNET_parsemyinfo(myinfo,msgjson);
free_json(msgjson);
}
else
{
if ( bits256_nonz(myinfo->persistent_priv) == 0 )
{
OS_randombytes(myinfo->persistent_priv.bytes,sizeof(myinfo->persistent_priv));
myinfo->myaddr.persistent = curve25519(myinfo->persistent_priv,curve25519_basepoint9());
}
json = cJSON_CreateObject();
jaddstr(json,"ipaddr",myinfo->ipaddr);
jaddbits256(json,"persistent_priv",myinfo->persistent_priv);
jaddbits256(json,"persistent_pub",myinfo->myaddr.persistent);
OS_randombytes((void *)&r,sizeof(r));
jadd64bits(json,"rand",r);
//printf("call SuperNET_encryptjson\n");
_SuperNET_encryptjson(destfname,passphrase,sizeof(passphrase),fname2fa,sizeof(fname2fa),json);
//printf("save.(%s)\n",jprint(json,0));
free_json(json);
}
if ( myinfo->ipaddr[0] == 0 )
{
if ( (ipaddr= OS_filestr(&allocsize,"ipaddr")) != 0 )
{
printf("got ipaddr.(%s)\n",ipaddr);
len = (int32_t)strlen(ipaddr) - 1;
while ( len > 8 && ((c= ipaddr[len]) == '\r' || c == '\n' || c == ' ' || c == '\t') )
ipaddr[len] = 0, len--;
printf("got ipaddr.(%s) %x\n",ipaddr,is_ipaddr(ipaddr));
if ( is_ipaddr(ipaddr) != 0 )
{
strcpy(myinfo->ipaddr,ipaddr);
myinfo->myaddr.selfipbits = (uint32_t)calc_ipbits(ipaddr);
}
free(ipaddr);
}
}
if ( myinfo->myaddr.selfipbits == 0 )
{
strcpy(myinfo->ipaddr,"127.0.0.1");
myinfo->myaddr.selfipbits = (uint32_t)calc_ipbits(myinfo->ipaddr);
}
OS_randombytes(myinfo->privkey.bytes,sizeof(myinfo->privkey));
myinfo->myaddr.pubkey = curve25519(myinfo->privkey,curve25519_basepoint9());
printf("(%s) %s %llu session(%s %s) persistent.%llx %llx\n",myinfo->ipaddr,myinfo->myaddr.NXTADDR,(long long)myinfo->myaddr.nxt64bits,bits256_str(str,myinfo->privkey),bits256_str(str2,myinfo->myaddr.pubkey),(long long)myinfo->persistent_priv.txid,(long long)myinfo->myaddr.persistent.txid);
return(coinargs);
}
#include "../includes/iguana_apidefs.h"
#include "../includes/iguana_apideclares.h"
THREE_STRINGS(SuperNET,encryptjson,password,permanentfile,anything)
{
char destfname[4096],pass[8192],fname2[1023]; cJSON *argjson,*retjson = cJSON_CreateObject();
safecopy(pass,password,sizeof(pass));
safecopy(fname2,permanentfile,sizeof(fname2));
argjson = jduplicate(json);
//printf("argjson.(%s)\n",jprint(argjson,0));
jdelete(argjson,"agent");
jdelete(argjson,"method");
jdelete(argjson,"password");
jdelete(argjson,"permanentfile");
jdelete(argjson,"timestamp");
jdelete(argjson,"tag");
if ( _SuperNET_encryptjson(destfname,pass,sizeof(pass),fname2,sizeof(fname2),argjson) == 0 )
{
jaddstr(retjson,"result","success");
jaddstr(retjson,"filename",destfname);
} else jaddstr(retjson,"error","couldnt encrypt json file");
free_json(argjson);
return(jprint(retjson,1));
}
TWO_STRINGS(SuperNET,decryptjson,password,permanentfile)
{
char pass[8192],fname2[1023]; cJSON *retjson,*obj; bits256 wallethash,wallet2priv;
safecopy(pass,password,sizeof(pass));
safecopy(fname2,permanentfile,sizeof(fname2));
wallethash = wallet2priv = GENESIS_PRIVKEY;
if ( strlen(pass) == sizeof(wallethash)*2 && is_hexstr(pass,(int32_t)sizeof(bits256)*2) > 0 )
wallethash = bits256_conv(pass);
if ( strlen(fname2) == sizeof(wallet2priv)*2 && is_hexstr(fname2,(int32_t)sizeof(bits256)*2) > 0 )
wallet2priv = bits256_conv(fname2);
//printf("decrypt.(%s %s)\n",pass,fname2);
if ( (retjson= SuperNET_decryptedjson(pass,sizeof(pass),wallethash,fname2,sizeof(fname2),wallet2priv)) != 0 )
{
obj = jduplicate(jobj(retjson,"anything"));
jdelete(retjson,"anything");
jadd(retjson,"result",obj);
return(jprint(retjson,1));
}
else return(clonestr("{\"error\":\"couldnt decrypt json file\"}"));
}
#include "../includes/iguana_apiundefs.h"

161
iguana/app/coin_mgmt.js

@ -1,6 +1,4 @@
var coinManagement = {};
// Classes
coinManagement.Coin = function (_id, _symbol, _description, _statusId) {
@ -30,13 +28,25 @@ coinManagement.CoinStatuses = [
coinManagement.Initialize = function () {
coinManagement.Coins = [
new coinManagement.Coin(6, 'USD', 'US Dollar', 1),
new coinManagement.Coin(2, 'EUR', 'EURO', 2),
new coinManagement.Coin(3, 'GBP', 'British Pound', 3),
new coinManagement.Coin(4, 'INR', 'Indian Rupee', 4),
new coinManagement.Coin(5, 'YEN', 'Japanese Yen', 3)
new coinManagement.Coin(1, 'BTC', 'Bitcoin', 1),
new coinManagement.Coin(2, 'BTCD', 'Bitcoin Dark', 1),
//new coinManagement.Coin(3, 'GBP', 'British Pound', 3),
//new coinManagement.Coin(4, 'INR', 'Indian Rupee', 4),
//new coinManagement.Coin(5, 'YEN', 'Japanese Yen', 3)
];
}
};
coinManagement.getCoinSymbols=function(){
var coins=[];
if (coinManagement.Coins === null || coinManagement.Coins === undefined) {
return [];
}
for (var index = 0; index < coinManagement.Coins.length; index++) {
coins.push(coinManagement.Coins[index].Symbol);
}
return coins;
};
coinManagement.GetCoinIndex = function (id) {
@ -52,6 +62,20 @@ coinManagement.GetCoinIndex = function (id) {
}
};
coinManagement.GetCoinIndexBySymbol = function (id) {
if (coinManagement.Coins == null || coinManagement.Coins == undefined) {
return -1;
}
for (var index = 0; index < coinManagement.Coins.length; index++) {
if (coinManagement.Coins[index].Symbol == id) {
console.log('# coin symbol:' + id.toString() + 'is @' + index);
return index;
}
}
};
coinManagement.Post = function (coin) {
if (coin === null || coin === undefined) {
@ -228,15 +252,35 @@ var GetStatusNameHtml = function (id) {
};
var getActionButton = function (id) {
return '<button class="btn btn-raised btn-danger btn-xs coinMgmtActionButton" data-id=' + id + '>Delete</button>';
var getActionButton = function (objCoin) {
if(objCoin.StatusId===3){
return getStopActionButton(objCoin.Id);
}else if(objCoin.StatusId===2 || objCoin.StatusId===4){
return getStartActionButton(objCoin.Id);
}else if(objCoin.StatusId===1){
return getAddActionButton(objCoin.Id);
}
};
var getAddActionButton = function (id) {
return '<button class="btn btn-raised btn-success btn-xs coinMgmtAddActionButton" data-id=' + id + '>Add Coin</button>';
};
var getStopActionButton = function (id) {
// return '<button class="btn btn-raised btn-success btn-xs coinMgmtStartActionButton" data-id=' + id + '>Start Coin</button>';
return '<button class="btn btn-raised btn-danger btn-xs coinMgmtStopActionButton" data-id=' + id + '>Pause Coin</button>';
};
var getStartActionButton = function (id) {
// return '<button class="btn btn-raised btn-success btn-xs coinMgmtStartActionButton" data-id=' + id + '>Start Coin</button>';
return '<button class="btn btn-raised btn-success btn-xs coinMgmtStartActionButton" data-id=' + id + '>Start Coin</button>';
};
var objToHtml = function (objCoin) {
if (objCoin == null || objCoin == undefined) {
return '';
}
return '<tr><td>' + objCoin.Symbol + '</td><td>' + objCoin.Description + '</td><td>' + GetStatusNameHtml(objCoin.StatusId) + '</td><td>' + getActionButton(objCoin.Id) + '</td></tr>';
return '<tr><td>' + objCoin.Symbol + '</td><td>' + objCoin.Description + '</td><td>' + GetStatusNameHtml(objCoin.StatusId) + '</td><td>' + getActionButton(objCoin) + '</td></tr>';
};
var addCoin = function (e) {
@ -244,7 +288,7 @@ var addCoin = function (e) {
console.log('# add coin called');
e.target.removeAttribute('data-dismiss');
if (coinEditFormIsValid() == false) {
if (coinEditFormIsValid() === false) {
console.log('# add coin form is invalid');
return;
}
@ -283,11 +327,85 @@ var deleteCoin = function (id) {
renderGrid();
};
var pauseCoin = function (id) {
console.log('# coin pause called');
var index = coinManagement.GetCoinIndex(id);
var coin=coinManagement.Coins[index].Symbol;
console.log("clicked on coin "+coin);
var request="{\"agent\":\"iguana\",\"method\":\"pausecoin\",\"coin\":\""+coin+"\"}";
SPNAPI.makeRequest(request, function(request,response){
response=JSON.parse(response);
if(response.result && response.result ==="coin paused"){
var indx=coinManagement.GetCoinIndexBySymbol(request.coin);
coinManagement.Coins[indx].StatusId=4;
console.log("coins status changed "+coinManagement.Coins[indx].StatusId);
renderGrid();
}
});
};
var startCoin = function (id) {
console.log('# coin start called');
//coinManagement.Delete(id);
var index = coinManagement.GetCoinIndex(id);
var coin=coinManagement.Coins[index].Symbol;
console.log("clicked on coin "+coin);
var request="{\"agent\":\"iguana\",\"method\":\"startcoin\",\"coin\":\""+coin+"\"}";
SPNAPI.makeRequest(request, function(request,response){
response=JSON.parse(response);
if(response.result && response.result ==="coin started"){
var indx=coinManagement.GetCoinIndexBySymbol(request.coin);
coinManagement.Coins[indx].StatusId=3;
console.log("coins status changed "+coinManagement.Coins[indx].StatusId);
renderGrid();
}
});
};
var addExistingCoin = function (id) {
var isactive=0;
var maxpeers=16;
var services=128;
var index = coinManagement.GetCoinIndex(id);
console.log('# coin add called '+index);
var coin=coinManagement.Coins[index].Symbol;
console.log("clicked on coin "+coin);
var request="{\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\""+coin+"\",\"active\":"+isactive+",\"maxpeers\":"+maxpeers+",\"services\":"+services+"}";
SPNAPI.makeRequest(request, function(request,response){
response=JSON.parse(response);
if(response.result && (response.result ==="coin added" || response.result ==="coin already there")){
var indx=coinManagement.GetCoinIndexBySymbol(request.newcoin);
coinManagement.Coins[indx].StatusId=2;
console.log("coins status changed "+coinManagement.Coins[indx].StatusId);
renderGrid();
}
});
};
var initCoinsAdded=false;
var addInitCoins= function(){
if(!initCoinsAdded){
for (var index = 0; index < coinManagement.Coins.length; index++) {
addExistingCoin(coinManagement.Coins[index].Id);
}
initCoinsAdded=true;
}
};
var coinEditFormReset = function () {
document.getElementById('txtSymbol').value = '';
document.getElementById('txtDescription').value = '';
document.getElementById('ddStatus').value = 1;
}
};
// Event Handlers
var startCoinManagement = function () {
@ -302,4 +420,19 @@ var startCoinManagement = function () {
renderGrid();
populateCoinStatusDropDown();
}
};
var add_new_coin_test=function(){
var request = IsJsonString($('textarea#json_src_coin').val());
if(request!==false){
SPNAPI.makeRequest(JSON.stringify(request), function(request,response){
//response=JSON.parse(response);
$(".coin_result").text(response);
});
}else{
console.log("Invalid JSON");
}
};

86
iguana/app/startup.js

@ -4,21 +4,97 @@ $(function () {
$(".select ").dropdown({ "autoinit ": ".select " });
startCoinManagement();
startPeerManagement();
startBlockExplorer();
//startPeerManagement();
// Event Handlers
// $('.coinMgmtActionButton').click equivelant w/o jQuery
document.body.onclick = function (e) {
e = window.event ? event.srcElement : e.target;
if (e.className && e.className.indexOf('coinMgmtActionButton') != -1) {
deleteCoin(e.getAttribute('data-id'));
if (e.className && e.className.indexOf('coinMgmtStartActionButton') != -1) {
startCoin(e.getAttribute('data-id'));
} else if (e.className && e.className.indexOf('coinMgmtAddActionButton') != -1) {
addExistingCoin(e.getAttribute('data-id'));
} else if (e.className && e.className.indexOf('coinMgmtStopActionButton') != -1) {
pauseCoin(e.getAttribute('data-id'));
}
else if (e.className && e.className.indexOf('addPeerToFav') != -1) {
addPeerToFav(e.getAttribute('data-id'));
addPeerToFav(e.getAttribute('data-id'),e.getAttribute('data-coin'));
}
else if (e.className && e.className.indexOf('removePeerFromFav') != -1) {
removePeerFromFav(e.getAttribute('data-id'));
removePeerFromFav(e.getAttribute('data-id'),e.getAttribute('data-coin'));
}else if(e.className && e.className.indexOf('disconnectPeer') != -1){
disconnectPeer(e.getAttribute('data-ip'),e.getAttribute('data-coin'));
}else if(e.className && e.className.indexOf('connectPeer') != -1){
connectPeer(e.getAttribute('data-ip'),e.getAttribute('data-coin'));
}else if(e.className && e.className.indexOf('coinRPCactive') != -1){
callBlockEXPRPC(e.getAttribute('data-value'));
}else if(e.className && e.className.indexOf('getBlockHashActionButton') != -1){
getBlockhash(e.getAttribute('data-height'));
}else if(e.className && e.className.indexOf('getBlockActionButton') != -1){
getBlock(e.getAttribute('data-hash'));
}else if(e.className && e.className.indexOf('getTrancationActionButton') != -1){
getRawTransaction(e.getAttribute('data-hash'));
}
else if(e.className && e.className.indexOf('host_pangea_request') != -1){
hostPangea();
}
else if(e.className && e.className.indexOf('list_pangea_request') != -1){
lobbyPangea();
}
else if(e.className && e.className.indexOf('join_pangea_game') != -1){
joinPangea(e.getAttribute("data-tablehash"));
}
else if(e.className && e.className.indexOf('instantdex_set_keypair') != -1){
setUeseridandAPIkeyPair();
}
else if(e.className && e.className.indexOf('instantdex_orderbook') != -1){
orderbook();
}
else if(e.className && e.className.indexOf('instantdex_set_method_table') != -1){
instantdex_set_method_table(e.getAttribute("data-method"));
}
else if(e.className && e.className.indexOf('instantdex_sell') != -1){
InstantDEXSell();
}
else if(e.className && e.className.indexOf('instantdex_buy') != -1){
InstantDEXBuy();
}
else if(e.className && e.className.indexOf('instantdex_balance') != -1){
InstantDEX_balance();
}
else if(e.className && e.className.indexOf('instantdex_support') != -1){
InstantDEX_supports();
}
else if(e.className && e.className.indexOf('instantdex_withdraw') != -1){
InstantDEXWithdaw();
}
else if(e.className && e.className.indexOf('instantdex_order_status') != -1){
InstantDEX_orderstatus();
}
else if(e.className && e.className.indexOf('instantdex_open_orders') != -1){
InstantDEX_openorders();
}
else if(e.className && e.className.indexOf('instantdex_trade_history') != -1){
InstantDEX_tradehistory();
}
else if(e.className && e.className.indexOf('instantdex_order_cancel') != -1){
InstantDEX_cancelorder();
}
else if(e.className && e.className.indexOf('instantdex_pollgap') != -1){
InstantDEX_pollgap();
}
else if(e.className && e.className.indexOf('submit_new_coin_test') != -1){
add_new_coin_test();
}
else if(e.className && e.className.indexOf('clear-response-coin') != -1){
$(".coin_result").text("JSON response");
}
///clear-response-coin
};
});

1
iguana/docs/supernet/docs/about.md

@ -0,0 +1 @@
#About Us

28
iguana/docs/supernet/docs/index.md

@ -0,0 +1,28 @@
# Developers
* Getting Started
* Desktop App SDK
* Mobile App SDK
** Android
** iOS
** Windows
* Iguana/SuperNET API Reference: Any General SuperNET specific API reference
** Coins ( ablaze )
** Peers ( eyedea )
* SuperNET Apps specific API Reference: Organising Applications specific API reference and interlinking between other pages to refer if the same API is used in between these applications.
** InstantDEX API
** Pegged Asset Exchange (PAX) API
** Jumblr API
* Iguana/SuperNET Core Coin API Reference: Referecing to SuperNET's core coin's API reference which might be nessary to function or build Iguana/SuperNET Application, and where it's using some different API calls than official APIs
** BitcoinDark API
** Bitcoin API
# For Users
* Iguana Chrome App User Manual
* Iguana Mobile App
** Android
** iOS
* InstantDEX User Manual
* Pegged Asset Exchange (PAX) User Manual
* Jumblr User Manual

5
iguana/docs/supernet/mkdocs.yml

@ -0,0 +1,5 @@
site_name: SuperNET Documentation
pages:
- Home: index.md
- About: about.md
theme: readthedocs

147
iguana/docs/supernet/site/about/index.html

@ -0,0 +1,147 @@
<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>About - SuperNET Documentation</title>
<link rel="shortcut icon" href="../img/favicon.ico">
<link href='https://fonts.googleapis.com/css?family=Lato:400,700|Roboto+Slab:400,700|Inconsolata:400,700' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="../css/theme.css" type="text/css" />
<link rel="stylesheet" href="../css/theme_extra.css" type="text/css" />
<link rel="stylesheet" href="../css/highlight.css">
<script>
// Current page data
var mkdocs_page_name = "About";
</script>
<script src="../js/jquery-2.1.1.min.js"></script>
<script src="../js/modernizr-2.8.3.min.js"></script>
<script type="text/javascript" src="../js/highlight.pack.js"></script>
<script src="../js/theme.js"></script>
</head>
<body class="wy-body-for-nav" role="document">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side stickynav">
<div class="wy-side-nav-search">
<a href=".." class="icon icon-home"> SuperNET Documentation</a>
<div role="search">
<form id ="rtd-search-form" class="wy-form" action="../search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
</form>
</div>
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
<ul class="current">
<li>
<li class="toctree-l1 ">
<a class="" href="..">Home</a>
</li>
<li>
<li>
<li class="toctree-l1 current">
<a class="current" href="./">About</a>
<ul>
<li class="toctree-l3"><a href="#about-us">About Us</a></li>
</ul>
</li>
<li>
</ul>
</div>
&nbsp;
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" role="navigation" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="..">SuperNET Documentation</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="..">Docs</a> &raquo;</li>
<li>About</li>
<li class="wy-breadcrumbs-aside">
</li>
</ul>
<hr/>
</div>
<div role="main">
<div class="section">
<h1 id="about-us">About Us</h1>
</div>
</div>
<footer>
<div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
<a href=".." class="btn btn-neutral" title="Home"><span class="icon icon-circle-arrow-left"></span> Previous</a>
</div>
<hr/>
<div role="contentinfo">
<!-- Copyright etc -->
</div>
Built with <a href="http://www.mkdocs.org">MkDocs</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<div class="rst-versions" role="note" style="cursor: pointer">
<span class="rst-current-version" data-toggle="rst-current-version">
<span><a href=".." style="color: #fcfcfc;">&laquo; Previous</a></span>
</span>
</div>
</body>
</html>

125
iguana/docs/supernet/site/css/highlight.css

@ -0,0 +1,125 @@
/*
This is the GitHub theme for highlight.js
github.com style (c) Vasily Polovnyov <vast@whiteants.net>
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
color: #333;
-webkit-text-size-adjust: none;
}
.hljs-comment,
.diff .hljs-header,
.hljs-javadoc {
color: #998;
font-style: italic;
}
.hljs-keyword,
.css .rule .hljs-keyword,
.hljs-winutils,
.nginx .hljs-title,
.hljs-subst,
.hljs-request,
.hljs-status {
color: #333;
font-weight: bold;
}
.hljs-number,
.hljs-hexcolor,
.ruby .hljs-constant {
color: #008080;
}
.hljs-string,
.hljs-tag .hljs-value,
.hljs-phpdoc,
.hljs-dartdoc,
.tex .hljs-formula {
color: #d14;
}
.hljs-title,
.hljs-id,
.scss .hljs-preprocessor {
color: #900;
font-weight: bold;
}
.hljs-list .hljs-keyword,
.hljs-subst {
font-weight: normal;
}
.hljs-class .hljs-title,
.hljs-type,
.vhdl .hljs-literal,
.tex .hljs-command {
color: #458;
font-weight: bold;
}
.hljs-tag,
.hljs-tag .hljs-title,
.hljs-rule .hljs-property,
.django .hljs-tag .hljs-keyword {
color: #000080;
font-weight: normal;
}
.hljs-attribute,
.hljs-variable,
.lisp .hljs-body,
.hljs-name {
color: #008080;
}
.hljs-regexp {
color: #009926;
}
.hljs-symbol,
.ruby .hljs-symbol .hljs-string,
.lisp .hljs-keyword,
.clojure .hljs-keyword,
.scheme .hljs-keyword,
.tex .hljs-special,
.hljs-prompt {
color: #990073;
}
.hljs-built_in {
color: #0086b3;
}
.hljs-preprocessor,
.hljs-pragma,
.hljs-pi,
.hljs-doctype,
.hljs-shebang,
.hljs-cdata {
color: #999;
font-weight: bold;
}
.hljs-deletion {
background: #fdd;
}
.hljs-addition {
background: #dfd;
}
.diff .hljs-change {
background: #0086b3;
}
.hljs-chunk {
color: #aaa;
}

12
iguana/docs/supernet/site/css/theme.css

File diff suppressed because one or more lines are too long

126
iguana/docs/supernet/site/css/theme_extra.css

@ -0,0 +1,126 @@
/*
* Tweak the overal size to better match RTD.
*/
body {
font-size: 90%;
}
h3, h4, h5, h6 {
color: #2980b9;
font-weight: 300
}
/*
* Sphinx doesn't have support for section dividers like we do in
* MkDocs, this styles the section titles in the nav
*
* https://github.com/mkdocs/mkdocs/issues/175
*/
.wy-menu-vertical span {
line-height: 18px;
padding: 0.4045em 1.618em;
display: block;
position: relative;
font-size: 90%;
color: #838383;
}
.wy-menu-vertical .subnav a {
padding: 0.4045em 2.427em;
}
/*
* Long navigations run off the bottom of the screen as the nav
* area doesn't scroll.
*
* https://github.com/mkdocs/mkdocs/pull/202
*/
.wy-nav-side {
height: 100%;
overflow-y: auto;
}
/*
* readthedocs theme hides nav items when the window height is
* too small to contain them.
*
* https://github.com/mkdocs/mkdocs/issues/#348
*/
.wy-menu-vertical ul {
margin-bottom: 2em;
}
/*
* Fix wrapping in the code highlighting
*
* https://github.com/mkdocs/mkdocs/issues/233
*/
code {
white-space: pre;
}
/*
* Wrap inline code samples otherwise they shoot of the side and
* can't be read at all.
*
* https://github.com/mkdocs/mkdocs/issues/313
*/
p code {
word-wrap: break-word;
}
/*
* The CSS classes from highlight.js seem to clash with the
* ReadTheDocs theme causing some code to be incorrectly made
* bold and italic.
*
* https://github.com/mkdocs/mkdocs/issues/411
*/
code.cs, code.c {
font-weight: inherit;
font-style: inherit;
}
/*
* Fix some issues with the theme and non-highlighted code
* samples. Without and highlighting styles attached the
* formatting is broken.
*
* https://github.com/mkdocs/mkdocs/issues/319
*/
.no-highlight {
display: block;
padding: 0.5em;
color: #333;
}
/*
* Additions specific to the search functionality provided by MkDocs
*/
#mkdocs-search-results article h3
{
margin-top: 23px;
border-top: 1px solid #E1E4E5;
padding-top: 24px;
}
#mkdocs-search-results article:first-child h3 {
border-top: none;
}
#mkdocs-search-query{
width: 100%;
border-radius: 50px;
padding: 6px 12px;
border-color: #D1D4D5;
}
.wy-menu-vertical li ul {
display: inherit;
}
.wy-menu-vertical li ul.subnav ul.subnav{
padding-left: 1em;
}

BIN
iguana/docs/supernet/site/fonts/fontawesome-webfont.eot

Binary file not shown.

399
iguana/docs/supernet/site/fonts/fontawesome-webfont.svg

@ -0,0 +1,399 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<metadata></metadata>
<defs>
<font id="fontawesomeregular" horiz-adv-x="1536" >
<font-face units-per-em="1792" ascent="1536" descent="-256" />
<missing-glyph horiz-adv-x="448" />
<glyph unicode=" " horiz-adv-x="448" />
<glyph unicode="&#x09;" horiz-adv-x="448" />
<glyph unicode="&#xa0;" horiz-adv-x="448" />
<glyph unicode="&#xa8;" horiz-adv-x="1792" />
<glyph unicode="&#xa9;" horiz-adv-x="1792" />
<glyph unicode="&#xae;" horiz-adv-x="1792" />
<glyph unicode="&#xb4;" horiz-adv-x="1792" />
<glyph unicode="&#xc6;" horiz-adv-x="1792" />
<glyph unicode="&#x2000;" horiz-adv-x="768" />
<glyph unicode="&#x2001;" />
<glyph unicode="&#x2002;" horiz-adv-x="768" />
<glyph unicode="&#x2003;" />
<glyph unicode="&#x2004;" horiz-adv-x="512" />
<glyph unicode="&#x2005;" horiz-adv-x="384" />
<glyph unicode="&#x2006;" horiz-adv-x="256" />
<glyph unicode="&#x2007;" horiz-adv-x="256" />
<glyph unicode="&#x2008;" horiz-adv-x="192" />
<glyph unicode="&#x2009;" horiz-adv-x="307" />
<glyph unicode="&#x200a;" horiz-adv-x="85" />
<glyph unicode="&#x202f;" horiz-adv-x="307" />
<glyph unicode="&#x205f;" horiz-adv-x="384" />
<glyph unicode="&#x2122;" horiz-adv-x="1792" />
<glyph unicode="&#x221e;" horiz-adv-x="1792" />
<glyph unicode="&#x2260;" horiz-adv-x="1792" />
<glyph unicode="&#xe000;" horiz-adv-x="500" d="M0 0z" />
<glyph unicode="&#xf000;" horiz-adv-x="1792" d="M1699 1350q0 -35 -43 -78l-632 -632v-768h320q26 0 45 -19t19 -45t-19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45t45 19h320v768l-632 632q-43 43 -43 78q0 23 18 36.5t38 17.5t43 4h1408q23 0 43 -4t38 -17.5t18 -36.5z" />
<glyph unicode="&#xf001;" d="M1536 1312v-1120q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89t34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v537l-768 -237v-709q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89 t34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v967q0 31 19 56.5t49 35.5l832 256q12 4 28 4q40 0 68 -28t28 -68z" />
<glyph unicode="&#xf002;" horiz-adv-x="1664" d="M1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1664 -128q0 -52 -38 -90t-90 -38q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5 t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z" />
<glyph unicode="&#xf003;" horiz-adv-x="1792" d="M1664 32v768q-32 -36 -69 -66q-268 -206 -426 -338q-51 -43 -83 -67t-86.5 -48.5t-102.5 -24.5h-1h-1q-48 0 -102.5 24.5t-86.5 48.5t-83 67q-158 132 -426 338q-37 30 -69 66v-768q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1664 1083v11v13.5t-0.5 13 t-3 12.5t-5.5 9t-9 7.5t-14 2.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5q0 -168 147 -284q193 -152 401 -317q6 -5 35 -29.5t46 -37.5t44.5 -31.5t50.5 -27.5t43 -9h1h1q20 0 43 9t50.5 27.5t44.5 31.5t46 37.5t35 29.5q208 165 401 317q54 43 100.5 115.5t46.5 131.5z M1792 1120v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" />
<glyph unicode="&#xf004;" horiz-adv-x="1792" d="M896 -128q-26 0 -44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5q224 0 351 -124t127 -344q0 -221 -229 -450l-623 -600 q-18 -18 -44 -18z" />
<glyph unicode="&#xf005;" horiz-adv-x="1664" d="M1664 889q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -21 -10.5 -35.5t-30.5 -14.5q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455 l502 -73q56 -9 56 -46z" />
<glyph unicode="&#xf006;" horiz-adv-x="1664" d="M1137 532l306 297l-422 62l-189 382l-189 -382l-422 -62l306 -297l-73 -421l378 199l377 -199zM1664 889q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -50 -41 -50q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500 l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455l502 -73q56 -9 56 -46z" />
<glyph unicode="&#xf007;" horiz-adv-x="1408" d="M1408 131q0 -120 -73 -189.5t-194 -69.5h-874q-121 0 -194 69.5t-73 189.5q0 53 3.5 103.5t14 109t26.5 108.5t43 97.5t62 81t85.5 53.5t111.5 20q9 0 42 -21.5t74.5 -48t108 -48t133.5 -21.5t133.5 21.5t108 48t74.5 48t42 21.5q61 0 111.5 -20t85.5 -53.5t62 -81 t43 -97.5t26.5 -108.5t14 -109t3.5 -103.5zM1088 1024q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5z" />
<glyph unicode="&#xf008;" horiz-adv-x="1920" d="M384 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 320v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 704v128q0 26 -19 45t-45 19h-128 q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 -64v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM384 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45 t45 -19h128q26 0 45 19t19 45zM1792 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 704v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM1792 320v128 q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1792 704v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1792 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19 t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1920 1248v-1344q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1344q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
<glyph unicode="&#xf009;" horiz-adv-x="1664" d="M768 512v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM768 1280v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM1664 512v-384q0 -52 -38 -90t-90 -38 h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM1664 1280v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90z" />
<glyph unicode="&#xf00a;" horiz-adv-x="1792" d="M512 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 288v-192q0 -40 -28 -68t-68 -28h-320 q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28 h320q40 0 68 -28t28 -68zM1792 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 800v-192 q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68z" />
<glyph unicode="&#xf00b;" horiz-adv-x="1792" d="M512 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 288v-192q0 -40 -28 -68t-68 -28h-960 q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68zM512 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 800v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28 h960q40 0 68 -28t28 -68zM1792 1312v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68z" />
<glyph unicode="&#xf00c;" horiz-adv-x="1792" d="M1671 970q0 -40 -28 -68l-724 -724l-136 -136q-28 -28 -68 -28t-68 28l-136 136l-362 362q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -295l656 657q28 28 68 28t68 -28l136 -136q28 -28 28 -68z" />
<glyph unicode="&#xf00d;" horiz-adv-x="1408" d="M1298 214q0 -40 -28 -68l-136 -136q-28 -28 -68 -28t-68 28l-294 294l-294 -294q-28 -28 -68 -28t-68 28l-136 136q-28 28 -28 68t28 68l294 294l-294 294q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -294l294 294q28 28 68 28t68 -28l136 -136q28 -28 28 -68 t-28 -68l-294 -294l294 -294q28 -28 28 -68z" />
<glyph unicode="&#xf00e;" horiz-adv-x="1664" d="M1024 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-224q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v224h-224q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h224v224q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-224h224 q13 0 22.5 -9.5t9.5 -22.5zM1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1664 -128q0 -53 -37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5 t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z" />
<glyph unicode="&#xf010;" horiz-adv-x="1664" d="M1024 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-576q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h576q13 0 22.5 -9.5t9.5 -22.5zM1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5z M1664 -128q0 -53 -37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z " />
<glyph unicode="&#xf011;" d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61t-298 61t-245 164t-164 245t-61 298q0 182 80.5 343t226.5 270q43 32 95.5 25t83.5 -50q32 -42 24.5 -94.5t-49.5 -84.5q-98 -74 -151.5 -181t-53.5 -228q0 -104 40.5 -198.5t109.5 -163.5t163.5 -109.5 t198.5 -40.5t198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5q0 121 -53.5 228t-151.5 181q-42 32 -49.5 84.5t24.5 94.5q31 43 84 50t95 -25q146 -109 226.5 -270t80.5 -343zM896 1408v-640q0 -52 -38 -90t-90 -38t-90 38t-38 90v640q0 52 38 90t90 38t90 -38t38 -90z" />
<glyph unicode="&#xf012;" horiz-adv-x="1792" d="M256 96v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM640 224v-320q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v320q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1024 480v-576q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23 v576q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1408 864v-960q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 1376v-1472q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v1472q0 14 9 23t23 9h192q14 0 23 -9t9 -23z" />
<glyph unicode="&#xf013;" d="M1024 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1536 749v-222q0 -12 -8 -23t-20 -13l-185 -28q-19 -54 -39 -91q35 -50 107 -138q10 -12 10 -25t-9 -23q-27 -37 -99 -108t-94 -71q-12 0 -26 9l-138 108q-44 -23 -91 -38 q-16 -136 -29 -186q-7 -28 -36 -28h-222q-14 0 -24.5 8.5t-11.5 21.5l-28 184q-49 16 -90 37l-141 -107q-10 -9 -25 -9q-14 0 -25 11q-126 114 -165 168q-7 10 -7 23q0 12 8 23q15 21 51 66.5t54 70.5q-27 50 -41 99l-183 27q-13 2 -21 12.5t-8 23.5v222q0 12 8 23t19 13 l186 28q14 46 39 92q-40 57 -107 138q-10 12 -10 24q0 10 9 23q26 36 98.5 107.5t94.5 71.5q13 0 26 -10l138 -107q44 23 91 38q16 136 29 186q7 28 36 28h222q14 0 24.5 -8.5t11.5 -21.5l28 -184q49 -16 90 -37l142 107q9 9 24 9q13 0 25 -10q129 -119 165 -170q7 -8 7 -22 q0 -12 -8 -23q-15 -21 -51 -66.5t-54 -70.5q26 -50 41 -98l183 -28q13 -2 21 -12.5t8 -23.5z" />
<glyph unicode="&#xf014;" horiz-adv-x="1408" d="M512 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM768 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1024 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576 q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1152 76v948h-896v-948q0 -22 7 -40.5t14.5 -27t10.5 -8.5h832q3 0 10.5 8.5t14.5 27t7 40.5zM480 1152h448l-48 117q-7 9 -17 11h-317q-10 -2 -17 -11zM1408 1120v-64q0 -14 -9 -23t-23 -9h-96v-948q0 -83 -47 -143.5t-113 -60.5h-832 q-66 0 -113 58.5t-47 141.5v952h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h309l70 167q15 37 54 63t79 26h320q40 0 79 -26t54 -63l70 -167h309q14 0 23 -9t9 -23z" />
<glyph unicode="&#xf015;" horiz-adv-x="1664" d="M1408 544v-480q0 -26 -19 -45t-45 -19h-384v384h-256v-384h-384q-26 0 -45 19t-19 45v480q0 1 0.5 3t0.5 3l575 474l575 -474q1 -2 1 -6zM1631 613l-62 -74q-8 -9 -21 -11h-3q-13 0 -21 7l-692 577l-692 -577q-12 -8 -24 -7q-13 2 -21 11l-62 74q-8 10 -7 23.5t11 21.5 l719 599q32 26 76 26t76 -26l244 -204v195q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-408l219 -182q10 -8 11 -21.5t-7 -23.5z" />
<glyph unicode="&#xf016;" horiz-adv-x="1280" d="M128 0h1024v768h-416q-40 0 -68 28t-28 68v416h-512v-1280zM768 896h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376zM1280 864v-896q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h640q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88z " />
<glyph unicode="&#xf017;" d="M896 992v-448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
<glyph unicode="&#xf018;" horiz-adv-x="1920" d="M1111 540v4l-24 320q-1 13 -11 22.5t-23 9.5h-186q-13 0 -23 -9.5t-11 -22.5l-24 -320v-4q-1 -12 8 -20t21 -8h244q12 0 21 8t8 20zM1870 73q0 -73 -46 -73h-704q13 0 22 9.5t8 22.5l-20 256q-1 13 -11 22.5t-23 9.5h-272q-13 0 -23 -9.5t-11 -22.5l-20 -256 q-1 -13 8 -22.5t22 -9.5h-704q-46 0 -46 73q0 54 26 116l417 1044q8 19 26 33t38 14h339q-13 0 -23 -9.5t-11 -22.5l-15 -192q-1 -14 8 -23t22 -9h166q13 0 22 9t8 23l-15 192q-1 13 -11 22.5t-23 9.5h339q20 0 38 -14t26 -33l417 -1044q26 -62 26 -116z" />
<glyph unicode="&#xf019;" horiz-adv-x="1664" d="M1280 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 416v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h465l135 -136 q58 -56 136 -56t136 56l136 136h464q40 0 68 -28t28 -68zM1339 985q17 -41 -14 -70l-448 -448q-18 -19 -45 -19t-45 19l-448 448q-31 29 -14 70q17 39 59 39h256v448q0 26 19 45t45 19h256q26 0 45 -19t19 -45v-448h256q42 0 59 -39z" />
<glyph unicode="&#xf01a;" d="M1120 608q0 -12 -10 -24l-319 -319q-11 -9 -23 -9t-23 9l-320 320q-15 16 -7 35q8 20 30 20h192v352q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-352h192q14 0 23 -9t9 -23zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273 t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
<glyph unicode="&#xf01b;" d="M1118 660q-8 -20 -30 -20h-192v-352q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v352h-192q-14 0 -23 9t-9 23q0 12 10 24l319 319q11 9 23 9t23 -9l320 -320q15 -16 7 -35zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198 t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
<glyph unicode="&#xf01c;" d="M1023 576h316q-1 3 -2.5 8t-2.5 8l-212 496h-708l-212 -496q-1 -2 -2.5 -8t-2.5 -8h316l95 -192h320zM1536 546v-482q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v482q0 62 25 123l238 552q10 25 36.5 42t52.5 17h832q26 0 52.5 -17t36.5 -42l238 -552 q25 -61 25 -123z" />
<glyph unicode="&#xf01d;" d="M1184 640q0 -37 -32 -55l-544 -320q-15 -9 -32 -9q-16 0 -32 8q-32 19 -32 56v640q0 37 32 56q33 18 64 -1l544 -320q32 -18 32 -55zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
<glyph unicode="&#xf01e;" d="M1536 1280v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l138 138q-148 137 -349 137q-104 0 -198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5q119 0 225 52t179 147q7 10 23 12q14 0 25 -9 l137 -138q9 -8 9.5 -20.5t-7.5 -22.5q-109 -132 -264 -204.5t-327 -72.5q-156 0 -298 61t-245 164t-164 245t-61 298t61 298t164 245t245 164t298 61q147 0 284.5 -55.5t244.5 -156.5l130 129q29 31 70 14q39 -17 39 -59z" />
<glyph unicode="&#xf021;" d="M1511 480q0 -5 -1 -7q-64 -268 -268 -434.5t-478 -166.5q-146 0 -282.5 55t-243.5 157l-129 -129q-19 -19 -45 -19t-45 19t-19 45v448q0 26 19 45t45 19h448q26 0 45 -19t19 -45t-19 -45l-137 -137q71 -66 161 -102t187 -36q134 0 250 65t186 179q11 17 53 117 q8 23 30 23h192q13 0 22.5 -9.5t9.5 -22.5zM1536 1280v-448q0 -26 -19 -45t-45 -19h-448q-26 0 -45 19t-19 45t19 45l138 138q-148 137 -349 137q-134 0 -250 -65t-186 -179q-11 -17 -53 -117q-8 -23 -30 -23h-199q-13 0 -22.5 9.5t-9.5 22.5v7q65 268 270 434.5t480 166.5 q146 0 284 -55.5t245 -156.5l130 129q19 19 45 19t45 -19t19 -45z" />
<glyph unicode="&#xf022;" horiz-adv-x="1792" d="M384 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M384 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1536 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5z M1536 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5zM1536 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5 t9.5 -22.5zM1664 160v832q0 13 -9.5 22.5t-22.5 9.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5v-832q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1792 1248v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47 t47 -113z" />
<glyph unicode="&#xf023;" horiz-adv-x="1152" d="M320 768h512v192q0 106 -75 181t-181 75t-181 -75t-75 -181v-192zM1152 672v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h32v192q0 184 132 316t316 132t316 -132t132 -316v-192h32q40 0 68 -28t28 -68z" />
<glyph unicode="&#xf024;" horiz-adv-x="1792" d="M320 1280q0 -72 -64 -110v-1266q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v1266q-64 38 -64 110q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -25 -12.5 -38.5t-39.5 -27.5q-215 -116 -369 -116q-61 0 -123.5 22t-108.5 48 t-115.5 48t-142.5 22q-192 0 -464 -146q-17 -9 -33 -9q-26 0 -45 19t-19 45v742q0 32 31 55q21 14 79 43q236 120 421 120q107 0 200 -29t219 -88q38 -19 88 -19q54 0 117.5 21t110 47t88 47t54.5 21q26 0 45 -19t19 -45z" />
<glyph unicode="&#xf025;" horiz-adv-x="1664" d="M1664 650q0 -166 -60 -314l-20 -49l-185 -33q-22 -83 -90.5 -136.5t-156.5 -53.5v-32q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-32q71 0 130 -35.5t93 -95.5l68 12q29 95 29 193q0 148 -88 279t-236.5 209t-315.5 78 t-315.5 -78t-236.5 -209t-88 -279q0 -98 29 -193l68 -12q34 60 93 95.5t130 35.5v32q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v32q-88 0 -156.5 53.5t-90.5 136.5l-185 33l-20 49q-60 148 -60 314q0 151 67 291t179 242.5 t266 163.5t320 61t320 -61t266 -163.5t179 -242.5t67 -291z" />
<glyph unicode="&#xf026;" horiz-adv-x="768" d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45z" />
<glyph unicode="&#xf027;" horiz-adv-x="1152" d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45zM1152 640q0 -76 -42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5q0 21 12 35.5t29 25t34 23t29 35.5 t12 57t-12 57t-29 35.5t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5q15 0 25 -5q70 -27 112.5 -93t42.5 -142z" />
<glyph unicode="&#xf028;" horiz-adv-x="1664" d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45zM1152 640q0 -76 -42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5q0 21 12 35.5t29 25t34 23t29 35.5 t12 57t-12 57t-29 35.5t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5q15 0 25 -5q70 -27 112.5 -93t42.5 -142zM1408 640q0 -153 -85 -282.5t-225 -188.5q-13 -5 -25 -5q-27 0 -46 19t-19 45q0 39 39 59q56 29 76 44q74 54 115.5 135.5t41.5 173.5t-41.5 173.5 t-115.5 135.5q-20 15 -76 44q-39 20 -39 59q0 26 19 45t45 19q13 0 26 -5q140 -59 225 -188.5t85 -282.5zM1664 640q0 -230 -127 -422.5t-338 -283.5q-13 -5 -26 -5q-26 0 -45 19t-19 45q0 36 39 59q7 4 22.5 10.5t22.5 10.5q46 25 82 51q123 91 192 227t69 289t-69 289 t-192 227q-36 26 -82 51q-7 4 -22.5 10.5t-22.5 10.5q-39 23 -39 59q0 26 19 45t45 19q13 0 26 -5q211 -91 338 -283.5t127 -422.5z" />
<glyph unicode="&#xf029;" horiz-adv-x="1408" d="M384 384v-128h-128v128h128zM384 1152v-128h-128v128h128zM1152 1152v-128h-128v128h128zM128 129h384v383h-384v-383zM128 896h384v384h-384v-384zM896 896h384v384h-384v-384zM640 640v-640h-640v640h640zM1152 128v-128h-128v128h128zM1408 128v-128h-128v128h128z M1408 640v-384h-384v128h-128v-384h-128v640h384v-128h128v128h128zM640 1408v-640h-640v640h640zM1408 1408v-640h-640v640h640z" />
<glyph unicode="&#xf02a;" horiz-adv-x="1792" d="M63 0h-63v1408h63v-1408zM126 1h-32v1407h32v-1407zM220 1h-31v1407h31v-1407zM377 1h-31v1407h31v-1407zM534 1h-62v1407h62v-1407zM660 1h-31v1407h31v-1407zM723 1h-31v1407h31v-1407zM786 1h-31v1407h31v-1407zM943 1h-63v1407h63v-1407zM1100 1h-63v1407h63v-1407z M1226 1h-63v1407h63v-1407zM1352 1h-63v1407h63v-1407zM1446 1h-63v1407h63v-1407zM1635 1h-94v1407h94v-1407zM1698 1h-32v1407h32v-1407zM1792 0h-63v1408h63v-1408z" />
<glyph unicode="&#xf02b;" d="M448 1088q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1515 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5 l715 -714q37 -39 37 -91z" />
<glyph unicode="&#xf02c;" horiz-adv-x="1920" d="M448 1088q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1515 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5 l715 -714q37 -39 37 -91zM1899 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-36 0 -59 14t-53 45l470 470q37 37 37 90q0 52 -37 91l-715 714q-38 38 -102 64.5t-117 26.5h224q53 0 117 -26.5t102 -64.5l715 -714q37 -39 37 -91z" />
<glyph unicode="&#xf02d;" horiz-adv-x="1664" d="M1639 1058q40 -57 18 -129l-275 -906q-19 -64 -76.5 -107.5t-122.5 -43.5h-923q-77 0 -148.5 53.5t-99.5 131.5q-24 67 -2 127q0 4 3 27t4 37q1 8 -3 21.5t-3 19.5q2 11 8 21t16.5 23.5t16.5 23.5q23 38 45 91.5t30 91.5q3 10 0.5 30t-0.5 28q3 11 17 28t17 23 q21 36 42 92t25 90q1 9 -2.5 32t0.5 28q4 13 22 30.5t22 22.5q19 26 42.5 84.5t27.5 96.5q1 8 -3 25.5t-2 26.5q2 8 9 18t18 23t17 21q8 12 16.5 30.5t15 35t16 36t19.5 32t26.5 23.5t36 11.5t47.5 -5.5l-1 -3q38 9 51 9h761q74 0 114 -56t18 -130l-274 -906 q-36 -119 -71.5 -153.5t-128.5 -34.5h-869q-27 0 -38 -15q-11 -16 -1 -43q24 -70 144 -70h923q29 0 56 15.5t35 41.5l300 987q7 22 5 57q38 -15 59 -43zM575 1056q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5 t-16.5 -22.5zM492 800q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5t-16.5 -22.5z" />
<glyph unicode="&#xf02e;" horiz-adv-x="1280" d="M1164 1408q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62v1289q0 34 19.5 62t52.5 41q21 9 44 9h1048z" />
<glyph unicode="&#xf02f;" horiz-adv-x="1664" d="M384 0h896v256h-896v-256zM384 640h896v384h-160q-40 0 -68 28t-28 68v160h-640v-640zM1536 576q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 576v-416q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-160q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68 v160h-224q-13 0 -22.5 9.5t-9.5 22.5v416q0 79 56.5 135.5t135.5 56.5h64v544q0 40 28 68t68 28h672q40 0 88 -20t76 -48l152 -152q28 -28 48 -76t20 -88v-256h64q79 0 135.5 -56.5t56.5 -135.5z" />
<glyph unicode="&#xf030;" horiz-adv-x="1920" d="M960 864q119 0 203.5 -84.5t84.5 -203.5t-84.5 -203.5t-203.5 -84.5t-203.5 84.5t-84.5 203.5t84.5 203.5t203.5 84.5zM1664 1280q106 0 181 -75t75 -181v-896q0 -106 -75 -181t-181 -75h-1408q-106 0 -181 75t-75 181v896q0 106 75 181t181 75h224l51 136 q19 49 69.5 84.5t103.5 35.5h512q53 0 103.5 -35.5t69.5 -84.5l51 -136h224zM960 128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
<glyph unicode="&#xf031;" horiz-adv-x="1664" d="M725 977l-170 -450q73 -1 153.5 -2t119 -1.5t52.5 -0.5l29 2q-32 95 -92 241q-53 132 -92 211zM21 -128h-21l2 79q22 7 80 18q89 16 110 31q20 16 48 68l237 616l280 724h75h53l11 -21l205 -480q103 -242 124 -297q39 -102 96 -235q26 -58 65 -164q24 -67 65 -149 q22 -49 35 -57q22 -19 69 -23q47 -6 103 -27q6 -39 6 -57q0 -14 -1 -26q-80 0 -192 8q-93 8 -189 8q-79 0 -135 -2l-200 -11l-58 -2q0 45 4 78l131 28q56 13 68 23q12 12 12 27t-6 32l-47 114l-92 228l-450 2q-29 -65 -104 -274q-23 -64 -23 -84q0 -31 17 -43 q26 -21 103 -32q3 0 13.5 -2t30 -5t40.5 -6q1 -28 1 -58q0 -17 -2 -27q-66 0 -349 20l-48 -8q-81 -14 -167 -14z" />
<glyph unicode="&#xf032;" horiz-adv-x="1408" d="M555 15q76 -32 140 -32q131 0 216 41t122 113q38 70 38 181q0 114 -41 180q-58 94 -141 126q-80 32 -247 32q-74 0 -101 -10v-144l-1 -173l3 -270q0 -15 12 -44zM541 761q43 -7 109 -7q175 0 264 65t89 224q0 112 -85 187q-84 75 -255 75q-52 0 -130 -13q0 -44 2 -77 q7 -122 6 -279l-1 -98q0 -43 1 -77zM0 -128l2 94q45 9 68 12q77 12 123 31q17 27 21 51q9 66 9 194l-2 497q-5 256 -9 404q-1 87 -11 109q-1 4 -12 12q-18 12 -69 15q-30 2 -114 13l-4 83l260 6l380 13l45 1q5 0 14 0.5t14 0.5q1 0 21.5 -0.5t40.5 -0.5h74q88 0 191 -27 q43 -13 96 -39q57 -29 102 -76q44 -47 65 -104t21 -122q0 -70 -32 -128t-95 -105q-26 -20 -150 -77q177 -41 267 -146q92 -106 92 -236q0 -76 -29 -161q-21 -62 -71 -117q-66 -72 -140 -108q-73 -36 -203 -60q-82 -15 -198 -11l-197 4q-84 2 -298 -11q-33 -3 -272 -11z" />
<glyph unicode="&#xf033;" horiz-adv-x="1024" d="M0 -126l17 85q4 1 77 20q76 19 116 39q29 37 41 101l27 139l56 268l12 64q8 44 17 84.5t16 67t12.5 46.5t9 30.5t3.5 11.5l29 157l16 63l22 135l8 50v38q-41 22 -144 28q-28 2 -38 4l19 103l317 -14q39 -2 73 -2q66 0 214 9q33 2 68 4.5t36 2.5q-2 -19 -6 -38 q-7 -29 -13 -51q-55 -19 -109 -31q-64 -16 -101 -31q-12 -31 -24 -88q-9 -44 -13 -82q-44 -199 -66 -306l-61 -311l-38 -158l-43 -235l-12 -45q-2 -7 1 -27q64 -15 119 -21q36 -5 66 -10q-1 -29 -7 -58q-7 -31 -9 -41q-18 0 -23 -1q-24 -2 -42 -2q-9 0 -28 3q-19 4 -145 17 l-198 2q-41 1 -174 -11q-74 -7 -98 -9z" />
<glyph unicode="&#xf034;" horiz-adv-x="1792" d="M81 1407l54 -27q20 -5 211 -5h130l19 3l115 1l215 -1h293l34 -2q14 -1 28 7t21 16l7 8l42 1q15 0 28 -1v-104.5t1 -131.5l1 -100l-1 -58q0 -32 -4 -51q-39 -15 -68 -18q-25 43 -54 128q-8 24 -15.5 62.5t-11.5 65.5t-6 29q-13 15 -27 19q-7 2 -42.5 2t-103.5 -1t-111 -1 q-34 0 -67 -5q-10 -97 -8 -136l1 -152v-332l3 -359l-1 -147q-1 -46 11 -85q49 -25 89 -32q2 0 18 -5t44 -13t43 -12q30 -8 50 -18q5 -45 5 -50q0 -10 -3 -29q-14 -1 -34 -1q-110 0 -187 10q-72 8 -238 8q-88 0 -233 -14q-48 -4 -70 -4q-2 22 -2 26l-1 26v9q21 33 79 49 q139 38 159 50q9 21 12 56q8 192 6 433l-5 428q-1 62 -0.5 118.5t0.5 102.5t-2 57t-6 15q-6 5 -14 6q-38 6 -148 6q-43 0 -100 -13.5t-73 -24.5q-13 -9 -22 -33t-22 -75t-24 -84q-6 -19 -19.5 -32t-20.5 -13q-44 27 -56 44v297v86zM1744 128q33 0 42 -18.5t-11 -44.5 l-126 -162q-20 -26 -49 -26t-49 26l-126 162q-20 26 -11 44.5t42 18.5h80v1024h-80q-33 0 -42 18.5t11 44.5l126 162q20 26 49 26t49 -26l126 -162q20 -26 11 -44.5t-42 -18.5h-80v-1024h80z" />
<glyph unicode="&#xf035;" d="M81 1407l54 -27q20 -5 211 -5h130l19 3l115 1l446 -1h318l34 -2q14 -1 28 7t21 16l7 8l42 1q15 0 28 -1v-104.5t1 -131.5l1 -100l-1 -58q0 -32 -4 -51q-39 -15 -68 -18q-25 43 -54 128q-8 24 -15.5 62.5t-11.5 65.5t-6 29q-13 15 -27 19q-7 2 -58.5 2t-138.5 -1t-128 -1 q-94 0 -127 -5q-10 -97 -8 -136l1 -152v52l3 -359l-1 -147q-1 -46 11 -85q49 -25 89 -32q2 0 18 -5t44 -13t43 -12q30 -8 50 -18q5 -45 5 -50q0 -10 -3 -29q-14 -1 -34 -1q-110 0 -187 10q-72 8 -238 8q-82 0 -233 -13q-45 -5 -70 -5q-2 22 -2 26l-1 26v9q21 33 79 49 q139 38 159 50q9 21 12 56q6 137 6 433l-5 44q0 265 -2 278q-2 11 -6 15q-6 5 -14 6q-38 6 -148 6q-50 0 -168.5 -14t-132.5 -24q-13 -9 -22 -33t-22 -75t-24 -84q-6 -19 -19.5 -32t-20.5 -13q-44 27 -56 44v297v86zM1505 113q26 -20 26 -49t-26 -49l-162 -126 q-26 -20 -44.5 -11t-18.5 42v80h-1024v-80q0 -33 -18.5 -42t-44.5 11l-162 126q-26 20 -26 49t26 49l162 126q26 20 44.5 11t18.5 -42v-80h1024v80q0 33 18.5 42t44.5 -11z" />
<glyph unicode="&#xf036;" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1408 576v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45zM1664 960v-128q0 -26 -19 -45 t-45 -19h-1536q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45zM1280 1344v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
<glyph unicode="&#xf037;" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1408 576v-128q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h896q26 0 45 -19t19 -45zM1664 960v-128q0 -26 -19 -45t-45 -19 h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1280 1344v-128q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h640q26 0 45 -19t19 -45z" />
<glyph unicode="&#xf038;" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 576v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45zM1792 960v-128q0 -26 -19 -45 t-45 -19h-1536q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45zM1792 1344v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
<glyph unicode="&#xf039;" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 576v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 960v-128q0 -26 -19 -45 t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 1344v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45z" />
<glyph unicode="&#xf03a;" horiz-adv-x="1792" d="M256 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM256 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5 t9.5 -22.5zM256 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344 q13 0 22.5 -9.5t9.5 -22.5zM256 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5 t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192 q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5z" />
<glyph unicode="&#xf03b;" horiz-adv-x="1792" d="M384 992v-576q0 -13 -9.5 -22.5t-22.5 -9.5q-14 0 -23 9l-288 288q-9 9 -9 23t9 23l288 288q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5 t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088 q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5z" />
<glyph unicode="&#xf03c;" horiz-adv-x="1792" d="M352 704q0 -14 -9 -23l-288 -288q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v576q0 13 9.5 22.5t22.5 9.5q14 0 23 -9l288 -288q9 -9 9 -23zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5 t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088 q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5z" />
<glyph unicode="&#xf03d;" horiz-adv-x="1792" d="M1792 1184v-1088q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-403 403v-166q0 -119 -84.5 -203.5t-203.5 -84.5h-704q-119 0 -203.5 84.5t-84.5 203.5v704q0 119 84.5 203.5t203.5 84.5h704q119 0 203.5 -84.5t84.5 -203.5v-165l403 402q18 19 45 19q12 0 25 -5 q39 -17 39 -59z" />
<glyph unicode="&#xf03e;" horiz-adv-x="1920" d="M640 960q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1664 576v-448h-1408v192l320 320l160 -160l512 512zM1760 1280h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-1216q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5v1216 q0 13 -9.5 22.5t-22.5 9.5zM1920 1248v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
<glyph unicode="&#xf040;" d="M363 0l91 91l-235 235l-91 -91v-107h128v-128h107zM886 928q0 22 -22 22q-10 0 -17 -7l-542 -542q-7 -7 -7 -17q0 -22 22 -22q10 0 17 7l542 542q7 7 7 17zM832 1120l416 -416l-832 -832h-416v416zM1515 1024q0 -53 -37 -90l-166 -166l-416 416l166 165q36 38 90 38 q53 0 91 -38l235 -234q37 -39 37 -91z" />
<glyph unicode="&#xf041;" horiz-adv-x="1024" d="M768 896q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1024 896q0 -109 -33 -179l-364 -774q-16 -33 -47.5 -52t-67.5 -19t-67.5 19t-46.5 52l-365 774q-33 70 -33 179q0 212 150 362t362 150t362 -150t150 -362z" />
<glyph unicode="&#xf042;" d="M768 96v1088q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
<glyph unicode="&#xf043;" horiz-adv-x="1024" d="M512 384q0 36 -20 69q-1 1 -15.5 22.5t-25.5 38t-25 44t-21 50.5q-4 16 -21 16t-21 -16q-7 -23 -21 -50.5t-25 -44t-25.5 -38t-15.5 -22.5q-20 -33 -20 -69q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 512q0 -212 -150 -362t-362 -150t-362 150t-150 362 q0 145 81 275q6 9 62.5 90.5t101 151t99.5 178t83 201.5q9 30 34 47t51 17t51.5 -17t33.5 -47q28 -93 83 -201.5t99.5 -178t101 -151t62.5 -90.5q81 -127 81 -275z" />
<glyph unicode="&#xf044;" horiz-adv-x="1792" d="M888 352l116 116l-152 152l-116 -116v-56h96v-96h56zM1328 1072q-16 16 -33 -1l-350 -350q-17 -17 -1 -33t33 1l350 350q17 17 1 33zM1408 478v-190q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832 q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-14 -14 -32 -8q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v126q0 13 9 22l64 64q15 15 35 7t20 -29zM1312 1216l288 -288l-672 -672h-288v288zM1756 1084l-92 -92 l-288 288l92 92q28 28 68 28t68 -28l152 -152q28 -28 28 -68t-28 -68z" />
<glyph unicode="&#xf045;" horiz-adv-x="1664" d="M1408 547v-259q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h255v0q13 0 22.5 -9.5t9.5 -22.5q0 -27 -26 -32q-77 -26 -133 -60q-10 -4 -16 -4h-112q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832 q66 0 113 47t47 113v214q0 19 18 29q28 13 54 37q16 16 35 8q21 -9 21 -29zM1645 1043l-384 -384q-18 -19 -45 -19q-12 0 -25 5q-39 17 -39 59v192h-160q-323 0 -438 -131q-119 -137 -74 -473q3 -23 -20 -34q-8 -2 -12 -2q-16 0 -26 13q-10 14 -21 31t-39.5 68.5t-49.5 99.5 t-38.5 114t-17.5 122q0 49 3.5 91t14 90t28 88t47 81.5t68.5 74t94.5 61.5t124.5 48.5t159.5 30.5t196.5 11h160v192q0 42 39 59q13 5 25 5q26 0 45 -19l384 -384q19 -19 19 -45t-19 -45z" />
<glyph unicode="&#xf046;" horiz-adv-x="1664" d="M1408 606v-318q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-10 -10 -23 -10q-3 0 -9 2q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832 q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v254q0 13 9 22l64 64q10 10 23 10q6 0 12 -3q20 -8 20 -29zM1639 1095l-814 -814q-24 -24 -57 -24t-57 24l-430 430q-24 24 -24 57t24 57l110 110q24 24 57 24t57 -24l263 -263l647 647q24 24 57 24t57 -24l110 -110 q24 -24 24 -57t-24 -57z" />
<glyph unicode="&#xf047;" horiz-adv-x="1792" d="M1792 640q0 -26 -19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-384v-384h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v384h-384v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45 t19 45l256 256q19 19 45 19t45 -19t19 -45v-128h384v384h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45t-19 -45t-45 -19h-128v-384h384v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45z" />
<glyph unicode="&#xf048;" horiz-adv-x="1024" d="M979 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 11 13 19z" />
<glyph unicode="&#xf049;" horiz-adv-x="1792" d="M1747 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 11 13 19l710 710 q19 19 32 13t13 -32v-710q4 11 13 19z" />
<glyph unicode="&#xf04a;" horiz-adv-x="1664" d="M1619 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-8 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-19 19 -19 45t19 45l710 710q19 19 32 13t13 -32v-710q5 11 13 19z" />
<glyph unicode="&#xf04b;" horiz-adv-x="1408" d="M1384 609l-1328 -738q-23 -13 -39.5 -3t-16.5 36v1472q0 26 16.5 36t39.5 -3l1328 -738q23 -13 23 -31t-23 -31z" />
<glyph unicode="&#xf04c;" d="M1536 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45zM640 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45z" />
<glyph unicode="&#xf04d;" d="M1536 1344v-1408q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" />
<glyph unicode="&#xf04e;" horiz-adv-x="1664" d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v710q0 26 13 32t32 -13l710 -710q19 -19 19 -45t-19 -45l-710 -710q-19 -19 -32 -13t-13 32v710q-5 -10 -13 -19z" />
<glyph unicode="&#xf050;" horiz-adv-x="1792" d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v710q0 26 13 32t32 -13l710 -710q8 -8 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-5 -10 -13 -19l-710 -710 q-19 -19 -32 -13t-13 32v710q-5 -10 -13 -19z" />
<glyph unicode="&#xf051;" horiz-adv-x="1024" d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-5 -10 -13 -19z" />
<glyph unicode="&#xf052;" horiz-adv-x="1538" d="M14 557l710 710q19 19 45 19t45 -19l710 -710q19 -19 13 -32t-32 -13h-1472q-26 0 -32 13t13 32zM1473 0h-1408q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19z" />
<glyph unicode="&#xf053;" horiz-adv-x="1152" d="M742 -37l-652 651q-37 37 -37 90.5t37 90.5l652 651q37 37 90.5 37t90.5 -37l75 -75q37 -37 37 -90.5t-37 -90.5l-486 -486l486 -485q37 -38 37 -91t-37 -90l-75 -75q-37 -37 -90.5 -37t-90.5 37z" />
<glyph unicode="&#xf054;" horiz-adv-x="1152" d="M1099 704q0 -52 -37 -91l-652 -651q-37 -37 -90 -37t-90 37l-76 75q-37 39 -37 91q0 53 37 90l486 486l-486 485q-37 39 -37 91q0 53 37 90l76 75q36 38 90 38t90 -38l652 -651q37 -37 37 -90z" />
<glyph unicode="&#xf055;" d="M1216 576v128q0 26 -19 45t-45 19h-256v256q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-256h-256q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h256v-256q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v256h256q26 0 45 19t19 45zM1536 640q0 -209 -103 -385.5 t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
<glyph unicode="&#xf056;" d="M1216 576v128q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5 t103 -385.5z" />
<glyph unicode="&#xf057;" d="M1149 414q0 26 -19 45l-181 181l181 181q19 19 19 45q0 27 -19 46l-90 90q-19 19 -46 19q-26 0 -45 -19l-181 -181l-181 181q-19 19 -45 19q-27 0 -46 -19l-90 -90q-19 -19 -19 -46q0 -26 19 -45l181 -181l-181 -181q-19 -19 -19 -45q0 -27 19 -46l90 -90q19 -19 46 -19 q26 0 45 19l181 181l181 -181q19 -19 45 -19q27 0 46 19l90 90q19 19 19 46zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
<glyph unicode="&#xf058;" d="M1284 802q0 28 -18 46l-91 90q-19 19 -45 19t-45 -19l-408 -407l-226 226q-19 19 -45 19t-45 -19l-91 -90q-18 -18 -18 -46q0 -27 18 -45l362 -362q19 -19 45 -19q27 0 46 19l543 543q18 18 18 45zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
<glyph unicode="&#xf059;" d="M896 160v192q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h192q14 0 23 9t9 23zM1152 832q0 88 -55.5 163t-138.5 116t-170 41q-243 0 -371 -213q-15 -24 8 -42l132 -100q7 -6 19 -6q16 0 25 12q53 68 86 92q34 24 86 24q48 0 85.5 -26t37.5 -59 q0 -38 -20 -61t-68 -45q-63 -28 -115.5 -86.5t-52.5 -125.5v-36q0 -14 9 -23t23 -9h192q14 0 23 9t9 23q0 19 21.5 49.5t54.5 49.5q32 18 49 28.5t46 35t44.5 48t28 60.5t12.5 81zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
<glyph unicode="&#xf05a;" d="M1024 160v160q0 14 -9 23t-23 9h-96v512q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h96v-320h-96q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h448q14 0 23 9t9 23zM896 1056v160q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23 t23 -9h192q14 0 23 9t9 23zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
<glyph unicode="&#xf05b;" d="M1197 512h-109q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h109q-32 108 -112.5 188.5t-188.5 112.5v-109q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v109q-108 -32 -188.5 -112.5t-112.5 -188.5h109q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-109 q32 -108 112.5 -188.5t188.5 -112.5v109q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-109q108 32 188.5 112.5t112.5 188.5zM1536 704v-128q0 -26 -19 -45t-45 -19h-143q-37 -161 -154.5 -278.5t-278.5 -154.5v-143q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v143 q-161 37 -278.5 154.5t-154.5 278.5h-143q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h143q37 161 154.5 278.5t278.5 154.5v143q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-143q161 -37 278.5 -154.5t154.5 -278.5h143q26 0 45 -19t19 -45z" />
<glyph unicode="&#xf05c;" d="M1097 457l-146 -146q-10 -10 -23 -10t-23 10l-137 137l-137 -137q-10 -10 -23 -10t-23 10l-146 146q-10 10 -10 23t10 23l137 137l-137 137q-10 10 -10 23t10 23l146 146q10 10 23 10t23 -10l137 -137l137 137q10 10 23 10t23 -10l146 -146q10 -10 10 -23t-10 -23 l-137 -137l137 -137q10 -10 10 -23t-10 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5 t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
<glyph unicode="&#xf05d;" d="M1171 723l-422 -422q-19 -19 -45 -19t-45 19l-294 294q-19 19 -19 45t19 45l102 102q19 19 45 19t45 -19l147 -147l275 275q19 19 45 19t45 -19l102 -102q19 -19 19 -45t-19 -45zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198 t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
<glyph unicode="&#xf05e;" d="M1312 643q0 161 -87 295l-754 -753q137 -89 297 -89q111 0 211.5 43.5t173.5 116.5t116 174.5t43 212.5zM313 344l755 754q-135 91 -300 91q-148 0 -273 -73t-198 -199t-73 -274q0 -162 89 -299zM1536 643q0 -157 -61 -300t-163.5 -246t-245 -164t-298.5 -61t-298.5 61 t-245 164t-163.5 246t-61 300t61 299.5t163.5 245.5t245 164t298.5 61t298.5 -61t245 -164t163.5 -245.5t61 -299.5z" />
<glyph unicode="&#xf060;" d="M1536 640v-128q0 -53 -32.5 -90.5t-84.5 -37.5h-704l293 -294q38 -36 38 -90t-38 -90l-75 -76q-37 -37 -90 -37q-52 0 -91 37l-651 652q-37 37 -37 90q0 52 37 91l651 650q38 38 91 38q52 0 90 -38l75 -74q38 -38 38 -91t-38 -91l-293 -293h704q52 0 84.5 -37.5 t32.5 -90.5z" />
<glyph unicode="&#xf061;" d="M1472 576q0 -54 -37 -91l-651 -651q-39 -37 -91 -37q-51 0 -90 37l-75 75q-38 38 -38 91t38 91l293 293h-704q-52 0 -84.5 37.5t-32.5 90.5v128q0 53 32.5 90.5t84.5 37.5h704l-293 294q-38 36 -38 90t38 90l75 75q38 38 90 38q53 0 91 -38l651 -651q37 -35 37 -90z" />
<glyph unicode="&#xf062;" horiz-adv-x="1664" d="M1611 565q0 -51 -37 -90l-75 -75q-38 -38 -91 -38q-54 0 -90 38l-294 293v-704q0 -52 -37.5 -84.5t-90.5 -32.5h-128q-53 0 -90.5 32.5t-37.5 84.5v704l-294 -293q-36 -38 -90 -38t-90 38l-75 75q-38 38 -38 90q0 53 38 91l651 651q35 37 90 37q54 0 91 -37l651 -651 q37 -39 37 -91z" />
<glyph unicode="&#xf063;" horiz-adv-x="1664" d="M1611 704q0 -53 -37 -90l-651 -652q-39 -37 -91 -37q-53 0 -90 37l-651 652q-38 36 -38 90q0 53 38 91l74 75q39 37 91 37q53 0 90 -37l294 -294v704q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-704l294 294q37 37 90 37q52 0 91 -37l75 -75q37 -39 37 -91z" />
<glyph unicode="&#xf064;" horiz-adv-x="1792" d="M1792 896q0 -26 -19 -45l-512 -512q-19 -19 -45 -19t-45 19t-19 45v256h-224q-98 0 -175.5 -6t-154 -21.5t-133 -42.5t-105.5 -69.5t-80 -101t-48.5 -138.5t-17.5 -181q0 -55 5 -123q0 -6 2.5 -23.5t2.5 -26.5q0 -15 -8.5 -25t-23.5 -10q-16 0 -28 17q-7 9 -13 22 t-13.5 30t-10.5 24q-127 285 -127 451q0 199 53 333q162 403 875 403h224v256q0 26 19 45t45 19t45 -19l512 -512q19 -19 19 -45z" />
<glyph unicode="&#xf065;" d="M755 480q0 -13 -10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45t-45 -19h-448q-26 0 -45 19t-19 45v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23zM1536 1344v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332 q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45z" />
<glyph unicode="&#xf066;" d="M768 576v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45zM1523 1248q0 -13 -10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45 t-45 -19h-448q-26 0 -45 19t-19 45v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23z" />
<glyph unicode="&#xf067;" horiz-adv-x="1408" d="M1408 800v-192q0 -40 -28 -68t-68 -28h-416v-416q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v416h-416q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h416v416q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-416h416q40 0 68 -28t28 -68z" />
<glyph unicode="&#xf068;" horiz-adv-x="1408" d="M1408 800v-192q0 -40 -28 -68t-68 -28h-1216q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h1216q40 0 68 -28t28 -68z" />
<glyph unicode="&#xf069;" horiz-adv-x="1664" d="M1482 486q46 -26 59.5 -77.5t-12.5 -97.5l-64 -110q-26 -46 -77.5 -59.5t-97.5 12.5l-266 153v-307q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v307l-266 -153q-46 -26 -97.5 -12.5t-77.5 59.5l-64 110q-26 46 -12.5 97.5t59.5 77.5l266 154l-266 154 q-46 26 -59.5 77.5t12.5 97.5l64 110q26 46 77.5 59.5t97.5 -12.5l266 -153v307q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-307l266 153q46 26 97.5 12.5t77.5 -59.5l64 -110q26 -46 12.5 -97.5t-59.5 -77.5l-266 -154z" />
<glyph unicode="&#xf06a;" d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM896 161v190q0 14 -9 23.5t-22 9.5h-192q-13 0 -23 -10t-10 -23v-190q0 -13 10 -23t23 -10h192 q13 0 22 9.5t9 23.5zM894 505l18 621q0 12 -10 18q-10 8 -24 8h-220q-14 0 -24 -8q-10 -6 -10 -18l17 -621q0 -10 10 -17.5t24 -7.5h185q14 0 23.5 7.5t10.5 17.5z" />
<glyph unicode="&#xf06b;" d="M928 180v56v468v192h-320v-192v-468v-56q0 -25 18 -38.5t46 -13.5h192q28 0 46 13.5t18 38.5zM472 1024h195l-126 161q-26 31 -69 31q-40 0 -68 -28t-28 -68t28 -68t68 -28zM1160 1120q0 40 -28 68t-68 28q-43 0 -69 -31l-125 -161h194q40 0 68 28t28 68zM1536 864v-320 q0 -14 -9 -23t-23 -9h-96v-416q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28t-28 68v416h-96q-14 0 -23 9t-9 23v320q0 14 9 23t23 9h440q-93 0 -158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5q107 0 168 -77l128 -165l128 165q61 77 168 77q93 0 158.5 -65.5t65.5 -158.5 t-65.5 -158.5t-158.5 -65.5h440q14 0 23 -9t9 -23z" />
<glyph unicode="&#xf06c;" horiz-adv-x="1792" d="M1280 832q0 26 -19 45t-45 19q-172 0 -318 -49.5t-259.5 -134t-235.5 -219.5q-19 -21 -19 -45q0 -26 19 -45t45 -19q24 0 45 19q27 24 74 71t67 66q137 124 268.5 176t313.5 52q26 0 45 19t19 45zM1792 1030q0 -95 -20 -193q-46 -224 -184.5 -383t-357.5 -268 q-214 -108 -438 -108q-148 0 -286 47q-15 5 -88 42t-96 37q-16 0 -39.5 -32t-45 -70t-52.5 -70t-60 -32q-30 0 -51 11t-31 24t-27 42q-2 4 -6 11t-5.5 10t-3 9.5t-1.5 13.5q0 35 31 73.5t68 65.5t68 56t31 48q0 4 -14 38t-16 44q-9 51 -9 104q0 115 43.5 220t119 184.5 t170.5 139t204 95.5q55 18 145 25.5t179.5 9t178.5 6t163.5 24t113.5 56.5l29.5 29.5t29.5 28t27 20t36.5 16t43.5 4.5q39 0 70.5 -46t47.5 -112t24 -124t8 -96z" />
<glyph unicode="&#xf06d;" horiz-adv-x="1408" d="M1408 -160v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1152 896q0 -78 -24.5 -144t-64 -112.5t-87.5 -88t-96 -77.5t-87.5 -72t-64 -81.5t-24.5 -96.5q0 -96 67 -224l-4 1l1 -1 q-90 41 -160 83t-138.5 100t-113.5 122.5t-72.5 150.5t-27.5 184q0 78 24.5 144t64 112.5t87.5 88t96 77.5t87.5 72t64 81.5t24.5 96.5q0 94 -66 224l3 -1l-1 1q90 -41 160 -83t138.5 -100t113.5 -122.5t72.5 -150.5t27.5 -184z" />
<glyph unicode="&#xf06e;" horiz-adv-x="1792" d="M1664 576q-152 236 -381 353q61 -104 61 -225q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 121 61 225q-229 -117 -381 -353q133 -205 333.5 -326.5t434.5 -121.5t434.5 121.5t333.5 326.5zM944 960q0 20 -14 34t-34 14q-125 0 -214.5 -89.5 t-89.5 -214.5q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34zM1792 576q0 -34 -20 -69q-140 -230 -376.5 -368.5t-499.5 -138.5t-499.5 139t-376.5 368q-20 35 -20 69t20 69q140 229 376.5 368t499.5 139t499.5 -139t376.5 -368q20 -35 20 -69z" />
<glyph unicode="&#xf070;" horiz-adv-x="1792" d="M555 201l78 141q-87 63 -136 159t-49 203q0 121 61 225q-229 -117 -381 -353q167 -258 427 -375zM944 960q0 20 -14 34t-34 14q-125 0 -214.5 -89.5t-89.5 -214.5q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34zM1307 1151q0 -7 -1 -9 q-105 -188 -315 -566t-316 -567l-49 -89q-10 -16 -28 -16q-12 0 -134 70q-16 10 -16 28q0 12 44 87q-143 65 -263.5 173t-208.5 245q-20 31 -20 69t20 69q153 235 380 371t496 136q89 0 180 -17l54 97q10 16 28 16q5 0 18 -6t31 -15.5t33 -18.5t31.5 -18.5t19.5 -11.5 q16 -10 16 -27zM1344 704q0 -139 -79 -253.5t-209 -164.5l280 502q8 -45 8 -84zM1792 576q0 -35 -20 -69q-39 -64 -109 -145q-150 -172 -347.5 -267t-419.5 -95l74 132q212 18 392.5 137t301.5 307q-115 179 -282 294l63 112q95 -64 182.5 -153t144.5 -184q20 -34 20 -69z " />
<glyph unicode="&#xf071;" horiz-adv-x="1792" d="M1024 161v190q0 14 -9.5 23.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -23.5v-190q0 -14 9.5 -23.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 23.5zM1022 535l18 459q0 12 -10 19q-13 11 -24 11h-220q-11 0 -24 -11q-10 -7 -10 -21l17 -457q0 -10 10 -16.5t24 -6.5h185 q14 0 23.5 6.5t10.5 16.5zM1008 1469l768 -1408q35 -63 -2 -126q-17 -29 -46.5 -46t-63.5 -17h-1536q-34 0 -63.5 17t-46.5 46q-37 63 -2 126l768 1408q17 31 47 49t65 18t65 -18t47 -49z" />
<glyph unicode="&#xf072;" horiz-adv-x="1408" d="M1376 1376q44 -52 12 -148t-108 -172l-161 -161l160 -696q5 -19 -12 -33l-128 -96q-7 -6 -19 -6q-4 0 -7 1q-15 3 -21 16l-279 508l-259 -259l53 -194q5 -17 -8 -31l-96 -96q-9 -9 -23 -9h-2q-15 2 -24 13l-189 252l-252 189q-11 7 -13 23q-1 13 9 25l96 97q9 9 23 9 q6 0 8 -1l194 -53l259 259l-508 279q-14 8 -17 24q-2 16 9 27l128 128q14 13 30 8l665 -159l160 160q76 76 172 108t148 -12z" />
<glyph unicode="&#xf073;" horiz-adv-x="1664" d="M128 -128h288v288h-288v-288zM480 -128h320v288h-320v-288zM128 224h288v320h-288v-320zM480 224h320v320h-320v-320zM128 608h288v288h-288v-288zM864 -128h320v288h-320v-288zM480 608h320v288h-320v-288zM1248 -128h288v288h-288v-288zM864 224h320v320h-320v-320z M512 1088v288q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-288q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1248 224h288v320h-288v-320zM864 608h320v288h-320v-288zM1248 608h288v288h-288v-288zM1280 1088v288q0 13 -9.5 22.5t-22.5 9.5h-64 q-13 0 -22.5 -9.5t-9.5 -22.5v-288q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1664 1152v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47 h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" />
<glyph unicode="&#xf074;" horiz-adv-x="1792" d="M666 1055q-60 -92 -137 -273q-22 45 -37 72.5t-40.5 63.5t-51 56.5t-63 35t-81.5 14.5h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224q250 0 410 -225zM1792 256q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192q-32 0 -85 -0.5t-81 -1t-73 1 t-71 5t-64 10.5t-63 18.5t-58 28.5t-59 40t-55 53.5t-56 69.5q59 93 136 273q22 -45 37 -72.5t40.5 -63.5t51 -56.5t63 -35t81.5 -14.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23zM1792 1152q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5 v192h-256q-48 0 -87 -15t-69 -45t-51 -61.5t-45 -77.5q-32 -62 -78 -171q-29 -66 -49.5 -111t-54 -105t-64 -100t-74 -83t-90 -68.5t-106.5 -42t-128 -16.5h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224q48 0 87 15t69 45t51 61.5t45 77.5q32 62 78 171q29 66 49.5 111 t54 105t64 100t74 83t90 68.5t106.5 42t128 16.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23z" />
<glyph unicode="&#xf075;" horiz-adv-x="1792" d="M1792 640q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22q-17 -2 -30.5 9t-17.5 29v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281 q0 130 71 248.5t191 204.5t286 136.5t348 50.5q244 0 450 -85.5t326 -233t120 -321.5z" />
<glyph unicode="&#xf076;" d="M1536 704v-128q0 -201 -98.5 -362t-274 -251.5t-395.5 -90.5t-395.5 90.5t-274 251.5t-98.5 362v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-128q0 -52 23.5 -90t53.5 -57t71 -30t64 -13t44 -2t44 2t64 13t71 30t53.5 57t23.5 90v128q0 26 19 45t45 19h384 q26 0 45 -19t19 -45zM512 1344v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45zM1536 1344v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45z" />
<glyph unicode="&#xf077;" horiz-adv-x="1664" d="M1611 320q0 -53 -37 -90l-75 -75q-38 -38 -91 -38q-54 0 -90 38l-486 485l-486 -485q-36 -38 -90 -38t-90 38l-75 75q-38 36 -38 90q0 53 38 91l651 651q37 37 90 37q52 0 91 -37l650 -651q38 -38 38 -91z" />
<glyph unicode="&#xf078;" horiz-adv-x="1664" d="M1611 832q0 -53 -37 -90l-651 -651q-38 -38 -91 -38q-54 0 -90 38l-651 651q-38 36 -38 90q0 53 38 91l74 75q39 37 91 37q53 0 90 -37l486 -486l486 486q37 37 90 37q52 0 91 -37l75 -75q37 -39 37 -91z" />
<glyph unicode="&#xf079;" horiz-adv-x="1920" d="M1280 32q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-8 0 -13.5 2t-9 7t-5.5 8t-3 11.5t-1 11.5v13v11v160v416h-192q-26 0 -45 19t-19 45q0 24 15 41l320 384q19 22 49 22t49 -22l320 -384q15 -17 15 -41q0 -26 -19 -45t-45 -19h-192v-384h576q16 0 25 -11l160 -192q7 -11 7 -21 zM1920 448q0 -24 -15 -41l-320 -384q-20 -23 -49 -23t-49 23l-320 384q-15 17 -15 41q0 26 19 45t45 19h192v384h-576q-16 0 -25 12l-160 192q-7 9 -7 20q0 13 9.5 22.5t22.5 9.5h960q8 0 13.5 -2t9 -7t5.5 -8t3 -11.5t1 -11.5v-13v-11v-160v-416h192q26 0 45 -19t19 -45z " />
<glyph unicode="&#xf07a;" horiz-adv-x="1664" d="M640 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1536 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1664 1088v-512q0 -24 -16 -42.5t-41 -21.5 l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5 t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45z" />
<glyph unicode="&#xf07b;" horiz-adv-x="1664" d="M1664 928v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158z" />
<glyph unicode="&#xf07c;" horiz-adv-x="1920" d="M1879 584q0 -31 -31 -66l-336 -396q-43 -51 -120.5 -86.5t-143.5 -35.5h-1088q-34 0 -60.5 13t-26.5 43q0 31 31 66l336 396q43 51 120.5 86.5t143.5 35.5h1088q34 0 60.5 -13t26.5 -43zM1536 928v-160h-832q-94 0 -197 -47.5t-164 -119.5l-337 -396l-5 -6q0 4 -0.5 12.5 t-0.5 12.5v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158z" />
<glyph unicode="&#xf07d;" horiz-adv-x="768" d="M704 1216q0 -26 -19 -45t-45 -19h-128v-1024h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v1024h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45z" />
<glyph unicode="&#xf07e;" horiz-adv-x="1792" d="M1792 640q0 -26 -19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-1024v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45t19 45l256 256q19 19 45 19t45 -19t19 -45v-128h1024v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45z" />
<glyph unicode="&#xf080;" horiz-adv-x="1920" d="M512 512v-384h-256v384h256zM896 1024v-896h-256v896h256zM1280 768v-640h-256v640h256zM1664 1152v-1024h-256v1024h256zM1792 32v1216q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-1216q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5z M1920 1248v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
<glyph unicode="&#xf081;" d="M1280 926q-56 -25 -121 -34q68 40 93 117q-65 -38 -134 -51q-61 66 -153 66q-87 0 -148.5 -61.5t-61.5 -148.5q0 -29 5 -48q-129 7 -242 65t-192 155q-29 -50 -29 -106q0 -114 91 -175q-47 1 -100 26v-2q0 -75 50 -133.5t123 -72.5q-29 -8 -51 -8q-13 0 -39 4 q21 -63 74.5 -104t121.5 -42q-116 -90 -261 -90q-26 0 -50 3q148 -94 322 -94q112 0 210 35.5t168 95t120.5 137t75 162t24.5 168.5q0 18 -1 27q63 45 105 109zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5 t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
<glyph unicode="&#xf082;" d="M1307 618l23 219h-198v109q0 49 15.5 68.5t71.5 19.5h110v219h-175q-152 0 -218 -72t-66 -213v-131h-131v-219h131v-635h262v635h175zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960 q119 0 203.5 -84.5t84.5 -203.5z" />
<glyph unicode="&#xf083;" horiz-adv-x="1792" d="M928 704q0 14 -9 23t-23 9q-66 0 -113 -47t-47 -113q0 -14 9 -23t23 -9t23 9t9 23q0 40 28 68t68 28q14 0 23 9t9 23zM1152 574q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM128 0h1536v128h-1536v-128zM1280 574q0 159 -112.5 271.5 t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM256 1216h384v128h-384v-128zM128 1024h1536v118v138h-828l-64 -128h-644v-128zM1792 1280v-1280q0 -53 -37.5 -90.5t-90.5 -37.5h-1536q-53 0 -90.5 37.5t-37.5 90.5v1280 q0 53 37.5 90.5t90.5 37.5h1536q53 0 90.5 -37.5t37.5 -90.5z" />
<glyph unicode="&#xf084;" horiz-adv-x="1792" d="M832 1024q0 80 -56 136t-136 56t-136 -56t-56 -136q0 -42 19 -83q-41 19 -83 19q-80 0 -136 -56t-56 -136t56 -136t136 -56t136 56t56 136q0 42 -19 83q41 -19 83 -19q80 0 136 56t56 136zM1683 320q0 -17 -49 -66t-66 -49q-9 0 -28.5 16t-36.5 33t-38.5 40t-24.5 26 l-96 -96l220 -220q28 -28 28 -68q0 -42 -39 -81t-81 -39q-40 0 -68 28l-671 671q-176 -131 -365 -131q-163 0 -265.5 102.5t-102.5 265.5q0 160 95 313t248 248t313 95q163 0 265.5 -102.5t102.5 -265.5q0 -189 -131 -365l355 -355l96 96q-3 3 -26 24.5t-40 38.5t-33 36.5 t-16 28.5q0 17 49 66t66 49q13 0 23 -10q6 -6 46 -44.5t82 -79.5t86.5 -86t73 -78t28.5 -41z" />
<glyph unicode="&#xf085;" horiz-adv-x="1920" d="M896 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1664 128q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 1152q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5 t90.5 37.5t37.5 90.5zM1280 731v-185q0 -10 -7 -19.5t-16 -10.5l-155 -24q-11 -35 -32 -76q34 -48 90 -115q7 -10 7 -20q0 -12 -7 -19q-23 -30 -82.5 -89.5t-78.5 -59.5q-11 0 -21 7l-115 90q-37 -19 -77 -31q-11 -108 -23 -155q-7 -24 -30 -24h-186q-11 0 -20 7.5t-10 17.5 l-23 153q-34 10 -75 31l-118 -89q-7 -7 -20 -7q-11 0 -21 8q-144 133 -144 160q0 9 7 19q10 14 41 53t47 61q-23 44 -35 82l-152 24q-10 1 -17 9.5t-7 19.5v185q0 10 7 19.5t16 10.5l155 24q11 35 32 76q-34 48 -90 115q-7 11 -7 20q0 12 7 20q22 30 82 89t79 59q11 0 21 -7 l115 -90q34 18 77 32q11 108 23 154q7 24 30 24h186q11 0 20 -7.5t10 -17.5l23 -153q34 -10 75 -31l118 89q8 7 20 7q11 0 21 -8q144 -133 144 -160q0 -9 -7 -19q-12 -16 -42 -54t-45 -60q23 -48 34 -82l152 -23q10 -2 17 -10.5t7 -19.5zM1920 198v-140q0 -16 -149 -31 q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20 t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31zM1920 1222v-140q0 -16 -149 -31q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68 q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70 q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31z" />
<glyph unicode="&#xf086;" horiz-adv-x="1792" d="M1408 768q0 -139 -94 -257t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224 q0 139 94 257t256.5 186.5t353.5 68.5t353.5 -68.5t256.5 -186.5t94 -257zM1792 512q0 -120 -71 -224.5t-195 -176.5q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22t-22 -7 q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132q58 -4 88 -4q161 0 309 45t264 129q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230z" />
<glyph unicode="&#xf087;" d="M256 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 768q0 51 -39 89.5t-89 38.5h-352q0 58 48 159.5t48 160.5q0 98 -32 145t-128 47q-26 -26 -38 -85t-30.5 -125.5t-59.5 -109.5q-22 -23 -77 -91q-4 -5 -23 -30t-31.5 -41t-34.5 -42.5 t-40 -44t-38.5 -35.5t-40 -27t-35.5 -9h-32v-640h32q13 0 31.5 -3t33 -6.5t38 -11t35 -11.5t35.5 -12.5t29 -10.5q211 -73 342 -73h121q192 0 192 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5q32 1 53.5 47t21.5 81zM1536 769 q0 -89 -49 -163q9 -33 9 -69q0 -77 -38 -144q3 -21 3 -43q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5h-36h-93q-96 0 -189.5 22.5t-216.5 65.5q-116 40 -138 40h-288q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5h274q36 24 137 155q58 75 107 128 q24 25 35.5 85.5t30.5 126.5t62 108q39 37 90 37q84 0 151 -32.5t102 -101.5t35 -186q0 -93 -48 -192h176q104 0 180 -76t76 -179z" />
<glyph unicode="&#xf088;" d="M256 1088q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 512q0 35 -21.5 81t-53.5 47q15 17 25 47.5t10 55.5q0 69 -53 119q18 32 18 69t-17.5 73.5t-47.5 52.5q5 30 5 56q0 85 -49 126t-136 41h-128q-131 0 -342 -73q-5 -2 -29 -10.5 t-35.5 -12.5t-35 -11.5t-38 -11t-33 -6.5t-31.5 -3h-32v-640h32q16 0 35.5 -9t40 -27t38.5 -35.5t40 -44t34.5 -42.5t31.5 -41t23 -30q55 -68 77 -91q41 -43 59.5 -109.5t30.5 -125.5t38 -85q96 0 128 47t32 145q0 59 -48 160.5t-48 159.5h352q50 0 89 38.5t39 89.5z M1536 511q0 -103 -76 -179t-180 -76h-176q48 -99 48 -192q0 -118 -35 -186q-35 -69 -102 -101.5t-151 -32.5q-51 0 -90 37q-34 33 -54 82t-25.5 90.5t-17.5 84.5t-31 64q-48 50 -107 127q-101 131 -137 155h-274q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5 h288q22 0 138 40q128 44 223 66t200 22h112q140 0 226.5 -79t85.5 -216v-5q60 -77 60 -178q0 -22 -3 -43q38 -67 38 -144q0 -36 -9 -69q49 -74 49 -163z" />
<glyph unicode="&#xf089;" horiz-adv-x="896" d="M832 1504v-1339l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41z" />
<glyph unicode="&#xf08a;" horiz-adv-x="1792" d="M1664 940q0 81 -21.5 143t-55 98.5t-81.5 59.5t-94 31t-98 8t-112 -25.5t-110.5 -64t-86.5 -72t-60 -61.5q-18 -22 -49 -22t-49 22q-24 28 -60 61.5t-86.5 72t-110.5 64t-112 25.5t-98 -8t-94 -31t-81.5 -59.5t-55 -98.5t-21.5 -143q0 -168 187 -355l581 -560l580 559 q188 188 188 356zM1792 940q0 -221 -229 -450l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5 q224 0 351 -124t127 -344z" />
<glyph unicode="&#xf08b;" horiz-adv-x="1664" d="M640 96q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-119 0 -203.5 84.5t-84.5 203.5v704q0 119 84.5 203.5t203.5 84.5h320q13 0 22.5 -9.5t9.5 -22.5q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-66 0 -113 -47t-47 -113v-704 q0 -66 47 -113t113 -47h288h11h13t11.5 -1t11.5 -3t8 -5.5t7 -9t2 -13.5zM1568 640q0 -26 -19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45z" />
<glyph unicode="&#xf08c;" d="M237 122h231v694h-231v-694zM483 1030q-1 52 -36 86t-93 34t-94.5 -34t-36.5 -86q0 -51 35.5 -85.5t92.5 -34.5h1q59 0 95 34.5t36 85.5zM1068 122h231v398q0 154 -73 233t-193 79q-136 0 -209 -117h2v101h-231q3 -66 0 -694h231v388q0 38 7 56q15 35 45 59.5t74 24.5 q116 0 116 -157v-371zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
<glyph unicode="&#xf08d;" horiz-adv-x="1152" d="M480 672v448q0 14 -9 23t-23 9t-23 -9t-9 -23v-448q0 -14 9 -23t23 -9t23 9t9 23zM1152 320q0 -26 -19 -45t-45 -19h-429l-51 -483q-2 -12 -10.5 -20.5t-20.5 -8.5h-1q-27 0 -32 27l-76 485h-404q-26 0 -45 19t-19 45q0 123 78.5 221.5t177.5 98.5v512q-52 0 -90 38 t-38 90t38 90t90 38h640q52 0 90 -38t38 -90t-38 -90t-90 -38v-512q99 0 177.5 -98.5t78.5 -221.5z" />
<glyph unicode="&#xf08e;" horiz-adv-x="1792" d="M1408 608v-320q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v320 q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1792 1472v-512q0 -26 -19 -45t-45 -19t-45 19l-176 176l-652 -652q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l652 652l-176 176q-19 19 -19 45t19 45t45 19h512q26 0 45 -19t19 -45z" />
<glyph unicode="&#xf090;" d="M1184 640q0 -26 -19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45zM1536 992v-704q0 -119 -84.5 -203.5t-203.5 -84.5h-320q-13 0 -22.5 9.5t-9.5 22.5 q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q66 0 113 47t47 113v704q0 66 -47 113t-113 47h-288h-11h-13t-11.5 1t-11.5 3t-8 5.5t-7 9t-2 13.5q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q119 0 203.5 -84.5t84.5 -203.5z" />
<glyph unicode="&#xf091;" horiz-adv-x="1664" d="M458 653q-74 162 -74 371h-256v-96q0 -78 94.5 -162t235.5 -113zM1536 928v96h-256q0 -209 -74 -371q141 29 235.5 113t94.5 162zM1664 1056v-128q0 -71 -41.5 -143t-112 -130t-173 -97.5t-215.5 -44.5q-42 -54 -95 -95q-38 -34 -52.5 -72.5t-14.5 -89.5q0 -54 30.5 -91 t97.5 -37q75 0 133.5 -45.5t58.5 -114.5v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 69 58.5 114.5t133.5 45.5q67 0 97.5 37t30.5 91q0 51 -14.5 89.5t-52.5 72.5q-53 41 -95 95q-113 5 -215.5 44.5t-173 97.5t-112 130t-41.5 143v128q0 40 28 68t68 28h288v96 q0 66 47 113t113 47h576q66 0 113 -47t47 -113v-96h288q40 0 68 -28t28 -68z" />
<glyph unicode="&#xf092;" d="M394 184q-8 -9 -20 3q-13 11 -4 19q8 9 20 -3q12 -11 4 -19zM352 245q9 -12 0 -19q-8 -6 -17 7t0 18q9 7 17 -6zM291 305q-5 -7 -13 -2q-10 5 -7 12q3 5 13 2q10 -5 7 -12zM322 271q-6 -7 -16 3q-9 11 -2 16q6 6 16 -3q9 -11 2 -16zM451 159q-4 -12 -19 -6q-17 4 -13 15 t19 7q16 -5 13 -16zM514 154q0 -11 -16 -11q-17 -2 -17 11q0 11 16 11q17 2 17 -11zM572 164q2 -10 -14 -14t-18 8t14 15q16 2 18 -9zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-224q-16 0 -24.5 1t-19.5 5t-16 14.5t-5 27.5v239q0 97 -52 142q57 6 102.5 18t94 39 t81 66.5t53 105t20.5 150.5q0 121 -79 206q37 91 -8 204q-28 9 -81 -11t-92 -44l-38 -24q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-86 13.5q-44 -113 -7 -204q-79 -85 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-40 -36 -49 -103 q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52t-49.5 24l-20 3q-21 0 -29 -4.5t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -103t0.5 -68q0 -22 -11 -33.5t-22 -13t-33 -1.5 h-224q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
<glyph unicode="&#xf093;" horiz-adv-x="1664" d="M1280 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 288v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h427q21 -56 70.5 -92 t110.5 -36h256q61 0 110.5 36t70.5 92h427q40 0 68 -28t28 -68zM1339 936q-17 -40 -59 -40h-256v-448q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v448h-256q-42 0 -59 40q-17 39 14 69l448 448q18 19 45 19t45 -19l448 -448q31 -30 14 -69z" />
<glyph unicode="&#xf094;" d="M1407 710q0 44 -7 113.5t-18 96.5q-12 30 -17 44t-9 36.5t-4 48.5q0 23 5 68.5t5 67.5q0 37 -10 55q-4 1 -13 1q-19 0 -58 -4.5t-59 -4.5q-60 0 -176 24t-175 24q-43 0 -94.5 -11.5t-85 -23.5t-89.5 -34q-137 -54 -202 -103q-96 -73 -159.5 -189.5t-88 -236t-24.5 -248.5 q0 -40 12.5 -120t12.5 -121q0 -23 -11 -66.5t-11 -65.5t12 -36.5t34 -14.5q24 0 72.5 11t73.5 11q57 0 169.5 -15.5t169.5 -15.5q181 0 284 36q129 45 235.5 152.5t166 245.5t59.5 275zM1535 712q0 -165 -70 -327.5t-196 -288t-281 -180.5q-124 -44 -326 -44 q-57 0 -170 14.5t-169 14.5q-24 0 -72.5 -14.5t-73.5 -14.5q-73 0 -123.5 55.5t-50.5 128.5q0 24 11 68t11 67q0 40 -12.5 120.5t-12.5 121.5q0 111 18 217.5t54.5 209.5t100.5 194t150 156q78 59 232 120q194 78 316 78q60 0 175.5 -24t173.5 -24q19 0 57 5t58 5 q81 0 118 -50.5t37 -134.5q0 -23 -5 -68t-5 -68q0 -10 1 -18.5t3 -17t4 -13.5t6.5 -16t6.5 -17q16 -40 25 -118.5t9 -136.5z" />
<glyph unicode="&#xf095;" horiz-adv-x="1408" d="M1408 296q0 -27 -10 -70.5t-21 -68.5q-21 -50 -122 -106q-94 -51 -186 -51q-27 0 -52.5 3.5t-57.5 12.5t-47.5 14.5t-55.5 20.5t-49 18q-98 35 -175 83q-128 79 -264.5 215.5t-215.5 264.5q-48 77 -83 175q-3 9 -18 49t-20.5 55.5t-14.5 47.5t-12.5 57.5t-3.5 52.5 q0 92 51 186q56 101 106 122q25 11 68.5 21t70.5 10q14 0 21 -3q18 -6 53 -76q11 -19 30 -54t35 -63.5t31 -53.5q3 -4 17.5 -25t21.5 -35.5t7 -28.5q0 -20 -28.5 -50t-62 -55t-62 -53t-28.5 -46q0 -9 5 -22.5t8.5 -20.5t14 -24t11.5 -19q76 -137 174 -235t235 -174 q2 -1 19 -11.5t24 -14t20.5 -8.5t22.5 -5q18 0 46 28.5t53 62t55 62t50 28.5q14 0 28.5 -7t35.5 -21.5t25 -17.5q25 -15 53.5 -31t63.5 -35t54 -30q70 -35 76 -53q3 -7 3 -21z" />
<glyph unicode="&#xf096;" horiz-adv-x="1408" d="M1120 1280h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v832q0 66 -47 113t-113 47zM1408 1120v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832 q119 0 203.5 -84.5t84.5 -203.5z" />
<glyph unicode="&#xf097;" horiz-adv-x="1280" d="M1152 1280h-1024v-1242l423 406l89 85l89 -85l423 -406v1242zM1164 1408q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62v1289 q0 34 19.5 62t52.5 41q21 9 44 9h1048z" />
<glyph unicode="&#xf098;" d="M1280 343q0 11 -2 16q-3 8 -38.5 29.5t-88.5 49.5l-53 29q-5 3 -19 13t-25 15t-21 5q-18 0 -47 -32.5t-57 -65.5t-44 -33q-7 0 -16.5 3.5t-15.5 6.5t-17 9.5t-14 8.5q-99 55 -170.5 126.5t-126.5 170.5q-2 3 -8.5 14t-9.5 17t-6.5 15.5t-3.5 16.5q0 13 20.5 33.5t45 38.5 t45 39.5t20.5 36.5q0 10 -5 21t-15 25t-13 19q-3 6 -15 28.5t-25 45.5t-26.5 47.5t-25 40.5t-16.5 18t-16 2q-48 0 -101 -22q-46 -21 -80 -94.5t-34 -130.5q0 -16 2.5 -34t5 -30.5t9 -33t10 -29.5t12.5 -33t11 -30q60 -164 216.5 -320.5t320.5 -216.5q6 -2 30 -11t33 -12.5 t29.5 -10t33 -9t30.5 -5t34 -2.5q57 0 130.5 34t94.5 80q22 53 22 101zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
<glyph unicode="&#xf099;" horiz-adv-x="1664" d="M1620 1128q-67 -98 -162 -167q1 -14 1 -42q0 -130 -38 -259.5t-115.5 -248.5t-184.5 -210.5t-258 -146t-323 -54.5q-271 0 -496 145q35 -4 78 -4q225 0 401 138q-105 2 -188 64.5t-114 159.5q33 -5 61 -5q43 0 85 11q-112 23 -185.5 111.5t-73.5 205.5v4q68 -38 146 -41 q-66 44 -105 115t-39 154q0 88 44 163q121 -149 294.5 -238.5t371.5 -99.5q-8 38 -8 74q0 134 94.5 228.5t228.5 94.5q140 0 236 -102q109 21 205 78q-37 -115 -142 -178q93 10 186 50z" />
<glyph unicode="&#xf09a;" horiz-adv-x="768" d="M511 980h257l-30 -284h-227v-824h-341v824h-170v284h170v171q0 182 86 275.5t283 93.5h227v-284h-142q-39 0 -62.5 -6.5t-34 -23.5t-13.5 -34.5t-3 -49.5v-142z" />
<glyph unicode="&#xf09b;" d="M1536 640q0 -251 -146.5 -451.5t-378.5 -277.5q-27 -5 -39.5 7t-12.5 30v211q0 97 -52 142q57 6 102.5 18t94 39t81 66.5t53 105t20.5 150.5q0 121 -79 206q37 91 -8 204q-28 9 -81 -11t-92 -44l-38 -24q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-86 13.5 q-44 -113 -7 -204q-79 -85 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-40 -36 -49 -103q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52t-49.5 24l-20 3q-21 0 -29 -4.5t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23 q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -89t0.5 -54q0 -18 -13 -30t-40 -7q-232 77 -378.5 277.5t-146.5 451.5q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
<glyph unicode="&#xf09c;" horiz-adv-x="1664" d="M1664 960v-256q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45v256q0 106 -75 181t-181 75t-181 -75t-75 -181v-192h96q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h672v192q0 185 131.5 316.5t316.5 131.5 t316.5 -131.5t131.5 -316.5z" />
<glyph unicode="&#xf09d;" horiz-adv-x="1920" d="M1760 1408q66 0 113 -47t47 -113v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600zM160 1280q-13 0 -22.5 -9.5t-9.5 -22.5v-224h1664v224q0 13 -9.5 22.5t-22.5 9.5h-1600zM1760 0q13 0 22.5 9.5t9.5 22.5v608h-1664v-608 q0 -13 9.5 -22.5t22.5 -9.5h1600zM256 128v128h256v-128h-256zM640 128v128h384v-128h-384z" />
<glyph unicode="&#xf09e;" horiz-adv-x="1408" d="M384 192q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 69q2 -28 -17 -48q-18 -21 -47 -21h-135q-25 0 -43 16.5t-20 41.5q-22 229 -184.5 391.5t-391.5 184.5q-25 2 -41.5 20t-16.5 43v135q0 29 21 47q17 17 43 17h5q160 -13 306 -80.5 t259 -181.5q114 -113 181.5 -259t80.5 -306zM1408 67q2 -27 -18 -47q-18 -20 -46 -20h-143q-26 0 -44.5 17.5t-19.5 42.5q-12 215 -101 408.5t-231.5 336t-336 231.5t-408.5 102q-25 1 -42.5 19.5t-17.5 43.5v143q0 28 20 46q18 18 44 18h3q262 -13 501.5 -120t425.5 -294 q187 -186 294 -425.5t120 -501.5z" />
<glyph unicode="&#xf0a0;" d="M1040 320q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5zM1296 320q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5zM1408 160v320q0 13 -9.5 22.5t-22.5 9.5 h-1216q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h1216q13 0 22.5 9.5t9.5 22.5zM178 640h1180l-157 482q-4 13 -16 21.5t-26 8.5h-782q-14 0 -26 -8.5t-16 -21.5zM1536 480v-320q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113v320q0 25 16 75 l197 606q17 53 63 86t101 33h782q55 0 101 -33t63 -86l197 -606q16 -50 16 -75z" />
<glyph unicode="&#xf0a1;" horiz-adv-x="1792" d="M1664 896q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5v-384q0 -52 -38 -90t-90 -38q-417 347 -812 380q-58 -19 -91 -66t-31 -100.5t40 -92.5q-20 -33 -23 -65.5t6 -58t33.5 -55t48 -50t61.5 -50.5q-29 -58 -111.5 -83t-168.5 -11.5t-132 55.5q-7 23 -29.5 87.5 t-32 94.5t-23 89t-15 101t3.5 98.5t22 110.5h-122q-66 0 -113 47t-47 113v192q0 66 47 113t113 47h480q435 0 896 384q52 0 90 -38t38 -90v-384zM1536 292v954q-394 -302 -768 -343v-270q377 -42 768 -341z" />
<glyph unicode="&#xf0a2;" horiz-adv-x="1664" d="M848 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM183 128h1298q-164 181 -246.5 411.5t-82.5 484.5q0 256 -320 256t-320 -256q0 -254 -82.5 -484.5t-246.5 -411.5zM1664 128q0 -52 -38 -90t-90 -38 h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38t-38 90q190 161 287 397.5t97 498.5q0 165 96 262t264 117q-8 18 -8 37q0 40 28 68t68 28t68 -28t28 -68q0 -19 -8 -37q168 -20 264 -117t96 -262q0 -262 97 -498.5t287 -397.5z" />
<glyph unicode="&#xf0a3;" d="M1376 640l138 -135q30 -28 20 -70q-12 -41 -52 -51l-188 -48l53 -186q12 -41 -19 -70q-29 -31 -70 -19l-186 53l-48 -188q-10 -40 -51 -52q-12 -2 -19 -2q-31 0 -51 22l-135 138l-135 -138q-28 -30 -70 -20q-41 11 -51 52l-48 188l-186 -53q-41 -12 -70 19q-31 29 -19 70 l53 186l-188 48q-40 10 -52 51q-10 42 20 70l138 135l-138 135q-30 28 -20 70q12 41 52 51l188 48l-53 186q-12 41 19 70q29 31 70 19l186 -53l48 188q10 41 51 51q41 12 70 -19l135 -139l135 139q29 30 70 19q41 -10 51 -51l48 -188l186 53q41 12 70 -19q31 -29 19 -70 l-53 -186l188 -48q40 -10 52 -51q10 -42 -20 -70z" />
<glyph unicode="&#xf0a4;" horiz-adv-x="1792" d="M256 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 768q0 51 -39 89.5t-89 38.5h-576q0 20 15 48.5t33 55t33 68t15 84.5q0 67 -44.5 97.5t-115.5 30.5q-24 0 -90 -139q-24 -44 -37 -65q-40 -64 -112 -145q-71 -81 -101 -106 q-69 -57 -140 -57h-32v-640h32q72 0 167 -32t193.5 -64t179.5 -32q189 0 189 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5h331q52 0 90 38t38 90zM1792 769q0 -105 -75.5 -181t-180.5 -76h-169q-4 -62 -37 -119q3 -21 3 -43 q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5q-133 0 -322 69q-164 59 -223 59h-288q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5h288q10 0 21.5 4.5t23.5 14t22.5 18t24 22.5t20.5 21.5t19 21.5t14 17q65 74 100 129q13 21 33 62t37 72t40.5 63t55 49.5 t69.5 17.5q125 0 206.5 -67t81.5 -189q0 -68 -22 -128h374q104 0 180 -76t76 -179z" />
<glyph unicode="&#xf0a5;" horiz-adv-x="1792" d="M1376 128h32v640h-32q-35 0 -67.5 12t-62.5 37t-50 46t-49 54q-2 3 -3.5 4.5t-4 4.5t-4.5 5q-72 81 -112 145q-14 22 -38 68q-1 3 -10.5 22.5t-18.5 36t-20 35.5t-21.5 30.5t-18.5 11.5q-71 0 -115.5 -30.5t-44.5 -97.5q0 -43 15 -84.5t33 -68t33 -55t15 -48.5h-576 q-50 0 -89 -38.5t-39 -89.5q0 -52 38 -90t90 -38h331q-15 -17 -25 -47.5t-10 -55.5q0 -69 53 -119q-18 -32 -18 -69t17.5 -73.5t47.5 -52.5q-4 -24 -4 -56q0 -85 48.5 -126t135.5 -41q84 0 183 32t194 64t167 32zM1664 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45 t45 -19t45 19t19 45zM1792 768v-640q0 -53 -37.5 -90.5t-90.5 -37.5h-288q-59 0 -223 -59q-190 -69 -317 -69q-142 0 -230 77.5t-87 217.5l1 5q-61 76 -61 178q0 22 3 43q-33 57 -37 119h-169q-105 0 -180.5 76t-75.5 181q0 103 76 179t180 76h374q-22 60 -22 128 q0 122 81.5 189t206.5 67q38 0 69.5 -17.5t55 -49.5t40.5 -63t37 -72t33 -62q35 -55 100 -129q2 -3 14 -17t19 -21.5t20.5 -21.5t24 -22.5t22.5 -18t23.5 -14t21.5 -4.5h288q53 0 90.5 -37.5t37.5 -90.5z" />
<glyph unicode="&#xf0a6;" d="M1280 -64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 700q0 189 -167 189q-26 0 -56 -5q-16 30 -52.5 47.5t-73.5 17.5t-69 -18q-50 53 -119 53q-25 0 -55.5 -10t-47.5 -25v331q0 52 -38 90t-90 38q-51 0 -89.5 -39t-38.5 -89v-576 q-20 0 -48.5 15t-55 33t-68 33t-84.5 15q-67 0 -97.5 -44.5t-30.5 -115.5q0 -24 139 -90q44 -24 65 -37q64 -40 145 -112q81 -71 106 -101q57 -69 57 -140v-32h640v32q0 72 32 167t64 193.5t32 179.5zM1536 705q0 -133 -69 -322q-59 -164 -59 -223v-288q0 -53 -37.5 -90.5 t-90.5 -37.5h-640q-53 0 -90.5 37.5t-37.5 90.5v288q0 10 -4.5 21.5t-14 23.5t-18 22.5t-22.5 24t-21.5 20.5t-21.5 19t-17 14q-74 65 -129 100q-21 13 -62 33t-72 37t-63 40.5t-49.5 55t-17.5 69.5q0 125 67 206.5t189 81.5q68 0 128 -22v374q0 104 76 180t179 76 q105 0 181 -75.5t76 -180.5v-169q62 -4 119 -37q21 3 43 3q101 0 178 -60q139 1 219.5 -85t80.5 -227z" />
<glyph unicode="&#xf0a7;" d="M1408 576q0 84 -32 183t-64 194t-32 167v32h-640v-32q0 -35 -12 -67.5t-37 -62.5t-46 -50t-54 -49q-9 -8 -14 -12q-81 -72 -145 -112q-22 -14 -68 -38q-3 -1 -22.5 -10.5t-36 -18.5t-35.5 -20t-30.5 -21.5t-11.5 -18.5q0 -71 30.5 -115.5t97.5 -44.5q43 0 84.5 15t68 33 t55 33t48.5 15v-576q0 -50 38.5 -89t89.5 -39q52 0 90 38t38 90v331q46 -35 103 -35q69 0 119 53q32 -18 69 -18t73.5 17.5t52.5 47.5q24 -4 56 -4q85 0 126 48.5t41 135.5zM1280 1344q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 580 q0 -142 -77.5 -230t-217.5 -87l-5 1q-76 -61 -178 -61q-22 0 -43 3q-54 -30 -119 -37v-169q0 -105 -76 -180.5t-181 -75.5q-103 0 -179 76t-76 180v374q-54 -22 -128 -22q-121 0 -188.5 81.5t-67.5 206.5q0 38 17.5 69.5t49.5 55t63 40.5t72 37t62 33q55 35 129 100 q3 2 17 14t21.5 19t21.5 20.5t22.5 24t18 22.5t14 23.5t4.5 21.5v288q0 53 37.5 90.5t90.5 37.5h640q53 0 90.5 -37.5t37.5 -90.5v-288q0 -59 59 -223q69 -190 69 -317z" />
<glyph unicode="&#xf0a8;" d="M1280 576v128q0 26 -19 45t-45 19h-502l189 189q19 19 19 45t-19 45l-91 91q-18 18 -45 18t-45 -18l-362 -362l-91 -91q-18 -18 -18 -45t18 -45l91 -91l362 -362q18 -18 45 -18t45 18l91 91q18 18 18 45t-18 45l-189 189h502q26 0 45 19t19 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
<glyph unicode="&#xf0a9;" d="M1285 640q0 27 -18 45l-91 91l-362 362q-18 18 -45 18t-45 -18l-91 -91q-18 -18 -18 -45t18 -45l189 -189h-502q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h502l-189 -189q-19 -19 -19 -45t19 -45l91 -91q18 -18 45 -18t45 18l362 362l91 91q18 18 18 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
<glyph unicode="&#xf0aa;" d="M1284 641q0 27 -18 45l-362 362l-91 91q-18 18 -45 18t-45 -18l-91 -91l-362 -362q-18 -18 -18 -45t18 -45l91 -91q18 -18 45 -18t45 18l189 189v-502q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v502l189 -189q19 -19 45 -19t45 19l91 91q18 18 18 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
<glyph unicode="&#xf0ab;" d="M1284 639q0 27 -18 45l-91 91q-18 18 -45 18t-45 -18l-189 -189v502q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-502l-189 189q-19 19 -45 19t-45 -19l-91 -91q-18 -18 -18 -45t18 -45l362 -362l91 -91q18 -18 45 -18t45 18l91 91l362 362q18 18 18 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
<glyph unicode="&#xf0ac;" d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM1042 887q-2 -1 -9.5 -9.5t-13.5 -9.5q2 0 4.5 5t5 11t3.5 7q6 7 22 15q14 6 52 12q34 8 51 -11 q-2 2 9.5 13t14.5 12q3 2 15 4.5t15 7.5l2 22q-12 -1 -17.5 7t-6.5 21q0 -2 -6 -8q0 7 -4.5 8t-11.5 -1t-9 -1q-10 3 -15 7.5t-8 16.5t-4 15q-2 5 -9.5 10.5t-9.5 10.5q-1 2 -2.5 5.5t-3 6.5t-4 5.5t-5.5 2.5t-7 -5t-7.5 -10t-4.5 -5q-3 2 -6 1.5t-4.5 -1t-4.5 -3t-5 -3.5 q-3 -2 -8.5 -3t-8.5 -2q15 5 -1 11q-10 4 -16 3q9 4 7.5 12t-8.5 14h5q-1 4 -8.5 8.5t-17.5 8.5t-13 6q-8 5 -34 9.5t-33 0.5q-5 -6 -4.5 -10.5t4 -14t3.5 -12.5q1 -6 -5.5 -13t-6.5 -12q0 -7 14 -15.5t10 -21.5q-3 -8 -16 -16t-16 -12q-5 -8 -1.5 -18.5t10.5 -16.5 q2 -2 1.5 -4t-3.5 -4.5t-5.5 -4t-6.5 -3.5l-3 -2q-11 -5 -20.5 6t-13.5 26q-7 25 -16 30q-23 8 -29 -1q-5 13 -41 26q-25 9 -58 4q6 1 0 15q-7 15 -19 12q3 6 4 17.5t1 13.5q3 13 12 23q1 1 7 8.5t9.5 13.5t0.5 6q35 -4 50 11q5 5 11.5 17t10.5 17q9 6 14 5.5t14.5 -5.5 t14.5 -5q14 -1 15.5 11t-7.5 20q12 -1 3 17q-5 7 -8 9q-12 4 -27 -5q-8 -4 2 -8q-1 1 -9.5 -10.5t-16.5 -17.5t-16 5q-1 1 -5.5 13.5t-9.5 13.5q-8 0 -16 -15q3 8 -11 15t-24 8q19 12 -8 27q-7 4 -20.5 5t-19.5 -4q-5 -7 -5.5 -11.5t5 -8t10.5 -5.5t11.5 -4t8.5 -3 q14 -10 8 -14q-2 -1 -8.5 -3.5t-11.5 -4.5t-6 -4q-3 -4 0 -14t-2 -14q-5 5 -9 17.5t-7 16.5q7 -9 -25 -6l-10 1q-4 0 -16 -2t-20.5 -1t-13.5 8q-4 8 0 20q1 4 4 2q-4 3 -11 9.5t-10 8.5q-46 -15 -94 -41q6 -1 12 1q5 2 13 6.5t10 5.5q34 14 42 7l5 5q14 -16 20 -25 q-7 4 -30 1q-20 -6 -22 -12q7 -12 5 -18q-4 3 -11.5 10t-14.5 11t-15 5q-16 0 -22 -1q-146 -80 -235 -222q7 -7 12 -8q4 -1 5 -9t2.5 -11t11.5 3q9 -8 3 -19q1 1 44 -27q19 -17 21 -21q3 -11 -10 -18q-1 2 -9 9t-9 4q-3 -5 0.5 -18.5t10.5 -12.5q-7 0 -9.5 -16t-2.5 -35.5 t-1 -23.5l2 -1q-3 -12 5.5 -34.5t21.5 -19.5q-13 -3 20 -43q6 -8 8 -9q3 -2 12 -7.5t15 -10t10 -10.5q4 -5 10 -22.5t14 -23.5q-2 -6 9.5 -20t10.5 -23q-1 0 -2.5 -1t-2.5 -1q3 -7 15.5 -14t15.5 -13q1 -3 2 -10t3 -11t8 -2q2 20 -24 62q-15 25 -17 29q-3 5 -5.5 15.5 t-4.5 14.5q2 0 6 -1.5t8.5 -3.5t7.5 -4t2 -3q-3 -7 2 -17.5t12 -18.5t17 -19t12 -13q6 -6 14 -19.5t0 -13.5q9 0 20 -10t17 -20q5 -8 8 -26t5 -24q2 -7 8.5 -13.5t12.5 -9.5l16 -8t13 -7q5 -2 18.5 -10.5t21.5 -11.5q10 -4 16 -4t14.5 2.5t13.5 3.5q15 2 29 -15t21 -21 q36 -19 55 -11q-2 -1 0.5 -7.5t8 -15.5t9 -14.5t5.5 -8.5q5 -6 18 -15t18 -15q6 4 7 9q-3 -8 7 -20t18 -10q14 3 14 32q-31 -15 -49 18q0 1 -2.5 5.5t-4 8.5t-2.5 8.5t0 7.5t5 3q9 0 10 3.5t-2 12.5t-4 13q-1 8 -11 20t-12 15q-5 -9 -16 -8t-16 9q0 -1 -1.5 -5.5t-1.5 -6.5 q-13 0 -15 1q1 3 2.5 17.5t3.5 22.5q1 4 5.5 12t7.5 14.5t4 12.5t-4.5 9.5t-17.5 2.5q-19 -1 -26 -20q-1 -3 -3 -10.5t-5 -11.5t-9 -7q-7 -3 -24 -2t-24 5q-13 8 -22.5 29t-9.5 37q0 10 2.5 26.5t3 25t-5.5 24.5q3 2 9 9.5t10 10.5q2 1 4.5 1.5t4.5 0t4 1.5t3 6q-1 1 -4 3 q-3 3 -4 3q7 -3 28.5 1.5t27.5 -1.5q15 -11 22 2q0 1 -2.5 9.5t-0.5 13.5q5 -27 29 -9q3 -3 15.5 -5t17.5 -5q3 -2 7 -5.5t5.5 -4.5t5 0.5t8.5 6.5q10 -14 12 -24q11 -40 19 -44q7 -3 11 -2t4.5 9.5t0 14t-1.5 12.5l-1 8v18l-1 8q-15 3 -18.5 12t1.5 18.5t15 18.5q1 1 8 3.5 t15.5 6.5t12.5 8q21 19 15 35q7 0 11 9q-1 0 -5 3t-7.5 5t-4.5 2q9 5 2 16q5 3 7.5 11t7.5 10q9 -12 21 -2q7 8 1 16q5 7 20.5 10.5t18.5 9.5q7 -2 8 2t1 12t3 12q4 5 15 9t13 5l17 11q3 4 0 4q18 -2 31 11q10 11 -6 20q3 6 -3 9.5t-15 5.5q3 1 11.5 0.5t10.5 1.5 q15 10 -7 16q-17 5 -43 -12zM879 10q206 36 351 189q-3 3 -12.5 4.5t-12.5 3.5q-18 7 -24 8q1 7 -2.5 13t-8 9t-12.5 8t-11 7q-2 2 -7 6t-7 5.5t-7.5 4.5t-8.5 2t-10 -1l-3 -1q-3 -1 -5.5 -2.5t-5.5 -3t-4 -3t0 -2.5q-21 17 -36 22q-5 1 -11 5.5t-10.5 7t-10 1.5t-11.5 -7 q-5 -5 -6 -15t-2 -13q-7 5 0 17.5t2 18.5q-3 6 -10.5 4.5t-12 -4.5t-11.5 -8.5t-9 -6.5t-8.5 -5.5t-8.5 -7.5q-3 -4 -6 -12t-5 -11q-2 4 -11.5 6.5t-9.5 5.5q2 -10 4 -35t5 -38q7 -31 -12 -48q-27 -25 -29 -40q-4 -22 12 -26q0 -7 -8 -20.5t-7 -21.5q0 -6 2 -16z" />
<glyph unicode="&#xf0ad;" horiz-adv-x="1664" d="M384 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1028 484l-682 -682q-37 -37 -90 -37q-52 0 -91 37l-106 108q-38 36 -38 90q0 53 38 91l681 681q39 -98 114.5 -173.5t173.5 -114.5zM1662 919q0 -39 -23 -106q-47 -134 -164.5 -217.5 t-258.5 -83.5q-185 0 -316.5 131.5t-131.5 316.5t131.5 316.5t316.5 131.5q58 0 121.5 -16.5t107.5 -46.5q16 -11 16 -28t-16 -28l-293 -169v-224l193 -107q5 3 79 48.5t135.5 81t70.5 35.5q15 0 23.5 -10t8.5 -25z" />
<glyph unicode="&#xf0ae;" horiz-adv-x="1792" d="M1024 128h640v128h-640v-128zM640 640h1024v128h-1024v-128zM1280 1152h384v128h-384v-128zM1792 320v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 832v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19 t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 1344v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45z" />
<glyph unicode="&#xf0b0;" horiz-adv-x="1408" d="M1403 1241q17 -41 -14 -70l-493 -493v-742q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-256 256q-19 19 -19 45v486l-493 493q-31 29 -14 70q17 39 59 39h1280q42 0 59 -39z" />
<glyph unicode="&#xf0b1;" horiz-adv-x="1792" d="M640 1280h512v128h-512v-128zM1792 640v-480q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v480h672v-160q0 -26 19 -45t45 -19h320q26 0 45 19t19 45v160h672zM1024 640v-128h-256v128h256zM1792 1120v-384h-1792v384q0 66 47 113t113 47h352v160q0 40 28 68 t68 28h576q40 0 68 -28t28 -68v-160h352q66 0 113 -47t47 -113z" />
<glyph unicode="&#xf0b2;" d="M1283 995l-355 -355l355 -355l144 144q29 31 70 14q39 -17 39 -59v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l144 144l-355 355l-355 -355l144 -144q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l144 -144 l355 355l-355 355l-144 -144q-19 -19 -45 -19q-12 0 -24 5q-40 17 -40 59v448q0 26 19 45t45 19h448q42 0 59 -40q17 -39 -14 -69l-144 -144l355 -355l355 355l-144 144q-31 30 -14 69q17 40 59 40h448q26 0 45 -19t19 -45v-448q0 -42 -39 -59q-13 -5 -25 -5q-26 0 -45 19z " />
<glyph unicode="&#xf0c0;" horiz-adv-x="1920" d="M593 640q-162 -5 -265 -128h-134q-82 0 -138 40.5t-56 118.5q0 353 124 353q6 0 43.5 -21t97.5 -42.5t119 -21.5q67 0 133 23q-5 -37 -5 -66q0 -139 81 -256zM1664 3q0 -120 -73 -189.5t-194 -69.5h-874q-121 0 -194 69.5t-73 189.5q0 53 3.5 103.5t14 109t26.5 108.5 t43 97.5t62 81t85.5 53.5t111.5 20q10 0 43 -21.5t73 -48t107 -48t135 -21.5t135 21.5t107 48t73 48t43 21.5q61 0 111.5 -20t85.5 -53.5t62 -81t43 -97.5t26.5 -108.5t14 -109t3.5 -103.5zM640 1280q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75 t75 -181zM1344 896q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5zM1920 671q0 -78 -56 -118.5t-138 -40.5h-134q-103 123 -265 128q81 117 81 256q0 29 -5 66q66 -23 133 -23q59 0 119 21.5t97.5 42.5 t43.5 21q124 0 124 -353zM1792 1280q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181z" />
<glyph unicode="&#xf0c1;" horiz-adv-x="1664" d="M1456 320q0 40 -28 68l-208 208q-28 28 -68 28q-42 0 -72 -32q3 -3 19 -18.5t21.5 -21.5t15 -19t13 -25.5t3.5 -27.5q0 -40 -28 -68t-68 -28q-15 0 -27.5 3.5t-25.5 13t-19 15t-21.5 21.5t-18.5 19q-33 -31 -33 -73q0 -40 28 -68l206 -207q27 -27 68 -27q40 0 68 26 l147 146q28 28 28 67zM753 1025q0 40 -28 68l-206 207q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67q0 -40 28 -68l208 -208q27 -27 68 -27q42 0 72 31q-3 3 -19 18.5t-21.5 21.5t-15 19t-13 25.5t-3.5 27.5q0 40 28 68t68 28q15 0 27.5 -3.5t25.5 -13t19 -15 t21.5 -21.5t18.5 -19q33 31 33 73zM1648 320q0 -120 -85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-206 207q-83 83 -83 203q0 123 88 209l-88 88q-86 -88 -208 -88q-120 0 -204 84l-208 208q-84 84 -84 204t85 203l147 146q83 83 203 83q121 0 204 -85l206 -207 q83 -83 83 -203q0 -123 -88 -209l88 -88q86 88 208 88q120 0 204 -84l208 -208q84 -84 84 -204z" />
<glyph unicode="&#xf0c2;" horiz-adv-x="1920" d="M1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088q-185 0 -316.5 131.5t-131.5 316.5q0 132 71 241.5t187 163.5q-2 28 -2 43q0 212 150 362t362 150q158 0 286.5 -88t187.5 -230q70 62 166 62q106 0 181 -75t75 -181q0 -75 -41 -138q129 -30 213 -134.5t84 -239.5z " />
<glyph unicode="&#xf0c3;" horiz-adv-x="1664" d="M1527 88q56 -89 21.5 -152.5t-140.5 -63.5h-1152q-106 0 -140.5 63.5t21.5 152.5l503 793v399h-64q-26 0 -45 19t-19 45t19 45t45 19h512q26 0 45 -19t19 -45t-19 -45t-45 -19h-64v-399zM748 813l-272 -429h712l-272 429l-20 31v37v399h-128v-399v-37z" />
<glyph unicode="&#xf0c4;" horiz-adv-x="1792" d="M960 640q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1260 576l507 -398q28 -20 25 -56q-5 -35 -35 -51l-128 -64q-13 -7 -29 -7q-17 0 -31 8l-690 387l-110 -66q-8 -4 -12 -5q14 -49 10 -97q-7 -77 -56 -147.5t-132 -123.5q-132 -84 -277 -84 q-136 0 -222 78q-90 84 -79 207q7 76 56 147t131 124q132 84 278 84q83 0 151 -31q9 13 22 22l122 73l-122 73q-13 9 -22 22q-68 -31 -151 -31q-146 0 -278 84q-82 53 -131 124t-56 147q-5 59 15.5 113t63.5 93q85 79 222 79q145 0 277 -84q83 -52 132 -123t56 -148 q4 -48 -10 -97q4 -1 12 -5l110 -66l690 387q14 8 31 8q16 0 29 -7l128 -64q30 -16 35 -51q3 -36 -25 -56zM579 836q46 42 21 108t-106 117q-92 59 -192 59q-74 0 -113 -36q-46 -42 -21 -108t106 -117q92 -59 192 -59q74 0 113 36zM494 91q81 51 106 117t-21 108 q-39 36 -113 36q-100 0 -192 -59q-81 -51 -106 -117t21 -108q39 -36 113 -36q100 0 192 59zM672 704l96 -58v11q0 36 33 56l14 8l-79 47l-26 -26q-3 -3 -10 -11t-12 -12q-2 -2 -4 -3.5t-3 -2.5zM896 480l96 -32l736 576l-128 64l-768 -431v-113l-160 -96l9 -8q2 -2 7 -6 q4 -4 11 -12t11 -12l26 -26zM1600 64l128 64l-520 408l-177 -138q-2 -3 -13 -7z" />
<glyph unicode="&#xf0c5;" horiz-adv-x="1792" d="M1696 1152q40 0 68 -28t28 -68v-1216q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v288h-544q-40 0 -68 28t-28 68v672q0 40 20 88t48 76l408 408q28 28 76 48t88 20h416q40 0 68 -28t28 -68v-328q68 40 128 40h416zM1152 939l-299 -299h299v299zM512 1323l-299 -299 h299v299zM708 676l316 316v416h-384v-416q0 -40 -28 -68t-68 -28h-416v-640h512v256q0 40 20 88t48 76zM1664 -128v1152h-384v-416q0 -40 -28 -68t-68 -28h-416v-640h896z" />
<glyph unicode="&#xf0c6;" horiz-adv-x="1408" d="M1404 151q0 -117 -79 -196t-196 -79q-135 0 -235 100l-777 776q-113 115 -113 271q0 159 110 270t269 111q158 0 273 -113l605 -606q10 -10 10 -22q0 -16 -30.5 -46.5t-46.5 -30.5q-13 0 -23 10l-606 607q-79 77 -181 77q-106 0 -179 -75t-73 -181q0 -105 76 -181 l776 -777q63 -63 145 -63q64 0 106 42t42 106q0 82 -63 145l-581 581q-26 24 -60 24q-29 0 -48 -19t-19 -48q0 -32 25 -59l410 -410q10 -10 10 -22q0 -16 -31 -47t-47 -31q-12 0 -22 10l-410 410q-63 61 -63 149q0 82 57 139t139 57q88 0 149 -63l581 -581q100 -98 100 -235 z" />
<glyph unicode="&#xf0c7;" d="M384 0h768v384h-768v-384zM1280 0h128v896q0 14 -10 38.5t-20 34.5l-281 281q-10 10 -34 20t-39 10v-416q0 -40 -28 -68t-68 -28h-576q-40 0 -68 28t-28 68v416h-128v-1280h128v416q0 40 28 68t68 28h832q40 0 68 -28t28 -68v-416zM896 928v320q0 13 -9.5 22.5t-22.5 9.5 h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5zM1536 896v-928q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h928q40 0 88 -20t76 -48l280 -280q28 -28 48 -76t20 -88z" />
<glyph unicode="&#xf0c8;" d="M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
<glyph unicode="&#xf0c9;" d="M1536 192v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1536 704v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1536 1216v-128q0 -26 -19 -45 t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" />
<glyph unicode="&#xf0ca;" horiz-adv-x="1792" d="M384 128q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM384 640q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5 t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5zM384 1152q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1792 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z M1792 1248v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z" />
<glyph unicode="&#xf0cb;" horiz-adv-x="1792" d="M381 -84q0 -80 -54.5 -126t-135.5 -46q-106 0 -172 66l57 88q49 -45 106 -45q29 0 50.5 14.5t21.5 42.5q0 64 -105 56l-26 56q8 10 32.5 43.5t42.5 54t37 38.5v1q-16 0 -48.5 -1t-48.5 -1v-53h-106v152h333v-88l-95 -115q51 -12 81 -49t30 -88zM383 543v-159h-362 q-6 36 -6 54q0 51 23.5 93t56.5 68t66 47.5t56.5 43.5t23.5 45q0 25 -14.5 38.5t-39.5 13.5q-46 0 -81 -58l-85 59q24 51 71.5 79.5t105.5 28.5q73 0 123 -41.5t50 -112.5q0 -50 -34 -91.5t-75 -64.5t-75.5 -50.5t-35.5 -52.5h127v60h105zM1792 224v-192q0 -13 -9.5 -22.5 t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5zM384 1123v-99h-335v99h107q0 41 0.5 122t0.5 121v12h-2q-8 -17 -50 -54l-71 76l136 127h106v-404h108zM1792 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5 t-9.5 22.5v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5zM1792 1248v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z" />
<glyph unicode="&#xf0cc;" horiz-adv-x="1792" d="M1760 640q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1728q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h1728zM483 704q-28 35 -51 80q-48 97 -48 188q0 181 134 309q133 127 393 127q50 0 167 -19q66 -12 177 -48q10 -38 21 -118q14 -123 14 -183q0 -18 -5 -45l-12 -3l-84 6 l-14 2q-50 149 -103 205q-88 91 -210 91q-114 0 -182 -59q-67 -58 -67 -146q0 -73 66 -140t279 -129q69 -20 173 -66q58 -28 95 -52h-743zM990 448h411q7 -39 7 -92q0 -111 -41 -212q-23 -55 -71 -104q-37 -35 -109 -81q-80 -48 -153 -66q-80 -21 -203 -21q-114 0 -195 23 l-140 40q-57 16 -72 28q-8 8 -8 22v13q0 108 -2 156q-1 30 0 68l2 37v44l102 2q15 -34 30 -71t22.5 -56t12.5 -27q35 -57 80 -94q43 -36 105 -57q59 -22 132 -22q64 0 139 27q77 26 122 86q47 61 47 129q0 84 -81 157q-34 29 -137 71z" />
<glyph unicode="&#xf0cd;" d="M48 1313q-37 2 -45 4l-3 88q13 1 40 1q60 0 112 -4q132 -7 166 -7q86 0 168 3q116 4 146 5q56 0 86 2l-1 -14l2 -64v-9q-60 -9 -124 -9q-60 0 -79 -25q-13 -14 -13 -132q0 -13 0.5 -32.5t0.5 -25.5l1 -229l14 -280q6 -124 51 -202q35 -59 96 -92q88 -47 177 -47 q104 0 191 28q56 18 99 51q48 36 65 64q36 56 53 114q21 73 21 229q0 79 -3.5 128t-11 122.5t-13.5 159.5l-4 59q-5 67 -24 88q-34 35 -77 34l-100 -2l-14 3l2 86h84l205 -10q76 -3 196 10l18 -2q6 -38 6 -51q0 -7 -4 -31q-45 -12 -84 -13q-73 -11 -79 -17q-15 -15 -15 -41 q0 -7 1.5 -27t1.5 -31q8 -19 22 -396q6 -195 -15 -304q-15 -76 -41 -122q-38 -65 -112 -123q-75 -57 -182 -89q-109 -33 -255 -33q-167 0 -284 46q-119 47 -179 122q-61 76 -83 195q-16 80 -16 237v333q0 188 -17 213q-25 36 -147 39zM1536 -96v64q0 14 -9 23t-23 9h-1472 q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h1472q14 0 23 9t9 23z" />
<glyph unicode="&#xf0ce;" horiz-adv-x="1664" d="M512 160v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM512 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 160v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23 v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM512 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 160v192 q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192 q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1664 1248v-1088q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1344q66 0 113 -47t47 -113 z" />
<glyph unicode="&#xf0d0;" horiz-adv-x="1664" d="M1190 955l293 293l-107 107l-293 -293zM1637 1248q0 -27 -18 -45l-1286 -1286q-18 -18 -45 -18t-45 18l-198 198q-18 18 -18 45t18 45l1286 1286q18 18 45 18t45 -18l198 -198q18 -18 18 -45zM286 1438l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98zM636 1276 l196 -60l-196 -60l-60 -196l-60 196l-196 60l196 60l60 196zM1566 798l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98zM926 1438l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98z" />
<glyph unicode="&#xf0d1;" horiz-adv-x="1792" d="M640 128q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM256 640h384v256h-158q-13 0 -22 -9l-195 -195q-9 -9 -9 -22v-30zM1536 128q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM1792 1216v-1024q0 -15 -4 -26.5t-13.5 -18.5 t-16.5 -11.5t-23.5 -6t-22.5 -2t-25.5 0t-22.5 0.5q0 -106 -75 -181t-181 -75t-181 75t-75 181h-384q0 -106 -75 -181t-181 -75t-181 75t-75 181h-64q-3 0 -22.5 -0.5t-25.5 0t-22.5 2t-23.5 6t-16.5 11.5t-13.5 18.5t-4 26.5q0 26 19 45t45 19v320q0 8 -0.5 35t0 38 t2.5 34.5t6.5 37t14 30.5t22.5 30l198 198q19 19 50.5 32t58.5 13h160v192q0 26 19 45t45 19h1024q26 0 45 -19t19 -45z" />
<glyph unicode="&#xf0d2;" d="M1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103q-111 0 -218 32q59 93 78 164q9 34 54 211q20 -39 73 -67.5t114 -28.5q121 0 216 68.5t147 188.5t52 270q0 114 -59.5 214t-172.5 163t-255 63q-105 0 -196 -29t-154.5 -77t-109 -110.5t-67 -129.5t-21.5 -134 q0 -104 40 -183t117 -111q30 -12 38 20q2 7 8 31t8 30q6 23 -11 43q-51 61 -51 151q0 151 104.5 259.5t273.5 108.5q151 0 235.5 -82t84.5 -213q0 -170 -68.5 -289t-175.5 -119q-61 0 -98 43.5t-23 104.5q8 35 26.5 93.5t30 103t11.5 75.5q0 50 -27 83t-77 33 q-62 0 -105 -57t-43 -142q0 -73 25 -122l-99 -418q-17 -70 -13 -177q-206 91 -333 281t-127 423q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
<glyph unicode="&#xf0d3;" d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-725q85 122 108 210q9 34 53 209q21 -39 73.5 -67t112.5 -28q181 0 295.5 147.5t114.5 373.5q0 84 -35 162.5t-96.5 139t-152.5 97t-197 36.5q-104 0 -194.5 -28.5t-153 -76.5 t-107.5 -109.5t-66.5 -128t-21.5 -132.5q0 -102 39.5 -180t116.5 -110q13 -5 23.5 0t14.5 19q10 44 15 61q6 23 -11 42q-50 62 -50 150q0 150 103.5 256.5t270.5 106.5q149 0 232.5 -81t83.5 -210q0 -168 -67.5 -286t-173.5 -118q-60 0 -97 43.5t-23 103.5q8 34 26.5 92.5 t29.5 102t11 74.5q0 49 -26.5 81.5t-75.5 32.5q-61 0 -103.5 -56.5t-42.5 -139.5q0 -72 24 -121l-98 -414q-24 -100 -7 -254h-183q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960z" />
<glyph unicode="&#xf0d4;" d="M678 -57q0 -38 -10 -71h-380q-95 0 -171.5 56.5t-103.5 147.5q24 45 69 77.5t100 49.5t107 24t107 7q32 0 49 -2q6 -4 30.5 -21t33 -23t31 -23t32 -25.5t27.5 -25.5t26.5 -29.5t21 -30.5t17.5 -34.5t9.5 -36t4.5 -40.5zM385 294q-234 -7 -385 -85v433q103 -118 273 -118 q32 0 70 5q-21 -61 -21 -86q0 -67 63 -149zM558 805q0 -100 -43.5 -160.5t-140.5 -60.5q-51 0 -97 26t-78 67.5t-56 93.5t-35.5 104t-11.5 99q0 96 51.5 165t144.5 69q66 0 119 -41t84 -104t47 -130t16 -128zM1536 896v-736q0 -119 -84.5 -203.5t-203.5 -84.5h-468 q39 73 39 157q0 66 -22 122.5t-55.5 93t-72 71t-72 59.5t-55.5 54.5t-22 59.5q0 36 23 68t56 61.5t65.5 64.5t55.5 93t23 131t-26.5 145.5t-75.5 118.5q-6 6 -14 11t-12.5 7.5t-10 9.5t-10.5 17h135l135 64h-437q-138 0 -244.5 -38.5t-182.5 -133.5q0 126 81 213t207 87h960 q119 0 203.5 -84.5t84.5 -203.5v-96h-256v256h-128v-256h-256v-128h256v-256h128v256h256z" />
<glyph unicode="&#xf0d5;" horiz-adv-x="1664" d="M876 71q0 21 -4.5 40.5t-9.5 36t-17.5 34.5t-21 30.5t-26.5 29.5t-27.5 25.5t-32 25.5t-31 23t-33 23t-30.5 21q-17 2 -50 2q-54 0 -106 -7t-108 -25t-98 -46t-69 -75t-27 -107q0 -68 35.5 -121.5t93 -84t120.5 -45.5t127 -15q59 0 112.5 12.5t100.5 39t74.5 73.5 t27.5 110zM756 933q0 60 -16.5 127.5t-47 130.5t-84 104t-119.5 41q-93 0 -144 -69t-51 -165q0 -47 11.5 -99t35.5 -104t56 -93.5t78 -67.5t97 -26q97 0 140.5 60.5t43.5 160.5zM625 1408h437l-135 -79h-135q71 -45 110 -126t39 -169q0 -74 -23 -131.5t-56 -92.5t-66 -64.5 t-56 -61t-23 -67.5q0 -26 16.5 -51t43 -48t58.5 -48t64 -55.5t58.5 -66t43 -85t16.5 -106.5q0 -160 -140 -282q-152 -131 -420 -131q-59 0 -119.5 10t-122 33.5t-108.5 58t-77 89t-30 121.5q0 61 37 135q32 64 96 110.5t145 71t155 36t150 13.5q-64 83 -64 149q0 12 2 23.5 t5 19.5t8 21.5t7 21.5q-40 -5 -70 -5q-149 0 -255.5 98t-106.5 246q0 140 95 250.5t234 141.5q94 20 187 20zM1664 1152v-128h-256v-256h-128v256h-256v128h256v256h128v-256h256z" />
<glyph unicode="&#xf0d6;" horiz-adv-x="1920" d="M768 384h384v96h-128v448h-114l-148 -137l77 -80q42 37 55 57h2v-288h-128v-96zM1280 640q0 -70 -21 -142t-59.5 -134t-101.5 -101t-138 -39t-138 39t-101.5 101t-59.5 134t-21 142t21 142t59.5 134t101.5 101t138 39t138 -39t101.5 -101t59.5 -134t21 -142zM1792 384 v512q-106 0 -181 75t-75 181h-1152q0 -106 -75 -181t-181 -75v-512q106 0 181 -75t75 -181h1152q0 106 75 181t181 75zM1920 1216v-1152q0 -26 -19 -45t-45 -19h-1792q-26 0 -45 19t-19 45v1152q0 26 19 45t45 19h1792q26 0 45 -19t19 -45z" />
<glyph unicode="&#xf0d7;" horiz-adv-x="1024" d="M1024 832q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45z" />
<glyph unicode="&#xf0d8;" horiz-adv-x="1024" d="M1024 320q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" />
<glyph unicode="&#xf0d9;" horiz-adv-x="640" d="M640 1088v-896q0 -26 -19 -45t-45 -19t-45 19l-448 448q-19 19 -19 45t19 45l448 448q19 19 45 19t45 -19t19 -45z" />
<glyph unicode="&#xf0da;" horiz-adv-x="640" d="M576 640q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19t-19 45v896q0 26 19 45t45 19t45 -19l448 -448q19 -19 19 -45z" />
<glyph unicode="&#xf0db;" horiz-adv-x="1664" d="M160 0h608v1152h-640v-1120q0 -13 9.5 -22.5t22.5 -9.5zM1536 32v1120h-640v-1152h608q13 0 22.5 9.5t9.5 22.5zM1664 1248v-1216q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1344q66 0 113 -47t47 -113z" />
<glyph unicode="&#xf0dc;" horiz-adv-x="1024" d="M1024 448q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45zM1024 832q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" />
<glyph unicode="&#xf0dd;" horiz-adv-x="1024" d="M1024 448q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45z" />
<glyph unicode="&#xf0de;" horiz-adv-x="1024" d="M1024 832q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" />
<glyph unicode="&#xf0e0;" horiz-adv-x="1792" d="M1792 826v-794q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v794q44 -49 101 -87q362 -246 497 -345q57 -42 92.5 -65.5t94.5 -48t110 -24.5h1h1q51 0 110 24.5t94.5 48t92.5 65.5q170 123 498 345q57 39 100 87zM1792 1120q0 -79 -49 -151t-122 -123 q-376 -261 -468 -325q-10 -7 -42.5 -30.5t-54 -38t-52 -32.5t-57.5 -27t-50 -9h-1h-1q-23 0 -50 9t-57.5 27t-52 32.5t-54 38t-42.5 30.5q-91 64 -262 182.5t-205 142.5q-62 42 -117 115.5t-55 136.5q0 78 41.5 130t118.5 52h1472q65 0 112.5 -47t47.5 -113z" />
<glyph unicode="&#xf0e1;" d="M349 911v-991h-330v991h330zM370 1217q1 -73 -50.5 -122t-135.5 -49h-2q-82 0 -132 49t-50 122q0 74 51.5 122.5t134.5 48.5t133 -48.5t51 -122.5zM1536 488v-568h-329v530q0 105 -40.5 164.5t-126.5 59.5q-63 0 -105.5 -34.5t-63.5 -85.5q-11 -30 -11 -81v-553h-329 q2 399 2 647t-1 296l-1 48h329v-144h-2q20 32 41 56t56.5 52t87 43.5t114.5 15.5q171 0 275 -113.5t104 -332.5z" />
<glyph unicode="&#xf0e2;" d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61q-172 0 -327 72.5t-264 204.5q-7 10 -6.5 22.5t8.5 20.5l137 138q10 9 25 9q16 -2 23 -12q73 -95 179 -147t225 -52q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5 t-163.5 109.5t-198.5 40.5q-98 0 -188 -35.5t-160 -101.5l137 -138q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l130 -129q107 101 244.5 156.5t284.5 55.5q156 0 298 -61t245 -164t164 -245t61 -298z" />
<glyph unicode="&#xf0e3;" horiz-adv-x="1792" d="M1771 0q0 -53 -37 -90l-107 -108q-39 -37 -91 -37q-53 0 -90 37l-363 364q-38 36 -38 90q0 53 43 96l-256 256l-126 -126q-14 -14 -34 -14t-34 14q2 -2 12.5 -12t12.5 -13t10 -11.5t10 -13.5t6 -13.5t5.5 -16.5t1.5 -18q0 -38 -28 -68q-3 -3 -16.5 -18t-19 -20.5 t-18.5 -16.5t-22 -15.5t-22 -9t-26 -4.5q-40 0 -68 28l-408 408q-28 28 -28 68q0 13 4.5 26t9 22t15.5 22t16.5 18.5t20.5 19t18 16.5q30 28 68 28q10 0 18 -1.5t16.5 -5.5t13.5 -6t13.5 -10t11.5 -10t13 -12.5t12 -12.5q-14 14 -14 34t14 34l348 348q14 14 34 14t34 -14 q-2 2 -12.5 12t-12.5 13t-10 11.5t-10 13.5t-6 13.5t-5.5 16.5t-1.5 18q0 38 28 68q3 3 16.5 18t19 20.5t18.5 16.5t22 15.5t22 9t26 4.5q40 0 68 -28l408 -408q28 -28 28 -68q0 -13 -4.5 -26t-9 -22t-15.5 -22t-16.5 -18.5t-20.5 -19t-18 -16.5q-30 -28 -68 -28 q-10 0 -18 1.5t-16.5 5.5t-13.5 6t-13.5 10t-11.5 10t-13 12.5t-12 12.5q14 -14 14 -34t-14 -34l-126 -126l256 -256q43 43 96 43q52 0 91 -37l363 -363q37 -39 37 -91z" />
<glyph unicode="&#xf0e4;" horiz-adv-x="1792" d="M384 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM576 832q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1004 351l101 382q6 26 -7.5 48.5t-38.5 29.5 t-48 -6.5t-30 -39.5l-101 -382q-60 -5 -107 -43.5t-63 -98.5q-20 -77 20 -146t117 -89t146 20t89 117q16 60 -6 117t-72 91zM1664 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 1024q0 53 -37.5 90.5 t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1472 832q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1792 384q0 -261 -141 -483q-19 -29 -54 -29h-1402q-35 0 -54 29 q-141 221 -141 483q0 182 71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
<glyph unicode="&#xf0e5;" horiz-adv-x="1792" d="M896 1152q-204 0 -381.5 -69.5t-282 -187.5t-104.5 -255q0 -112 71.5 -213.5t201.5 -175.5l87 -50l-27 -96q-24 -91 -70 -172q152 63 275 171l43 38l57 -6q69 -8 130 -8q204 0 381.5 69.5t282 187.5t104.5 255t-104.5 255t-282 187.5t-381.5 69.5zM1792 640 q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22h-5q-15 0 -27 10.5t-16 27.5v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281q0 174 120 321.5 t326 233t450 85.5t450 -85.5t326 -233t120 -321.5z" />
<glyph unicode="&#xf0e6;" horiz-adv-x="1792" d="M704 1152q-153 0 -286 -52t-211.5 -141t-78.5 -191q0 -82 53 -158t149 -132l97 -56l-35 -84q34 20 62 39l44 31l53 -10q78 -14 153 -14q153 0 286 52t211.5 141t78.5 191t-78.5 191t-211.5 141t-286 52zM704 1280q191 0 353.5 -68.5t256.5 -186.5t94 -257t-94 -257 t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224q0 139 94 257t256.5 186.5 t353.5 68.5zM1526 111q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22t-22 -7q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132q58 -4 88 -4q161 0 309 45t264 129 q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230q0 -120 -71 -224.5t-195 -176.5z" />
<glyph unicode="&#xf0e7;" horiz-adv-x="896" d="M885 970q18 -20 7 -44l-540 -1157q-13 -25 -42 -25q-4 0 -14 2q-17 5 -25.5 19t-4.5 30l197 808l-406 -101q-4 -1 -12 -1q-18 0 -31 11q-18 15 -13 39l201 825q4 14 16 23t28 9h328q19 0 32 -12.5t13 -29.5q0 -8 -5 -18l-171 -463l396 98q8 2 12 2q19 0 34 -15z" />
<glyph unicode="&#xf0e8;" horiz-adv-x="1792" d="M1792 288v-320q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192h-512v-192h96q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192h-512v-192h96q40 0 68 -28t28 -68v-320 q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192q0 52 38 90t90 38h512v192h-96q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-96v-192h512q52 0 90 -38t38 -90v-192h96q40 0 68 -28t28 -68 z" />
<glyph unicode="&#xf0e9;" horiz-adv-x="1664" d="M896 708v-580q0 -104 -76 -180t-180 -76t-180 76t-76 180q0 26 19 45t45 19t45 -19t19 -45q0 -50 39 -89t89 -39t89 39t39 89v580q33 11 64 11t64 -11zM1664 681q0 -13 -9.5 -22.5t-22.5 -9.5q-11 0 -23 10q-49 46 -93 69t-102 23q-68 0 -128 -37t-103 -97 q-7 -10 -17.5 -28t-14.5 -24q-11 -17 -28 -17q-18 0 -29 17q-4 6 -14.5 24t-17.5 28q-43 60 -102.5 97t-127.5 37t-127.5 -37t-102.5 -97q-7 -10 -17.5 -28t-14.5 -24q-11 -17 -29 -17q-17 0 -28 17q-4 6 -14.5 24t-17.5 28q-43 60 -103 97t-128 37q-58 0 -102 -23t-93 -69 q-12 -10 -23 -10q-13 0 -22.5 9.5t-9.5 22.5q0 5 1 7q45 183 172.5 319.5t298 204.5t360.5 68q140 0 274.5 -40t246.5 -113.5t194.5 -187t115.5 -251.5q1 -2 1 -7zM896 1408v-98q-42 2 -64 2t-64 -2v98q0 26 19 45t45 19t45 -19t19 -45z" />
<glyph unicode="&#xf0ea;" horiz-adv-x="1792" d="M768 -128h896v640h-416q-40 0 -68 28t-28 68v416h-384v-1152zM1024 1312v64q0 13 -9.5 22.5t-22.5 9.5h-704q-13 0 -22.5 -9.5t-9.5 -22.5v-64q0 -13 9.5 -22.5t22.5 -9.5h704q13 0 22.5 9.5t9.5 22.5zM1280 640h299l-299 299v-299zM1792 512v-672q0 -40 -28 -68t-68 -28 h-960q-40 0 -68 28t-28 68v160h-544q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h1088q40 0 68 -28t28 -68v-328q21 -13 36 -28l408 -408q28 -28 48 -76t20 -88z" />
<glyph unicode="&#xf0eb;" horiz-adv-x="1024" d="M736 960q0 -13 -9.5 -22.5t-22.5 -9.5t-22.5 9.5t-9.5 22.5q0 46 -54 71t-106 25q-13 0 -22.5 9.5t-9.5 22.5t9.5 22.5t22.5 9.5q50 0 99.5 -16t87 -54t37.5 -90zM896 960q0 72 -34.5 134t-90 101.5t-123 62t-136.5 22.5t-136.5 -22.5t-123 -62t-90 -101.5t-34.5 -134 q0 -101 68 -180q10 -11 30.5 -33t30.5 -33q128 -153 141 -298h228q13 145 141 298q10 11 30.5 33t30.5 33q68 79 68 180zM1024 960q0 -155 -103 -268q-45 -49 -74.5 -87t-59.5 -95.5t-34 -107.5q47 -28 47 -82q0 -37 -25 -64q25 -27 25 -64q0 -52 -45 -81q13 -23 13 -47 q0 -46 -31.5 -71t-77.5 -25q-20 -44 -60 -70t-87 -26t-87 26t-60 70q-46 0 -77.5 25t-31.5 71q0 24 13 47q-45 29 -45 81q0 37 25 64q-25 27 -25 64q0 54 47 82q-4 50 -34 107.5t-59.5 95.5t-74.5 87q-103 113 -103 268q0 99 44.5 184.5t117 142t164 89t186.5 32.5 t186.5 -32.5t164 -89t117 -142t44.5 -184.5z" />
<glyph unicode="&#xf0ec;" horiz-adv-x="1792" d="M1792 352v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5q-12 0 -24 10l-319 320q-9 9 -9 22q0 14 9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h1376q13 0 22.5 -9.5t9.5 -22.5zM1792 896q0 -14 -9 -23l-320 -320q-9 -9 -23 -9 q-13 0 -22.5 9.5t-9.5 22.5v192h-1376q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1376v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23z" />
<glyph unicode="&#xf0ed;" horiz-adv-x="1920" d="M1280 608q0 14 -9 23t-23 9h-224v352q0 13 -9.5 22.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-352h-224q-13 0 -22.5 -9.5t-9.5 -22.5q0 -14 9 -23l352 -352q9 -9 23 -9t23 9l351 351q10 12 10 24zM1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088 q-185 0 -316.5 131.5t-131.5 316.5q0 130 70 240t188 165q-2 30 -2 43q0 212 150 362t362 150q156 0 285.5 -87t188.5 -231q71 62 166 62q106 0 181 -75t75 -181q0 -76 -41 -138q130 -31 213.5 -135.5t83.5 -238.5z" />
<glyph unicode="&#xf0ee;" horiz-adv-x="1920" d="M1280 672q0 14 -9 23l-352 352q-9 9 -23 9t-23 -9l-351 -351q-10 -12 -10 -24q0 -14 9 -23t23 -9h224v-352q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5v352h224q13 0 22.5 9.5t9.5 22.5zM1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088 q-185 0 -316.5 131.5t-131.5 316.5q0 130 70 240t188 165q-2 30 -2 43q0 212 150 362t362 150q156 0 285.5 -87t188.5 -231q71 62 166 62q106 0 181 -75t75 -181q0 -76 -41 -138q130 -31 213.5 -135.5t83.5 -238.5z" />
<glyph unicode="&#xf0f0;" horiz-adv-x="1408" d="M384 192q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45zM1408 131q0 -121 -73 -190t-194 -69h-874q-121 0 -194 69t-73 190q0 68 5.5 131t24 138t47.5 132.5t81 103t120 60.5q-22 -52 -22 -120v-203q-58 -20 -93 -70t-35 -111q0 -80 56 -136t136 -56 t136 56t56 136q0 61 -35.5 111t-92.5 70v203q0 62 25 93q132 -104 295 -104t295 104q25 -31 25 -93v-64q-106 0 -181 -75t-75 -181v-89q-32 -29 -32 -71q0 -40 28 -68t68 -28t68 28t28 68q0 42 -32 71v89q0 52 38 90t90 38t90 -38t38 -90v-89q-32 -29 -32 -71q0 -40 28 -68 t68 -28t68 28t28 68q0 42 -32 71v89q0 68 -34.5 127.5t-93.5 93.5q0 10 0.5 42.5t0 48t-2.5 41.5t-7 47t-13 40q68 -15 120 -60.5t81 -103t47.5 -132.5t24 -138t5.5 -131zM1088 1024q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5 t271.5 -112.5t112.5 -271.5z" />
<glyph unicode="&#xf0f1;" horiz-adv-x="1408" d="M1280 832q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 832q0 -62 -35.5 -111t-92.5 -70v-395q0 -159 -131.5 -271.5t-316.5 -112.5t-316.5 112.5t-131.5 271.5v132q-164 20 -274 128t-110 252v512q0 26 19 45t45 19q6 0 16 -2q17 30 47 48 t65 18q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5q-33 0 -64 18v-402q0 -106 94 -181t226 -75t226 75t94 181v402q-31 -18 -64 -18q-53 0 -90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5q35 0 65 -18t47 -48q10 2 16 2q26 0 45 -19t19 -45v-512q0 -144 -110 -252 t-274 -128v-132q0 -106 94 -181t226 -75t226 75t94 181v395q-57 21 -92.5 70t-35.5 111q0 80 56 136t136 56t136 -56t56 -136z" />
<glyph unicode="&#xf0f2;" horiz-adv-x="1792" d="M640 1152h512v128h-512v-128zM288 1152v-1280h-64q-92 0 -158 66t-66 158v832q0 92 66 158t158 66h64zM1408 1152v-1280h-1024v1280h128v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h128zM1792 928v-832q0 -92 -66 -158t-158 -66h-64v1280h64q92 0 158 -66 t66 -158z" />
<glyph unicode="&#xf0f3;" horiz-adv-x="1664" d="M848 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM1664 128q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38t-38 90q190 161 287 397.5t97 498.5 q0 165 96 262t264 117q-8 18 -8 37q0 40 28 68t68 28t68 -28t28 -68q0 -19 -8 -37q168 -20 264 -117t96 -262q0 -262 97 -498.5t287 -397.5z" />
<glyph unicode="&#xf0f4;" horiz-adv-x="1920" d="M1664 896q0 80 -56 136t-136 56h-64v-384h64q80 0 136 56t56 136zM0 128h1792q0 -106 -75 -181t-181 -75h-1280q-106 0 -181 75t-75 181zM1856 896q0 -159 -112.5 -271.5t-271.5 -112.5h-64v-32q0 -92 -66 -158t-158 -66h-704q-92 0 -158 66t-66 158v736q0 26 19 45 t45 19h1152q159 0 271.5 -112.5t112.5 -271.5z" />
<glyph unicode="&#xf0f5;" horiz-adv-x="1408" d="M640 1472v-640q0 -61 -35.5 -111t-92.5 -70v-779q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v779q-57 20 -92.5 70t-35.5 111v640q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45 t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45zM1408 1472v-1600q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v512h-224q-13 0 -22.5 9.5t-9.5 22.5v800q0 132 94 226t226 94h256q26 0 45 -19t19 -45z" />
<glyph unicode="&#xf0f6;" horiz-adv-x="1280" d="M1024 352v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704q14 0 23 -9t9 -23zM1024 608v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704q14 0 23 -9t9 -23zM128 0h1024v768h-416q-40 0 -68 28t-28 68v416h-512v-1280z M768 896h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376zM1280 864v-896q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h640q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88z" />
<glyph unicode="&#xf0f7;" horiz-adv-x="1408" d="M384 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M1152 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M1152 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M1152 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M896 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M896 -128h384v1536h-1152v-1536h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224zM1408 1472v-1664q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1664q0 26 19 45t45 19h1280q26 0 45 -19t19 -45z" />
<glyph unicode="&#xf0f8;" horiz-adv-x="1408" d="M384 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M1152 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M896 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M896 -128h384v1152h-256v-32q0 -40 -28 -68t-68 -28h-448q-40 0 -68 28t-28 68v32h-256v-1152h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224zM896 1056v320q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-96h-128v96q0 13 -9.5 22.5 t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5v96h128v-96q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1408 1088v-1280q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1280q0 26 19 45t45 19h320 v288q0 40 28 68t68 28h448q40 0 68 -28t28 -68v-288h320q26 0 45 -19t19 -45z" />
<glyph unicode="&#xf0f9;" horiz-adv-x="1920" d="M640 128q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM256 640h384v256h-158q-14 -2 -22 -9l-195 -195q-7 -12 -9 -22v-30zM1536 128q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5 t90.5 37.5t37.5 90.5zM1664 800v192q0 14 -9 23t-23 9h-224v224q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-224h-224q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v224h224q14 0 23 9t9 23zM1920 1344v-1152 q0 -26 -19 -45t-45 -19h-192q0 -106 -75 -181t-181 -75t-181 75t-75 181h-384q0 -106 -75 -181t-181 -75t-181 75t-75 181h-128q-26 0 -45 19t-19 45t19 45t45 19v416q0 26 13 58t32 51l198 198q19 19 51 32t58 13h160v320q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
<glyph unicode="&#xf0fa;" horiz-adv-x="1792" d="M1280 416v192q0 14 -9 23t-23 9h-224v224q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-224h-224q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v224h224q14 0 23 9t9 23zM640 1152h512v128h-512v-128zM256 1152v-1280h-32 q-92 0 -158 66t-66 158v832q0 92 66 158t158 66h32zM1440 1152v-1280h-1088v1280h160v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h160zM1792 928v-832q0 -92 -66 -158t-158 -66h-32v1280h32q92 0 158 -66t66 -158z" />
<glyph unicode="&#xf0fb;" horiz-adv-x="1920" d="M1920 576q-1 -32 -288 -96l-352 -32l-224 -64h-64l-293 -352h69q26 0 45 -4.5t19 -11.5t-19 -11.5t-45 -4.5h-96h-160h-64v32h64v416h-160l-192 -224h-96l-32 32v192h32v32h128v8l-192 24v128l192 24v8h-128v32h-32v192l32 32h96l192 -224h160v416h-64v32h64h160h96 q26 0 45 -4.5t19 -11.5t-19 -11.5t-45 -4.5h-69l293 -352h64l224 -64l352 -32q261 -58 287 -93z" />
<glyph unicode="&#xf0fc;" horiz-adv-x="1664" d="M640 640v384h-256v-256q0 -53 37.5 -90.5t90.5 -37.5h128zM1664 192v-192h-1152v192l128 192h-128q-159 0 -271.5 112.5t-112.5 271.5v320l-64 64l32 128h480l32 128h960l32 -192l-64 -32v-800z" />
<glyph unicode="&#xf0fd;" d="M1280 192v896q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-512v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-896q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h512v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1536 1120v-960 q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
<glyph unicode="&#xf0fe;" d="M1280 576v128q0 26 -19 45t-45 19h-320v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-320q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h320v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h320q26 0 45 19t19 45zM1536 1120v-960 q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
<glyph unicode="&#xf100;" horiz-adv-x="1024" d="M627 160q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23zM1011 160q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23 t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23z" />
<glyph unicode="&#xf101;" horiz-adv-x="1024" d="M595 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23zM979 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23 l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" />
<glyph unicode="&#xf102;" horiz-adv-x="1152" d="M1075 224q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23zM1075 608q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393 q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" />
<glyph unicode="&#xf103;" horiz-adv-x="1152" d="M1075 672q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23zM1075 1056q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23 t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" />
<glyph unicode="&#xf104;" horiz-adv-x="640" d="M627 992q0 -13 -10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" />
<glyph unicode="&#xf105;" horiz-adv-x="640" d="M595 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" />
<glyph unicode="&#xf106;" horiz-adv-x="1152" d="M1075 352q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" />
<glyph unicode="&#xf107;" horiz-adv-x="1152" d="M1075 800q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" />
<glyph unicode="&#xf108;" horiz-adv-x="1920" d="M1792 544v832q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-832q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5zM1920 1376v-1088q0 -66 -47 -113t-113 -47h-544q0 -37 16 -77.5t32 -71t16 -43.5q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19 t-19 45q0 14 16 44t32 70t16 78h-544q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
<glyph unicode="&#xf109;" horiz-adv-x="1920" d="M416 256q-66 0 -113 47t-47 113v704q0 66 47 113t113 47h1088q66 0 113 -47t47 -113v-704q0 -66 -47 -113t-113 -47h-1088zM384 1120v-704q0 -13 9.5 -22.5t22.5 -9.5h1088q13 0 22.5 9.5t9.5 22.5v704q0 13 -9.5 22.5t-22.5 9.5h-1088q-13 0 -22.5 -9.5t-9.5 -22.5z M1760 192h160v-96q0 -40 -47 -68t-113 -28h-1600q-66 0 -113 28t-47 68v96h160h1600zM1040 96q16 0 16 16t-16 16h-160q-16 0 -16 -16t16 -16h160z" />
<glyph unicode="&#xf10a;" horiz-adv-x="1152" d="M640 128q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1024 288v960q0 13 -9.5 22.5t-22.5 9.5h-832q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h832q13 0 22.5 9.5t9.5 22.5zM1152 1248v-1088q0 -66 -47 -113t-113 -47h-832 q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h832q66 0 113 -47t47 -113z" />
<glyph unicode="&#xf10b;" horiz-adv-x="768" d="M464 128q0 33 -23.5 56.5t-56.5 23.5t-56.5 -23.5t-23.5 -56.5t23.5 -56.5t56.5 -23.5t56.5 23.5t23.5 56.5zM672 288v704q0 13 -9.5 22.5t-22.5 9.5h-512q-13 0 -22.5 -9.5t-9.5 -22.5v-704q0 -13 9.5 -22.5t22.5 -9.5h512q13 0 22.5 9.5t9.5 22.5zM480 1136 q0 16 -16 16h-160q-16 0 -16 -16t16 -16h160q16 0 16 16zM768 1152v-1024q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v1024q0 52 38 90t90 38h512q52 0 90 -38t38 -90z" />
<glyph unicode="&#xf10c;" d="M768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103 t279.5 -279.5t103 -385.5z" />
<glyph unicode="&#xf10d;" horiz-adv-x="1664" d="M768 576v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136z M1664 576v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136z" />
<glyph unicode="&#xf10e;" horiz-adv-x="1664" d="M768 1216v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136zM1664 1216 v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136z" />
<glyph unicode="&#xf110;" horiz-adv-x="1568" d="M496 192q0 -60 -42.5 -102t-101.5 -42q-60 0 -102 42t-42 102t42 102t102 42q59 0 101.5 -42t42.5 -102zM928 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM320 640q0 -66 -47 -113t-113 -47t-113 47t-47 113 t47 113t113 47t113 -47t47 -113zM1360 192q0 -46 -33 -79t-79 -33t-79 33t-33 79t33 79t79 33t79 -33t33 -79zM528 1088q0 -73 -51.5 -124.5t-124.5 -51.5t-124.5 51.5t-51.5 124.5t51.5 124.5t124.5 51.5t124.5 -51.5t51.5 -124.5zM992 1280q0 -80 -56 -136t-136 -56 t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1536 640q0 -40 -28 -68t-68 -28t-68 28t-28 68t28 68t68 28t68 -28t28 -68zM1328 1088q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5z" />
<glyph unicode="&#xf111;" d="M1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
<glyph unicode="&#xf112;" horiz-adv-x="1792" d="M1792 416q0 -166 -127 -451q-3 -7 -10.5 -24t-13.5 -30t-13 -22q-12 -17 -28 -17q-15 0 -23.5 10t-8.5 25q0 9 2.5 26.5t2.5 23.5q5 68 5 123q0 101 -17.5 181t-48.5 138.5t-80 101t-105.5 69.5t-133 42.5t-154 21.5t-175.5 6h-224v-256q0 -26 -19 -45t-45 -19t-45 19 l-512 512q-19 19 -19 45t19 45l512 512q19 19 45 19t45 -19t19 -45v-256h224q713 0 875 -403q53 -134 53 -333z" />
<glyph unicode="&#xf113;" horiz-adv-x="1664" d="M640 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1280 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1440 320 q0 120 -69 204t-187 84q-41 0 -195 -21q-71 -11 -157 -11t-157 11q-152 21 -195 21q-118 0 -187 -84t-69 -204q0 -88 32 -153.5t81 -103t122 -60t140 -29.5t149 -7h168q82 0 149 7t140 29.5t122 60t81 103t32 153.5zM1664 496q0 -207 -61 -331q-38 -77 -105.5 -133t-141 -86 t-170 -47.5t-171.5 -22t-167 -4.5q-78 0 -142 3t-147.5 12.5t-152.5 30t-137 51.5t-121 81t-86 115q-62 123 -62 331q0 237 136 396q-27 82 -27 170q0 116 51 218q108 0 190 -39.5t189 -123.5q147 35 309 35q148 0 280 -32q105 82 187 121t189 39q51 -102 51 -218 q0 -87 -27 -168q136 -160 136 -398z" />
<glyph unicode="&#xf114;" horiz-adv-x="1664" d="M1536 224v704q0 40 -28 68t-68 28h-704q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68v-960q0 -40 28 -68t68 -28h1216q40 0 68 28t28 68zM1664 928v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320 q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158z" />
<glyph unicode="&#xf115;" horiz-adv-x="1920" d="M1781 605q0 35 -53 35h-1088q-40 0 -85.5 -21.5t-71.5 -52.5l-294 -363q-18 -24 -18 -40q0 -35 53 -35h1088q40 0 86 22t71 53l294 363q18 22 18 39zM640 768h768v160q0 40 -28 68t-68 28h-576q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68 v-853l256 315q44 53 116 87.5t140 34.5zM1909 605q0 -62 -46 -120l-295 -363q-43 -53 -116 -87.5t-140 -34.5h-1088q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158v-160h192q54 0 99 -24.5t67 -70.5q15 -32 15 -68z " />
<glyph unicode="&#xf116;" horiz-adv-x="1152" d="M896 608v-64q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-224q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v224q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-224h224q14 0 23 -9t9 -23zM1024 224v704q0 40 -28 68t-68 28h-704q-40 0 -68 -28 t-28 -68v-704q0 -40 28 -68t68 -28h704q40 0 68 28t28 68zM1152 928v-704q0 -92 -65.5 -158t-158.5 -66h-704q-93 0 -158.5 66t-65.5 158v704q0 93 65.5 158.5t158.5 65.5h704q93 0 158.5 -65.5t65.5 -158.5z" />
<glyph unicode="&#xf117;" horiz-adv-x="1152" d="M928 1152q93 0 158.5 -65.5t65.5 -158.5v-704q0 -92 -65.5 -158t-158.5 -66h-704q-93 0 -158.5 66t-65.5 158v704q0 93 65.5 158.5t158.5 65.5h704zM1024 224v704q0 40 -28 68t-68 28h-704q-40 0 -68 -28t-28 -68v-704q0 -40 28 -68t68 -28h704q40 0 68 28t28 68z M864 640q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-576q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h576z" />
<glyph unicode="&#xf118;" d="M1134 461q-37 -121 -138 -195t-228 -74t-228 74t-138 195q-8 25 4 48.5t38 31.5q25 8 48.5 -4t31.5 -38q25 -80 92.5 -129.5t151.5 -49.5t151.5 49.5t92.5 129.5q8 26 32 38t49 4t37 -31.5t4 -48.5zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5 t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5 t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
<glyph unicode="&#xf119;" d="M1134 307q8 -25 -4 -48.5t-37 -31.5t-49 4t-32 38q-25 80 -92.5 129.5t-151.5 49.5t-151.5 -49.5t-92.5 -129.5q-8 -26 -31.5 -38t-48.5 -4q-26 8 -38 31.5t-4 48.5q37 121 138 195t228 74t228 -74t138 -195zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5 t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204 t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
<glyph unicode="&#xf11a;" d="M1152 448q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h640q26 0 45 -19t19 -45zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5 t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
<glyph unicode="&#xf11b;" horiz-adv-x="1920" d="M832 448v128q0 14 -9 23t-23 9h-192v192q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-192h-192q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h192v-192q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v192h192q14 0 23 9t9 23zM1408 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5 t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 640q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1920 512q0 -212 -150 -362t-362 -150q-192 0 -338 128h-220q-146 -128 -338 -128q-212 0 -362 150 t-150 362t150 362t362 150h896q212 0 362 -150t150 -362z" />
<glyph unicode="&#xf11c;" horiz-adv-x="1920" d="M384 368v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM512 624v-96q0 -16 -16 -16h-224q-16 0 -16 16v96q0 16 16 16h224q16 0 16 -16zM384 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1408 368v-96q0 -16 -16 -16 h-864q-16 0 -16 16v96q0 16 16 16h864q16 0 16 -16zM768 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM640 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1024 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16 h96q16 0 16 -16zM896 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1280 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1664 368v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1152 880v-96 q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1408 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1664 880v-352q0 -16 -16 -16h-224q-16 0 -16 16v96q0 16 16 16h112v240q0 16 16 16h96q16 0 16 -16zM1792 128v896h-1664v-896 h1664zM1920 1024v-896q0 -53 -37.5 -90.5t-90.5 -37.5h-1664q-53 0 -90.5 37.5t-37.5 90.5v896q0 53 37.5 90.5t90.5 37.5h1664q53 0 90.5 -37.5t37.5 -90.5z" />
<glyph unicode="&#xf11d;" horiz-adv-x="1792" d="M1664 491v616q-169 -91 -306 -91q-82 0 -145 32q-100 49 -184 76.5t-178 27.5q-173 0 -403 -127v-599q245 113 433 113q55 0 103.5 -7.5t98 -26t77 -31t82.5 -39.5l28 -14q44 -22 101 -22q120 0 293 92zM320 1280q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9 h-64q-14 0 -23 9t-9 23v1266q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -39 -35 -57q-10 -5 -17 -9q-218 -116 -369 -116q-88 0 -158 35l-28 14q-64 33 -99 48t-91 29t-114 14q-102 0 -235.5 -44t-228.5 -102 q-15 -9 -33 -9q-16 0 -32 8q-32 19 -32 56v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55z" />
<glyph unicode="&#xf11e;" horiz-adv-x="1792" d="M832 536v192q-181 -16 -384 -117v-185q205 96 384 110zM832 954v197q-172 -8 -384 -126v-189q215 111 384 118zM1664 491v184q-235 -116 -384 -71v224q-20 6 -39 15q-5 3 -33 17t-34.5 17t-31.5 15t-34.5 15.5t-32.5 13t-36 12.5t-35 8.5t-39.5 7.5t-39.5 4t-44 2 q-23 0 -49 -3v-222h19q102 0 192.5 -29t197.5 -82q19 -9 39 -15v-188q42 -17 91 -17q120 0 293 92zM1664 918v189q-169 -91 -306 -91q-45 0 -78 8v-196q148 -42 384 90zM320 1280q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v1266 q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -39 -35 -57q-10 -5 -17 -9q-218 -116 -369 -116q-88 0 -158 35l-28 14q-64 33 -99 48t-91 29t-114 14q-102 0 -235.5 -44t-228.5 -102q-15 -9 -33 -9q-16 0 -32 8 q-32 19 -32 56v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55z" />
<glyph unicode="&#xf120;" horiz-adv-x="1664" d="M585 553l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23zM1664 96v-64q0 -14 -9 -23t-23 -9h-960q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h960q14 0 23 -9 t9 -23z" />
<glyph unicode="&#xf121;" horiz-adv-x="1920" d="M617 137l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23zM1208 1204l-373 -1291q-4 -13 -15.5 -19.5t-23.5 -2.5l-62 17q-13 4 -19.5 15.5t-2.5 24.5 l373 1291q4 13 15.5 19.5t23.5 2.5l62 -17q13 -4 19.5 -15.5t2.5 -24.5zM1865 553l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23z" />
<glyph unicode="&#xf122;" horiz-adv-x="1792" d="M640 454v-70q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-512 512q-19 19 -19 45t19 45l512 512q29 31 70 14q39 -17 39 -59v-69l-397 -398q-19 -19 -19 -45t19 -45zM1792 416q0 -58 -17 -133.5t-38.5 -138t-48 -125t-40.5 -90.5l-20 -40q-8 -17 -28 -17q-6 0 -9 1 q-25 8 -23 34q43 400 -106 565q-64 71 -170.5 110.5t-267.5 52.5v-251q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-512 512q-19 19 -19 45t19 45l512 512q29 31 70 14q39 -17 39 -59v-262q411 -28 599 -221q169 -173 169 -509z" />
<glyph unicode="&#xf123;" horiz-adv-x="1664" d="M1186 579l257 250l-356 52l-66 10l-30 60l-159 322v-963l59 -31l318 -168l-60 355l-12 66zM1638 841l-363 -354l86 -500q5 -33 -6 -51.5t-34 -18.5q-17 0 -40 12l-449 236l-449 -236q-23 -12 -40 -12q-23 0 -34 18.5t-6 51.5l86 500l-364 354q-32 32 -23 59.5t54 34.5 l502 73l225 455q20 41 49 41q28 0 49 -41l225 -455l502 -73q45 -7 54 -34.5t-24 -59.5z" />
<glyph unicode="&#xf124;" horiz-adv-x="1408" d="M1401 1187l-640 -1280q-17 -35 -57 -35q-5 0 -15 2q-22 5 -35.5 22.5t-13.5 39.5v576h-576q-22 0 -39.5 13.5t-22.5 35.5t4 42t29 30l1280 640q13 7 29 7q27 0 45 -19q15 -14 18.5 -34.5t-6.5 -39.5z" />
<glyph unicode="&#xf125;" horiz-adv-x="1664" d="M557 256h595v595zM512 301l595 595h-595v-595zM1664 224v-192q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v224h-864q-14 0 -23 9t-9 23v864h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224v224q0 14 9 23t23 9h192q14 0 23 -9t9 -23 v-224h851l246 247q10 9 23 9t23 -9q9 -10 9 -23t-9 -23l-247 -246v-851h224q14 0 23 -9t9 -23z" />
<glyph unicode="&#xf126;" horiz-adv-x="1024" d="M288 64q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM288 1216q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM928 1088q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1024 1088q0 -52 -26 -96.5t-70 -69.5 q-2 -287 -226 -414q-68 -38 -203 -81q-128 -40 -169.5 -71t-41.5 -100v-26q44 -25 70 -69.5t26 -96.5q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 52 26 96.5t70 69.5v820q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136q0 -52 -26 -96.5t-70 -69.5v-497 q54 26 154 57q55 17 87.5 29.5t70.5 31t59 39.5t40.5 51t28 69.5t8.5 91.5q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136z" />
<glyph unicode="&#xf127;" horiz-adv-x="1664" d="M439 265l-256 -256q-10 -9 -23 -9q-12 0 -23 9q-9 10 -9 23t9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23zM608 224v-320q0 -14 -9 -23t-23 -9t-23 9t-9 23v320q0 14 9 23t23 9t23 -9t9 -23zM384 448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23t9 23t23 9h320 q14 0 23 -9t9 -23zM1648 320q0 -120 -85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-334 335q-21 21 -42 56l239 18l273 -274q27 -27 68 -27.5t68 26.5l147 146q28 28 28 67q0 40 -28 68l-274 275l18 239q35 -21 56 -42l336 -336q84 -86 84 -204zM1031 1044l-239 -18 l-273 274q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67q0 -40 28 -68l274 -274l-18 -240q-35 21 -56 42l-336 336q-84 86 -84 204q0 120 85 203l147 146q83 83 203 83q121 0 204 -85l334 -335q21 -21 42 -56zM1664 960q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9 t-9 23t9 23t23 9h320q14 0 23 -9t9 -23zM1120 1504v-320q0 -14 -9 -23t-23 -9t-23 9t-9 23v320q0 14 9 23t23 9t23 -9t9 -23zM1527 1353l-256 -256q-11 -9 -23 -9t-23 9q-9 10 -9 23t9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23z" />
<glyph unicode="&#xf128;" horiz-adv-x="1024" d="M704 280v-240q0 -16 -12 -28t-28 -12h-240q-16 0 -28 12t-12 28v240q0 16 12 28t28 12h240q16 0 28 -12t12 -28zM1020 880q0 -54 -15.5 -101t-35 -76.5t-55 -59.5t-57.5 -43.5t-61 -35.5q-41 -23 -68.5 -65t-27.5 -67q0 -17 -12 -32.5t-28 -15.5h-240q-15 0 -25.5 18.5 t-10.5 37.5v45q0 83 65 156.5t143 108.5q59 27 84 56t25 76q0 42 -46.5 74t-107.5 32q-65 0 -108 -29q-35 -25 -107 -115q-13 -16 -31 -16q-12 0 -25 8l-164 125q-13 10 -15.5 25t5.5 28q160 266 464 266q80 0 161 -31t146 -83t106 -127.5t41 -158.5z" />
<glyph unicode="&#xf129;" horiz-adv-x="640" d="M640 192v-128q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64v384h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-576h64q26 0 45 -19t19 -45zM512 1344v-192q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v192 q0 26 19 45t45 19h256q26 0 45 -19t19 -45z" />
<glyph unicode="&#xf12a;" horiz-adv-x="640" d="M512 288v-224q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v224q0 26 19 45t45 19h256q26 0 45 -19t19 -45zM542 1344l-28 -768q-1 -26 -20.5 -45t-45.5 -19h-256q-26 0 -45.5 19t-20.5 45l-28 768q-1 26 17.5 45t44.5 19h320q26 0 44.5 -19t17.5 -45z" />
<glyph unicode="&#xf12b;" d="M897 167v-167h-248l-159 252l-24 42q-8 9 -11 21h-3l-9 -21q-10 -20 -25 -44l-155 -250h-258v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109zM1534 846v-206h-514l-3 27 q-4 28 -4 46q0 64 26 117t65 86.5t84 65t84 54.5t65 54t26 64q0 38 -29.5 62.5t-70.5 24.5q-51 0 -97 -39q-14 -11 -36 -38l-105 92q26 37 63 66q83 65 188 65q110 0 178 -59.5t68 -158.5q0 -56 -24.5 -103t-62 -76.5t-81.5 -58.5t-82 -50.5t-65.5 -51.5t-30.5 -63h232v80 h126z" />
<glyph unicode="&#xf12c;" d="M897 167v-167h-248l-159 252l-24 42q-8 9 -11 21h-3l-9 -21q-10 -20 -25 -44l-155 -250h-258v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109zM1536 -50v-206h-514l-4 27 q-3 45 -3 46q0 64 26 117t65 86.5t84 65t84 54.5t65 54t26 64q0 38 -29.5 62.5t-70.5 24.5q-51 0 -97 -39q-14 -11 -36 -38l-105 92q26 37 63 66q80 65 188 65q110 0 178 -59.5t68 -158.5q0 -66 -34.5 -118.5t-84 -86t-99.5 -62.5t-87 -63t-41 -73h232v80h126z" />
<glyph unicode="&#xf12d;" horiz-adv-x="1920" d="M896 128l336 384h-768l-336 -384h768zM1909 1205q15 -34 9.5 -71.5t-30.5 -65.5l-896 -1024q-38 -44 -96 -44h-768q-38 0 -69.5 20.5t-47.5 54.5q-15 34 -9.5 71.5t30.5 65.5l896 1024q38 44 96 44h768q38 0 69.5 -20.5t47.5 -54.5z" />
<glyph unicode="&#xf12e;" horiz-adv-x="1664" d="M1664 438q0 -81 -44.5 -135t-123.5 -54q-41 0 -77.5 17.5t-59 38t-56.5 38t-71 17.5q-110 0 -110 -124q0 -39 16 -115t15 -115v-5q-22 0 -33 -1q-34 -3 -97.5 -11.5t-115.5 -13.5t-98 -5q-61 0 -103 26.5t-42 83.5q0 37 17.5 71t38 56.5t38 59t17.5 77.5q0 79 -54 123.5 t-135 44.5q-84 0 -143 -45.5t-59 -127.5q0 -43 15 -83t33.5 -64.5t33.5 -53t15 -50.5q0 -45 -46 -89q-37 -35 -117 -35q-95 0 -245 24q-9 2 -27.5 4t-27.5 4l-13 2q-1 0 -3 1q-2 0 -2 1v1024q2 -1 17.5 -3.5t34 -5t21.5 -3.5q150 -24 245 -24q80 0 117 35q46 44 46 89 q0 22 -15 50.5t-33.5 53t-33.5 64.5t-15 83q0 82 59 127.5t144 45.5q80 0 134 -44.5t54 -123.5q0 -41 -17.5 -77.5t-38 -59t-38 -56.5t-17.5 -71q0 -57 42 -83.5t103 -26.5q64 0 180 15t163 17v-2q-1 -2 -3.5 -17.5t-5 -34t-3.5 -21.5q-24 -150 -24 -245q0 -80 35 -117 q44 -46 89 -46q22 0 50.5 15t53 33.5t64.5 33.5t83 15q82 0 127.5 -59t45.5 -143z" />
<glyph unicode="&#xf130;" horiz-adv-x="1152" d="M1152 832v-128q0 -221 -147.5 -384.5t-364.5 -187.5v-132h256q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h256v132q-217 24 -364.5 187.5t-147.5 384.5v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -185 131.5 -316.5t316.5 -131.5 t316.5 131.5t131.5 316.5v128q0 26 19 45t45 19t45 -19t19 -45zM896 1216v-512q0 -132 -94 -226t-226 -94t-226 94t-94 226v512q0 132 94 226t226 94t226 -94t94 -226z" />
<glyph unicode="&#xf131;" horiz-adv-x="1408" d="M271 591l-101 -101q-42 103 -42 214v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -53 15 -113zM1385 1193l-361 -361v-128q0 -132 -94 -226t-226 -94q-55 0 -109 19l-96 -96q97 -51 205 -51q185 0 316.5 131.5t131.5 316.5v128q0 26 19 45t45 19t45 -19t19 -45v-128 q0 -221 -147.5 -384.5t-364.5 -187.5v-132h256q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h256v132q-125 13 -235 81l-254 -254q-10 -10 -23 -10t-23 10l-82 82q-10 10 -10 23t10 23l1234 1234q10 10 23 10t23 -10l82 -82q10 -10 10 -23 t-10 -23zM1005 1325l-621 -621v512q0 132 94 226t226 94q102 0 184.5 -59t116.5 -152z" />
<glyph unicode="&#xf132;" horiz-adv-x="1280" d="M1088 576v640h-448v-1137q119 63 213 137q235 184 235 360zM1280 1344v-768q0 -86 -33.5 -170.5t-83 -150t-118 -127.5t-126.5 -103t-121 -77.5t-89.5 -49.5t-42.5 -20q-12 -6 -26 -6t-26 6q-16 7 -42.5 20t-89.5 49.5t-121 77.5t-126.5 103t-118 127.5t-83 150 t-33.5 170.5v768q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
<glyph unicode="&#xf133;" horiz-adv-x="1664" d="M128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280 q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" />
<glyph unicode="&#xf134;" horiz-adv-x="1408" d="M512 1344q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 1376v-320q0 -16 -12 -25q-8 -7 -20 -7q-4 0 -7 1l-448 96q-11 2 -18 11t-7 20h-256v-102q111 -23 183.5 -111t72.5 -203v-800q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v800 q0 106 62.5 190.5t161.5 114.5v111h-32q-59 0 -115 -23.5t-91.5 -53t-66 -66.5t-40.5 -53.5t-14 -24.5q-17 -35 -57 -35q-16 0 -29 7q-23 12 -31.5 37t3.5 49q5 10 14.5 26t37.5 53.5t60.5 70t85 67t108.5 52.5q-25 42 -25 86q0 66 47 113t113 47t113 -47t47 -113 q0 -33 -14 -64h302q0 11 7 20t18 11l448 96q3 1 7 1q12 0 20 -7q12 -9 12 -25z" />
<glyph unicode="&#xf135;" horiz-adv-x="1664" d="M1440 1088q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1664 1376q0 -249 -75.5 -430.5t-253.5 -360.5q-81 -80 -195 -176l-20 -379q-2 -16 -16 -26l-384 -224q-7 -4 -16 -4q-12 0 -23 9l-64 64q-13 14 -8 32l85 276l-281 281l-276 -85q-3 -1 -9 -1 q-14 0 -23 9l-64 64q-17 19 -5 39l224 384q10 14 26 16l379 20q96 114 176 195q188 187 358 258t431 71q14 0 24 -9.5t10 -22.5z" />
<glyph unicode="&#xf136;" horiz-adv-x="1792" d="M1708 881l-188 -881h-304l181 849q4 21 1 43q-4 20 -16 35q-10 14 -28 24q-18 9 -40 9h-197l-205 -960h-303l204 960h-304l-205 -960h-304l272 1280h1139q157 0 245 -118q86 -116 52 -281z" />
<glyph unicode="&#xf137;" d="M909 141l102 102q19 19 19 45t-19 45l-307 307l307 307q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45t19 -45l454 -454q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
<glyph unicode="&#xf138;" d="M717 141l454 454q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l307 -307l-307 -307q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
<glyph unicode="&#xf139;" d="M1165 397l102 102q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19l307 307l307 -307q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
<glyph unicode="&#xf13a;" d="M813 237l454 454q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-307 -307l-307 307q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l454 -454q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
<glyph unicode="&#xf13b;" horiz-adv-x="1408" d="M1130 939l16 175h-884l47 -534h612l-22 -228l-197 -53l-196 53l-13 140h-175l22 -278l362 -100h4v1l359 99l50 544h-644l-15 181h674zM0 1408h1408l-128 -1438l-578 -162l-574 162z" />
<glyph unicode="&#xf13c;" horiz-adv-x="1792" d="M275 1408h1505l-266 -1333l-804 -267l-698 267l71 356h297l-29 -147l422 -161l486 161l68 339h-1208l58 297h1209l38 191h-1208z" />
<glyph unicode="&#xf13d;" horiz-adv-x="1792" d="M960 1280q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1792 352v-352q0 -22 -20 -30q-8 -2 -12 -2q-13 0 -23 9l-93 93q-119 -143 -318.5 -226.5t-429.5 -83.5t-429.5 83.5t-318.5 226.5l-93 -93q-9 -9 -23 -9q-4 0 -12 2q-20 8 -20 30v352 q0 14 9 23t23 9h352q22 0 30 -20q8 -19 -7 -35l-100 -100q67 -91 189.5 -153.5t271.5 -82.5v647h-192q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h192v163q-58 34 -93 92.5t-35 128.5q0 106 75 181t181 75t181 -75t75 -181q0 -70 -35 -128.5t-93 -92.5v-163h192q26 0 45 -19 t19 -45v-128q0 -26 -19 -45t-45 -19h-192v-647q149 20 271.5 82.5t189.5 153.5l-100 100q-15 16 -7 35q8 20 30 20h352q14 0 23 -9t9 -23z" />
<glyph unicode="&#xf13e;" horiz-adv-x="1152" d="M1056 768q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h32v320q0 185 131.5 316.5t316.5 131.5t316.5 -131.5t131.5 -316.5q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45q0 106 -75 181t-181 75t-181 -75t-75 -181 v-320h736z" />
<glyph unicode="&#xf140;" d="M1024 640q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM1152 640q0 159 -112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM1280 640q0 -212 -150 -362t-362 -150t-362 150 t-150 362t150 362t362 150t362 -150t150 -362zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
<glyph unicode="&#xf141;" horiz-adv-x="1408" d="M384 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM896 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM1408 800v-192q0 -40 -28 -68t-68 -28h-192 q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68z" />
<glyph unicode="&#xf142;" horiz-adv-x="384" d="M384 288v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM384 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM384 1312v-192q0 -40 -28 -68t-68 -28h-192 q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68z" />
<glyph unicode="&#xf143;" d="M512 256q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM863 162q-13 232 -177 396t-396 177q-14 1 -24 -9t-10 -23v-128q0 -13 8.5 -22t21.5 -10q154 -11 264 -121t121 -264q1 -13 10 -21.5t22 -8.5h128q13 0 23 10 t9 24zM1247 161q-5 154 -56 297.5t-139.5 260t-205 205t-260 139.5t-297.5 56q-14 1 -23 -9q-10 -10 -10 -23v-128q0 -13 9 -22t22 -10q204 -7 378 -111.5t278.5 -278.5t111.5 -378q1 -13 10 -22t22 -9h128q13 0 23 10q11 9 9 23zM1536 1120v-960q0 -119 -84.5 -203.5 t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
<glyph unicode="&#xf144;" d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM1152 585q32 18 32 55t-32 55l-544 320q-31 19 -64 1q-32 -19 -32 -56v-640q0 -37 32 -56 q16 -8 32 -8q17 0 32 9z" />
<glyph unicode="&#xf145;" horiz-adv-x="1792" d="M1024 1084l316 -316l-572 -572l-316 316zM813 105l618 618q19 19 19 45t-19 45l-362 362q-18 18 -45 18t-45 -18l-618 -618q-19 -19 -19 -45t19 -45l362 -362q18 -18 45 -18t45 18zM1702 742l-907 -908q-37 -37 -90.5 -37t-90.5 37l-126 126q56 56 56 136t-56 136 t-136 56t-136 -56l-125 126q-37 37 -37 90.5t37 90.5l907 906q37 37 90.5 37t90.5 -37l125 -125q-56 -56 -56 -136t56 -136t136 -56t136 56l126 -125q37 -37 37 -90.5t-37 -90.5z" />
<glyph unicode="&#xf146;" d="M1280 576v128q0 26 -19 45t-45 19h-896q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h896q26 0 45 19t19 45zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5 t84.5 -203.5z" />
<glyph unicode="&#xf147;" horiz-adv-x="1408" d="M1152 736v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h832q14 0 23 -9t9 -23zM1280 288v832q0 66 -47 113t-113 47h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113zM1408 1120v-832q0 -119 -84.5 -203.5 t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5z" />
<glyph unicode="&#xf148;" horiz-adv-x="1024" d="M1018 933q-18 -37 -58 -37h-192v-864q0 -14 -9 -23t-23 -9h-704q-21 0 -29 18q-8 20 4 35l160 192q9 11 25 11h320v640h-192q-40 0 -58 37q-17 37 9 68l320 384q18 22 49 22t49 -22l320 -384q27 -32 9 -68z" />
<glyph unicode="&#xf149;" horiz-adv-x="1024" d="M32 1280h704q13 0 22.5 -9.5t9.5 -23.5v-863h192q40 0 58 -37t-9 -69l-320 -384q-18 -22 -49 -22t-49 22l-320 384q-26 31 -9 69q18 37 58 37h192v640h-320q-14 0 -25 11l-160 192q-13 14 -4 34q9 19 29 19z" />
<glyph unicode="&#xf14a;" d="M685 237l614 614q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-467 -467l-211 211q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l358 -358q19 -19 45 -19t45 19zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5 t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
<glyph unicode="&#xf14b;" d="M404 428l152 -152l-52 -52h-56v96h-96v56zM818 818q14 -13 -3 -30l-291 -291q-17 -17 -30 -3q-14 13 3 30l291 291q17 17 30 3zM544 128l544 544l-288 288l-544 -544v-288h288zM1152 736l92 92q28 28 28 68t-28 68l-152 152q-28 28 -68 28t-68 -28l-92 -92zM1536 1120 v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
<glyph unicode="&#xf14c;" d="M1280 608v480q0 26 -19 45t-45 19h-480q-42 0 -59 -39q-17 -41 14 -70l144 -144l-534 -534q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19l534 534l144 -144q18 -19 45 -19q12 0 25 5q39 17 39 59zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960 q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
<glyph unicode="&#xf14d;" d="M1005 435l352 352q19 19 19 45t-19 45l-352 352q-30 31 -69 14q-40 -17 -40 -59v-160q-119 0 -216 -19.5t-162.5 -51t-114 -79t-76.5 -95.5t-44.5 -109t-21.5 -111.5t-5 -110.5q0 -181 167 -404q10 -12 25 -12q7 0 13 3q22 9 19 33q-44 354 62 473q46 52 130 75.5 t224 23.5v-160q0 -42 40 -59q12 -5 24 -5q26 0 45 19zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
<glyph unicode="&#xf14e;" d="M640 448l256 128l-256 128v-256zM1024 1039v-542l-512 -256v542zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
<glyph unicode="&#xf150;" d="M1145 861q18 -35 -5 -66l-320 -448q-19 -27 -52 -27t-52 27l-320 448q-23 31 -5 66q17 35 57 35h640q40 0 57 -35zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5zM1536 1120 v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
<glyph unicode="&#xf151;" d="M1145 419q-17 -35 -57 -35h-640q-40 0 -57 35q-18 35 5 66l320 448q19 27 52 27t52 -27l320 -448q23 -31 5 -66zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5zM1536 1120v-960 q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
<glyph unicode="&#xf152;" d="M1088 640q0 -33 -27 -52l-448 -320q-31 -23 -66 -5q-35 17 -35 57v640q0 40 35 57q35 18 66 -5l448 -320q27 -19 27 -52zM1280 160v960q0 14 -9 23t-23 9h-960q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h960q14 0 23 9t9 23zM1536 1120v-960q0 -119 -84.5 -203.5 t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
<glyph unicode="&#xf153;" horiz-adv-x="1024" d="M976 229l35 -159q3 -12 -3 -22.5t-17 -14.5l-5 -1q-4 -2 -10.5 -3.5t-16 -4.5t-21.5 -5.5t-25.5 -5t-30 -5t-33.5 -4.5t-36.5 -3t-38.5 -1q-234 0 -409 130.5t-238 351.5h-95q-13 0 -22.5 9.5t-9.5 22.5v113q0 13 9.5 22.5t22.5 9.5h66q-2 57 1 105h-67q-14 0 -23 9 t-9 23v114q0 14 9 23t23 9h98q67 210 243.5 338t400.5 128q102 0 194 -23q11 -3 20 -15q6 -11 3 -24l-43 -159q-3 -13 -14 -19.5t-24 -2.5l-4 1q-4 1 -11.5 2.5l-17.5 3.5t-22.5 3.5t-26 3t-29 2.5t-29.5 1q-126 0 -226 -64t-150 -176h468q16 0 25 -12q10 -12 7 -26 l-24 -114q-5 -26 -32 -26h-488q-3 -37 0 -105h459q15 0 25 -12q9 -12 6 -27l-24 -112q-2 -11 -11 -18.5t-20 -7.5h-387q48 -117 149.5 -185.5t228.5 -68.5q18 0 36 1.5t33.5 3.5t29.5 4.5t24.5 5t18.5 4.5l12 3l5 2q13 5 26 -2q12 -7 15 -21z" />
<glyph unicode="&#xf154;" horiz-adv-x="1024" d="M1020 399v-367q0 -14 -9 -23t-23 -9h-956q-14 0 -23 9t-9 23v150q0 13 9.5 22.5t22.5 9.5h97v383h-95q-14 0 -23 9.5t-9 22.5v131q0 14 9 23t23 9h95v223q0 171 123.5 282t314.5 111q185 0 335 -125q9 -8 10 -20.5t-7 -22.5l-103 -127q-9 -11 -22 -12q-13 -2 -23 7 q-5 5 -26 19t-69 32t-93 18q-85 0 -137 -47t-52 -123v-215h305q13 0 22.5 -9t9.5 -23v-131q0 -13 -9.5 -22.5t-22.5 -9.5h-305v-379h414v181q0 13 9 22.5t23 9.5h162q14 0 23 -9.5t9 -22.5z" />
<glyph unicode="&#xf155;" horiz-adv-x="1024" d="M978 351q0 -153 -99.5 -263.5t-258.5 -136.5v-175q0 -14 -9 -23t-23 -9h-135q-13 0 -22.5 9.5t-9.5 22.5v175q-66 9 -127.5 31t-101.5 44.5t-74 48t-46.5 37.5t-17.5 18q-17 21 -2 41l103 135q7 10 23 12q15 2 24 -9l2 -2q113 -99 243 -125q37 -8 74 -8q81 0 142.5 43 t61.5 122q0 28 -15 53t-33.5 42t-58.5 37.5t-66 32t-80 32.5q-39 16 -61.5 25t-61.5 26.5t-62.5 31t-56.5 35.5t-53.5 42.5t-43.5 49t-35.5 58t-21 66.5t-8.5 78q0 138 98 242t255 134v180q0 13 9.5 22.5t22.5 9.5h135q14 0 23 -9t9 -23v-176q57 -6 110.5 -23t87 -33.5 t63.5 -37.5t39 -29t15 -14q17 -18 5 -38l-81 -146q-8 -15 -23 -16q-14 -3 -27 7q-3 3 -14.5 12t-39 26.5t-58.5 32t-74.5 26t-85.5 11.5q-95 0 -155 -43t-60 -111q0 -26 8.5 -48t29.5 -41.5t39.5 -33t56 -31t60.5 -27t70 -27.5q53 -20 81 -31.5t76 -35t75.5 -42.5t62 -50 t53 -63.5t31.5 -76.5t13 -94z" />
<glyph unicode="&#xf156;" horiz-adv-x="898" d="M898 1066v-102q0 -14 -9 -23t-23 -9h-168q-23 -144 -129 -234t-276 -110q167 -178 459 -536q14 -16 4 -34q-8 -18 -29 -18h-195q-16 0 -25 12q-306 367 -498 571q-9 9 -9 22v127q0 13 9.5 22.5t22.5 9.5h112q132 0 212.5 43t102.5 125h-427q-14 0 -23 9t-9 23v102 q0 14 9 23t23 9h413q-57 113 -268 113h-145q-13 0 -22.5 9.5t-9.5 22.5v133q0 14 9 23t23 9h832q14 0 23 -9t9 -23v-102q0 -14 -9 -23t-23 -9h-233q47 -61 64 -144h171q14 0 23 -9t9 -23z" />
<glyph unicode="&#xf157;" horiz-adv-x="1027" d="M603 0h-172q-13 0 -22.5 9t-9.5 23v330h-288q-13 0 -22.5 9t-9.5 23v103q0 13 9.5 22.5t22.5 9.5h288v85h-288q-13 0 -22.5 9t-9.5 23v104q0 13 9.5 22.5t22.5 9.5h214l-321 578q-8 16 0 32q10 16 28 16h194q19 0 29 -18l215 -425q19 -38 56 -125q10 24 30.5 68t27.5 61 l191 420q8 19 29 19h191q17 0 27 -16q9 -14 1 -31l-313 -579h215q13 0 22.5 -9.5t9.5 -22.5v-104q0 -14 -9.5 -23t-22.5 -9h-290v-85h290q13 0 22.5 -9.5t9.5 -22.5v-103q0 -14 -9.5 -23t-22.5 -9h-290v-330q0 -13 -9.5 -22.5t-22.5 -9.5z" />
<glyph unicode="&#xf158;" horiz-adv-x="1664" d="M1664 352v-32q0 -132 -94 -226t-226 -94h-128q-132 0 -226 94t-94 226v480h-224q-2 -102 -14.5 -190.5t-30.5 -156t-48.5 -126.5t-57 -99.5t-67.5 -77.5t-69.5 -58.5t-74 -44t-69 -32t-65.5 -25.5q-4 -2 -32 -13q-8 -2 -12 -2q-22 0 -30 20l-71 178q-5 13 0 25t17 17 q7 3 20 7.5t18 6.5q31 12 46.5 18.5t44.5 20t45.5 26t42 32.5t40.5 42.5t34.5 53.5t30.5 68.5t22.5 83.5t17 103t6.5 123h-256q-14 0 -23 9t-9 23v160q0 14 9 23t23 9h1216q14 0 23 -9t9 -23v-160q0 -14 -9 -23t-23 -9h-224v-512q0 -26 19 -45t45 -19h128q26 0 45 19t19 45 v64q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1280 1376v-160q0 -14 -9 -23t-23 -9h-960q-14 0 -23 9t-9 23v160q0 14 9 23t23 9h960q14 0 23 -9t9 -23z" />
<glyph unicode="&#xf159;" horiz-adv-x="1792" d="M514 341l81 299h-159l75 -300q1 -1 1 -3t1 -3q0 1 0.5 3.5t0.5 3.5zM630 768l35 128h-292l32 -128h225zM822 768h139l-35 128h-70zM1271 340l78 300h-162l81 -299q0 -1 0.5 -3.5t1.5 -3.5q0 1 0.5 3t0.5 3zM1382 768l33 128h-297l34 -128h230zM1792 736v-64q0 -14 -9 -23 t-23 -9h-213l-164 -616q-7 -24 -31 -24h-159q-24 0 -31 24l-166 616h-209l-167 -616q-7 -24 -31 -24h-159q-11 0 -19.5 7t-10.5 17l-160 616h-208q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h175l-33 128h-142q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h109l-89 344q-5 15 5 28 q10 12 26 12h137q26 0 31 -24l90 -360h359l97 360q7 24 31 24h126q24 0 31 -24l98 -360h365l93 360q5 24 31 24h137q16 0 26 -12q10 -13 5 -28l-91 -344h111q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-145l-34 -128h179q14 0 23 -9t9 -23z" />
<glyph unicode="&#xf15a;" horiz-adv-x="1280" d="M1167 896q18 -182 -131 -258q117 -28 175 -103t45 -214q-7 -71 -32.5 -125t-64.5 -89t-97 -58.5t-121.5 -34.5t-145.5 -15v-255h-154v251q-80 0 -122 1v-252h-154v255q-18 0 -54 0.5t-55 0.5h-200l31 183h111q50 0 58 51v402h16q-6 1 -16 1v287q-13 68 -89 68h-111v164 l212 -1q64 0 97 1v252h154v-247q82 2 122 2v245h154v-252q79 -7 140 -22.5t113 -45t82.5 -78t36.5 -114.5zM952 351q0 36 -15 64t-37 46t-57.5 30.5t-65.5 18.5t-74 9t-69 3t-64.5 -1t-47.5 -1v-338q8 0 37 -0.5t48 -0.5t53 1.5t58.5 4t57 8.5t55.5 14t47.5 21t39.5 30 t24.5 40t9.5 51zM881 827q0 33 -12.5 58.5t-30.5 42t-48 28t-55 16.5t-61.5 8t-58 2.5t-54 -1t-39.5 -0.5v-307q5 0 34.5 -0.5t46.5 0t50 2t55 5.5t51.5 11t48.5 18.5t37 27t27 38.5t9 51z" />
<glyph unicode="&#xf15b;" horiz-adv-x="1280" d="M1280 768v-800q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h544v-544q0 -40 28 -68t68 -28h544zM1277 896h-509v509q82 -15 132 -65l312 -312q50 -50 65 -132z" />
<glyph unicode="&#xf15c;" horiz-adv-x="1280" d="M1024 160v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23zM1024 416v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23zM1280 768v-800q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28 t-28 68v1344q0 40 28 68t68 28h544v-544q0 -40 28 -68t68 -28h544zM1277 896h-509v509q82 -15 132 -65l312 -312q50 -50 65 -132z" />
<glyph unicode="&#xf15d;" horiz-adv-x="1664" d="M1191 1128h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18t-7.5 -29zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1572 -23 v-233h-584v90l369 529q12 18 21 27l11 9v3q-2 0 -6.5 -0.5t-7.5 -0.5q-12 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530q-6 -8 -21 -26l-11 -11v-2l14 2q9 2 30 2h248v119h121zM1661 874v-106h-288v106h75l-47 144h-243l-47 -144h75v-106h-287v106h70l230 662h162 l230 -662h70z" />
<glyph unicode="&#xf15e;" horiz-adv-x="1664" d="M1191 104h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18t-7.5 -29zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1661 -150 v-106h-288v106h75l-47 144h-243l-47 -144h75v-106h-287v106h70l230 662h162l230 -662h70zM1572 1001v-233h-584v90l369 529q12 18 21 27l11 9v3q-2 0 -6.5 -0.5t-7.5 -0.5q-12 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530q-6 -8 -21 -26l-11 -10v-3l14 3q9 1 30 1h248 v119h121z" />
<glyph unicode="&#xf160;" horiz-adv-x="1792" d="M736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1792 -32v-192q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h832 q14 0 23 -9t9 -23zM1600 480v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23zM1408 992v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23zM1216 1504v-192q0 -14 -9 -23t-23 -9h-256 q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h256q14 0 23 -9t9 -23z" />
<glyph unicode="&#xf161;" horiz-adv-x="1792" d="M1216 -32v-192q0 -14 -9 -23t-23 -9h-256q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h256q14 0 23 -9t9 -23zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192 q14 0 23 -9t9 -23zM1408 480v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23zM1600 992v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23zM1792 1504v-192q0 -14 -9 -23t-23 -9h-832 q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h832q14 0 23 -9t9 -23z" />
<glyph unicode="&#xf162;" d="M1346 223q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94t36.5 -95t104.5 -38q50 0 85 27t35 68zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23 zM1486 165q0 -62 -13 -121.5t-41 -114t-68 -95.5t-98.5 -65.5t-127.5 -24.5q-62 0 -108 16q-24 8 -42 15l39 113q15 -7 31 -11q37 -13 75 -13q84 0 134.5 58.5t66.5 145.5h-2q-21 -23 -61.5 -37t-84.5 -14q-106 0 -173 71.5t-67 172.5q0 105 72 178t181 73q123 0 205 -94.5 t82 -252.5zM1456 882v-114h-469v114h167v432q0 7 0.5 19t0.5 17v16h-2l-7 -12q-8 -13 -26 -31l-62 -58l-82 86l192 185h123v-654h165z" />
<glyph unicode="&#xf163;" d="M1346 1247q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94t36.5 -95t104.5 -38q50 0 85 27t35 68zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9 t9 -23zM1456 -142v-114h-469v114h167v432q0 7 0.5 19t0.5 17v16h-2l-7 -12q-8 -13 -26 -31l-62 -58l-82 86l192 185h123v-654h165zM1486 1189q0 -62 -13 -121.5t-41 -114t-68 -95.5t-98.5 -65.5t-127.5 -24.5q-62 0 -108 16q-24 8 -42 15l39 113q15 -7 31 -11q37 -13 75 -13 q84 0 134.5 58.5t66.5 145.5h-2q-21 -23 -61.5 -37t-84.5 -14q-106 0 -173 71.5t-67 172.5q0 105 72 178t181 73q123 0 205 -94.5t82 -252.5z" />
<glyph unicode="&#xf164;" horiz-adv-x="1664" d="M256 192q0 26 -19 45t-45 19q-27 0 -45.5 -19t-18.5 -45q0 -27 18.5 -45.5t45.5 -18.5q26 0 45 18.5t19 45.5zM416 704v-640q0 -26 -19 -45t-45 -19h-288q-26 0 -45 19t-19 45v640q0 26 19 45t45 19h288q26 0 45 -19t19 -45zM1600 704q0 -86 -55 -149q15 -44 15 -76 q3 -76 -43 -137q17 -56 0 -117q-15 -57 -54 -94q9 -112 -49 -181q-64 -76 -197 -78h-36h-76h-17q-66 0 -144 15.5t-121.5 29t-120.5 39.5q-123 43 -158 44q-26 1 -45 19.5t-19 44.5v641q0 25 18 43.5t43 20.5q24 2 76 59t101 121q68 87 101 120q18 18 31 48t17.5 48.5 t13.5 60.5q7 39 12.5 61t19.5 52t34 50q19 19 45 19q46 0 82.5 -10.5t60 -26t40 -40.5t24 -45t12 -50t5 -45t0.5 -39q0 -38 -9.5 -76t-19 -60t-27.5 -56q-3 -6 -10 -18t-11 -22t-8 -24h277q78 0 135 -57t57 -135z" />
<glyph unicode="&#xf165;" horiz-adv-x="1664" d="M256 960q0 -26 -19 -45t-45 -19q-27 0 -45.5 19t-18.5 45q0 27 18.5 45.5t45.5 18.5q26 0 45 -18.5t19 -45.5zM416 448v640q0 26 -19 45t-45 19h-288q-26 0 -45 -19t-19 -45v-640q0 -26 19 -45t45 -19h288q26 0 45 19t19 45zM1545 597q55 -61 55 -149q-1 -78 -57.5 -135 t-134.5 -57h-277q4 -14 8 -24t11 -22t10 -18q18 -37 27 -57t19 -58.5t10 -76.5q0 -24 -0.5 -39t-5 -45t-12 -50t-24 -45t-40 -40.5t-60 -26t-82.5 -10.5q-26 0 -45 19q-20 20 -34 50t-19.5 52t-12.5 61q-9 42 -13.5 60.5t-17.5 48.5t-31 48q-33 33 -101 120q-49 64 -101 121 t-76 59q-25 2 -43 20.5t-18 43.5v641q0 26 19 44.5t45 19.5q35 1 158 44q77 26 120.5 39.5t121.5 29t144 15.5h17h76h36q133 -2 197 -78q58 -69 49 -181q39 -37 54 -94q17 -61 0 -117q46 -61 43 -137q0 -32 -15 -76z" />
<glyph unicode="&#xf166;" d="M919 233v157q0 50 -29 50q-17 0 -33 -16v-224q16 -16 33 -16q29 0 29 49zM1103 355h66v34q0 51 -33 51t-33 -51v-34zM532 621v-70h-80v-423h-74v423h-78v70h232zM733 495v-367h-67v40q-39 -45 -76 -45q-33 0 -42 28q-6 16 -6 54v290h66v-270q0 -24 1 -26q1 -15 15 -15 q20 0 42 31v280h67zM985 384v-146q0 -52 -7 -73q-12 -42 -53 -42q-35 0 -68 41v-36h-67v493h67v-161q32 40 68 40q41 0 53 -42q7 -21 7 -74zM1236 255v-9q0 -29 -2 -43q-3 -22 -15 -40q-27 -40 -80 -40q-52 0 -81 38q-21 27 -21 86v129q0 59 20 86q29 38 80 38t78 -38 q21 -28 21 -86v-76h-133v-65q0 -51 34 -51q24 0 30 26q0 1 0.5 7t0.5 16.5v21.5h68zM785 1079v-156q0 -51 -32 -51t-32 51v156q0 52 32 52t32 -52zM1318 366q0 177 -19 260q-10 44 -43 73.5t-76 34.5q-136 15 -412 15q-275 0 -411 -15q-44 -5 -76.5 -34.5t-42.5 -73.5 q-20 -87 -20 -260q0 -176 20 -260q10 -43 42.5 -73t75.5 -35q137 -15 412 -15t412 15q43 5 75.5 35t42.5 73q20 84 20 260zM563 1017l90 296h-75l-51 -195l-53 195h-78l24 -69t23 -69q35 -103 46 -158v-201h74v201zM852 936v130q0 58 -21 87q-29 38 -78 38q-51 0 -78 -38 q-21 -29 -21 -87v-130q0 -58 21 -87q27 -38 78 -38q49 0 78 38q21 27 21 87zM1033 816h67v370h-67v-283q-22 -31 -42 -31q-15 0 -16 16q-1 2 -1 26v272h-67v-293q0 -37 6 -55q11 -27 43 -27q36 0 77 45v-40zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960 q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
<glyph unicode="&#xf167;" d="M971 292v-211q0 -67 -39 -67q-23 0 -45 22v301q22 22 45 22q39 0 39 -67zM1309 291v-46h-90v46q0 68 45 68t45 -68zM343 509h107v94h-312v-94h105v-569h100v569zM631 -60h89v494h-89v-378q-30 -42 -57 -42q-18 0 -21 21q-1 3 -1 35v364h-89v-391q0 -49 8 -73 q12 -37 58 -37q48 0 102 61v-54zM1060 88v197q0 73 -9 99q-17 56 -71 56q-50 0 -93 -54v217h-89v-663h89v48q45 -55 93 -55q54 0 71 55q9 27 9 100zM1398 98v13h-91q0 -51 -2 -61q-7 -36 -40 -36q-46 0 -46 69v87h179v103q0 79 -27 116q-39 51 -106 51q-68 0 -107 -51 q-28 -37 -28 -116v-173q0 -79 29 -116q39 -51 108 -51q72 0 108 53q18 27 21 54q2 9 2 58zM790 1011v210q0 69 -43 69t-43 -69v-210q0 -70 43 -70t43 70zM1509 260q0 -234 -26 -350q-14 -59 -58 -99t-102 -46q-184 -21 -555 -21t-555 21q-58 6 -102.5 46t-57.5 99 q-26 112 -26 350q0 234 26 350q14 59 58 99t103 47q183 20 554 20t555 -20q58 -7 102.5 -47t57.5 -99q26 -112 26 -350zM511 1536h102l-121 -399v-271h-100v271q-14 74 -61 212q-37 103 -65 187h106l71 -263zM881 1203v-175q0 -81 -28 -118q-37 -51 -106 -51q-67 0 -105 51 q-28 38 -28 118v175q0 80 28 117q38 51 105 51q69 0 106 -51q28 -37 28 -117zM1216 1365v-499h-91v55q-53 -62 -103 -62q-46 0 -59 37q-8 24 -8 75v394h91v-367q0 -33 1 -35q3 -22 21 -22q27 0 57 43v381h91z" />
<glyph unicode="&#xf168;" horiz-adv-x="1408" d="M597 869q-10 -18 -257 -456q-27 -46 -65 -46h-239q-21 0 -31 17t0 36l253 448q1 0 0 1l-161 279q-12 22 -1 37q9 15 32 15h239q40 0 66 -45zM1403 1511q11 -16 0 -37l-528 -934v-1l336 -615q11 -20 1 -37q-10 -15 -32 -15h-239q-42 0 -66 45l-339 622q18 32 531 942 q25 45 64 45h241q22 0 31 -15z" />
<glyph unicode="&#xf169;" d="M685 771q0 1 -126 222q-21 34 -52 34h-184q-18 0 -26 -11q-7 -12 1 -29l125 -216v-1l-196 -346q-9 -14 0 -28q8 -13 24 -13h185q31 0 50 36zM1309 1268q-7 12 -24 12h-187q-30 0 -49 -35l-411 -729q1 -2 262 -481q20 -35 52 -35h184q18 0 25 12q8 13 -1 28l-260 476v1 l409 723q8 16 0 28zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
<glyph unicode="&#xf16a;" horiz-adv-x="1792" d="M1280 640q0 37 -30 54l-512 320q-31 20 -65 2q-33 -18 -33 -56v-640q0 -38 33 -56q16 -8 31 -8q20 0 34 10l512 320q30 17 30 54zM1792 640q0 -96 -1 -150t-8.5 -136.5t-22.5 -147.5q-16 -73 -69 -123t-124 -58q-222 -25 -671 -25t-671 25q-71 8 -124.5 58t-69.5 123 q-14 65 -21.5 147.5t-8.5 136.5t-1 150t1 150t8.5 136.5t22.5 147.5q16 73 69 123t124 58q222 25 671 25t671 -25q71 -8 124.5 -58t69.5 -123q14 -65 21.5 -147.5t8.5 -136.5t1 -150z" />
<glyph unicode="&#xf16b;" horiz-adv-x="1792" d="M402 829l494 -305l-342 -285l-490 319zM1388 274v-108l-490 -293v-1l-1 1l-1 -1v1l-489 293v108l147 -96l342 284v2l1 -1l1 1v-2l343 -284zM554 1418l342 -285l-494 -304l-338 270zM1390 829l338 -271l-489 -319l-343 285zM1239 1418l489 -319l-338 -270l-494 304z" />
<glyph unicode="&#xf16c;" horiz-adv-x="1408" d="M928 135v-151l-707 -1v151zM1169 481v-701l-1 -35v-1h-1132l-35 1h-1v736h121v-618h928v618h120zM241 393l704 -65l-13 -150l-705 65zM309 709l683 -183l-39 -146l-683 183zM472 1058l609 -360l-77 -130l-609 360zM832 1389l398 -585l-124 -85l-399 584zM1285 1536 l121 -697l-149 -26l-121 697z" />
<glyph unicode="&#xf16d;" d="M1362 110v648h-135q20 -63 20 -131q0 -126 -64 -232.5t-174 -168.5t-240 -62q-197 0 -337 135.5t-140 327.5q0 68 20 131h-141v-648q0 -26 17.5 -43.5t43.5 -17.5h1069q25 0 43 17.5t18 43.5zM1078 643q0 124 -90.5 211.5t-218.5 87.5q-127 0 -217.5 -87.5t-90.5 -211.5 t90.5 -211.5t217.5 -87.5q128 0 218.5 87.5t90.5 211.5zM1362 1003v165q0 28 -20 48.5t-49 20.5h-174q-29 0 -49 -20.5t-20 -48.5v-165q0 -29 20 -49t49 -20h174q29 0 49 20t20 49zM1536 1211v-1142q0 -81 -58 -139t-139 -58h-1142q-81 0 -139 58t-58 139v1142q0 81 58 139 t139 58h1142q81 0 139 -58t58 -139z" />
<glyph unicode="&#xf16e;" d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960zM698 640q0 88 -62 150t-150 62t-150 -62t-62 -150t62 -150t150 -62t150 62t62 150zM1262 640q0 88 -62 150 t-150 62t-150 -62t-62 -150t62 -150t150 -62t150 62t62 150z" />
<glyph unicode="&#xf170;" d="M768 914l201 -306h-402zM1133 384h94l-459 691l-459 -691h94l104 160h522zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
<glyph unicode="&#xf171;" horiz-adv-x="1408" d="M815 677q8 -63 -50.5 -101t-111.5 -6q-39 17 -53.5 58t-0.5 82t52 58q36 18 72.5 12t64 -35.5t27.5 -67.5zM926 698q-14 107 -113 164t-197 13q-63 -28 -100.5 -88.5t-34.5 -129.5q4 -91 77.5 -155t165.5 -56q91 8 152 84t50 168zM1165 1240q-20 27 -56 44.5t-58 22 t-71 12.5q-291 47 -566 -2q-43 -7 -66 -12t-55 -22t-50 -43q30 -28 76 -45.5t73.5 -22t87.5 -11.5q228 -29 448 -1q63 8 89.5 12t72.5 21.5t75 46.5zM1222 205q-8 -26 -15.5 -76.5t-14 -84t-28.5 -70t-58 -56.5q-86 -48 -189.5 -71.5t-202 -22t-201.5 18.5q-46 8 -81.5 18 t-76.5 27t-73 43.5t-52 61.5q-25 96 -57 292l6 16l18 9q223 -148 506.5 -148t507.5 148q21 -6 24 -23t-5 -45t-8 -37zM1403 1166q-26 -167 -111 -655q-5 -30 -27 -56t-43.5 -40t-54.5 -31q-252 -126 -610 -88q-248 27 -394 139q-15 12 -25.5 26.5t-17 35t-9 34t-6 39.5 t-5.5 35q-9 50 -26.5 150t-28 161.5t-23.5 147.5t-22 158q3 26 17.5 48.5t31.5 37.5t45 30t46 22.5t48 18.5q125 46 313 64q379 37 676 -50q155 -46 215 -122q16 -20 16.5 -51t-5.5 -54z" />
<glyph unicode="&#xf172;" d="M848 666q0 43 -41 66t-77 1q-43 -20 -42.5 -72.5t43.5 -70.5q39 -23 81 4t36 72zM928 682q8 -66 -36 -121t-110 -61t-119 40t-56 113q-2 49 25.5 93t72.5 64q70 31 141.5 -10t81.5 -118zM1100 1073q-20 -21 -53.5 -34t-53 -16t-63.5 -8q-155 -20 -324 0q-44 6 -63 9.5 t-52.5 16t-54.5 32.5q13 19 36 31t40 15.5t47 8.5q198 35 408 1q33 -5 51 -8.5t43 -16t39 -31.5zM1142 327q0 7 5.5 26.5t3 32t-17.5 16.5q-161 -106 -365 -106t-366 106l-12 -6l-5 -12q26 -154 41 -210q47 -81 204 -108q249 -46 428 53q34 19 49 51.5t22.5 85.5t12.5 71z M1272 1020q9 53 -8 75q-43 55 -155 88q-216 63 -487 36q-132 -12 -226 -46q-38 -15 -59.5 -25t-47 -34t-29.5 -54q8 -68 19 -138t29 -171t24 -137q1 -5 5 -31t7 -36t12 -27t22 -28q105 -80 284 -100q259 -28 440 63q24 13 39.5 23t31 29t19.5 40q48 267 80 473zM1536 1120 v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
<glyph unicode="&#xf173;" horiz-adv-x="1024" d="M390 1408h219v-388h364v-241h-364v-394q0 -136 14 -172q13 -37 52 -60q50 -31 117 -31q117 0 232 76v-242q-102 -48 -178 -65q-77 -19 -173 -19q-105 0 -186 27q-78 25 -138 75q-58 51 -79 105q-22 54 -22 161v539h-170v217q91 30 155 84q64 55 103 132q39 78 54 196z " />
<glyph unicode="&#xf174;" d="M1123 127v181q-88 -56 -174 -56q-51 0 -88 23q-29 17 -39 45q-11 30 -11 129v295h274v181h-274v291h-164q-11 -90 -40 -147t-78 -99q-48 -40 -116 -63v-163h127v-404q0 -78 17 -121q17 -42 59 -78q43 -37 104 -57q62 -20 140 -20q67 0 129 14q57 13 134 49zM1536 1120 v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
<glyph unicode="&#xf175;" horiz-adv-x="768" d="M765 237q8 -19 -5 -35l-350 -384q-10 -10 -23 -10q-14 0 -24 10l-355 384q-13 16 -5 35q9 19 29 19h224v1248q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1248h224q21 0 29 -19z" />
<glyph unicode="&#xf176;" horiz-adv-x="768" d="M765 1043q-9 -19 -29 -19h-224v-1248q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v1248h-224q-21 0 -29 19t5 35l350 384q10 10 23 10q14 0 24 -10l355 -384q13 -16 5 -35z" />
<glyph unicode="&#xf177;" horiz-adv-x="1792" d="M1792 736v-192q0 -14 -9 -23t-23 -9h-1248v-224q0 -21 -19 -29t-35 5l-384 350q-10 10 -10 23q0 14 10 24l384 354q16 14 35 6q19 -9 19 -29v-224h1248q14 0 23 -9t9 -23z" />
<glyph unicode="&#xf178;" horiz-adv-x="1792" d="M1728 643q0 -14 -10 -24l-384 -354q-16 -14 -35 -6q-19 9 -19 29v224h-1248q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h1248v224q0 21 19 29t35 -5l384 -350q10 -10 10 -23z" />
<glyph unicode="&#xf179;" horiz-adv-x="1408" d="M1393 321q-39 -125 -123 -250q-129 -196 -257 -196q-49 0 -140 32q-86 32 -151 32q-61 0 -142 -33q-81 -34 -132 -34q-152 0 -301 259q-147 261 -147 503q0 228 113 374q112 144 284 144q72 0 177 -30q104 -30 138 -30q45 0 143 34q102 34 173 34q119 0 213 -65 q52 -36 104 -100q-79 -67 -114 -118q-65 -94 -65 -207q0 -124 69 -223t158 -126zM1017 1494q0 -61 -29 -136q-30 -75 -93 -138q-54 -54 -108 -72q-37 -11 -104 -17q3 149 78 257q74 107 250 148q1 -3 2.5 -11t2.5 -11q0 -4 0.5 -10t0.5 -10z" />
<glyph unicode="&#xf17a;" horiz-adv-x="1664" d="M682 530v-651l-682 94v557h682zM682 1273v-659h-682v565zM1664 530v-786l-907 125v661h907zM1664 1408v-794h-907v669z" />
<glyph unicode="&#xf17b;" horiz-adv-x="1408" d="M493 1053q16 0 27.5 11.5t11.5 27.5t-11.5 27.5t-27.5 11.5t-27 -11.5t-11 -27.5t11 -27.5t27 -11.5zM915 1053q16 0 27 11.5t11 27.5t-11 27.5t-27 11.5t-27.5 -11.5t-11.5 -27.5t11.5 -27.5t27.5 -11.5zM103 869q42 0 72 -30t30 -72v-430q0 -43 -29.5 -73t-72.5 -30 t-73 30t-30 73v430q0 42 30 72t73 30zM1163 850v-666q0 -46 -32 -78t-77 -32h-75v-227q0 -43 -30 -73t-73 -30t-73 30t-30 73v227h-138v-227q0 -43 -30 -73t-73 -30q-42 0 -72 30t-30 73l-1 227h-74q-46 0 -78 32t-32 78v666h918zM931 1255q107 -55 171 -153.5t64 -215.5 h-925q0 117 64 215.5t172 153.5l-71 131q-7 13 5 20q13 6 20 -6l72 -132q95 42 201 42t201 -42l72 132q7 12 20 6q12 -7 5 -20zM1408 767v-430q0 -43 -30 -73t-73 -30q-42 0 -72 30t-30 73v430q0 43 30 72.5t72 29.5q43 0 73 -29.5t30 -72.5z" />
<glyph unicode="&#xf17c;" d="M663 1125q-11 -1 -15.5 -10.5t-8.5 -9.5q-5 -1 -5 5q0 12 19 15h10zM750 1111q-4 -1 -11.5 6.5t-17.5 4.5q24 11 32 -2q3 -6 -3 -9zM399 684q-4 1 -6 -3t-4.5 -12.5t-5.5 -13.5t-10 -13q-7 -10 -1 -12q4 -1 12.5 7t12.5 18q1 3 2 7t2 6t1.5 4.5t0.5 4v3t-1 2.5t-3 2z M1254 325q0 18 -55 42q4 15 7.5 27.5t5 26t3 21.5t0.5 22.5t-1 19.5t-3.5 22t-4 20.5t-5 25t-5.5 26.5q-10 48 -47 103t-72 75q24 -20 57 -83q87 -162 54 -278q-11 -40 -50 -42q-31 -4 -38.5 18.5t-8 83.5t-11.5 107q-9 39 -19.5 69t-19.5 45.5t-15.5 24.5t-13 15t-7.5 7 q-14 62 -31 103t-29.5 56t-23.5 33t-15 40q-4 21 6 53.5t4.5 49.5t-44.5 25q-15 3 -44.5 18t-35.5 16q-8 1 -11 26t8 51t36 27q37 3 51 -30t4 -58q-11 -19 -2 -26.5t30 -0.5q13 4 13 36v37q-5 30 -13.5 50t-21 30.5t-23.5 15t-27 7.5q-107 -8 -89 -134q0 -15 -1 -15 q-9 9 -29.5 10.5t-33 -0.5t-15.5 5q1 57 -16 90t-45 34q-27 1 -41.5 -27.5t-16.5 -59.5q-1 -15 3.5 -37t13 -37.5t15.5 -13.5q10 3 16 14q4 9 -7 8q-7 0 -15.5 14.5t-9.5 33.5q-1 22 9 37t34 14q17 0 27 -21t9.5 -39t-1.5 -22q-22 -15 -31 -29q-8 -12 -27.5 -23.5 t-20.5 -12.5q-13 -14 -15.5 -27t7.5 -18q14 -8 25 -19.5t16 -19t18.5 -13t35.5 -6.5q47 -2 102 15q2 1 23 7t34.5 10.5t29.5 13t21 17.5q9 14 20 8q5 -3 6.5 -8.5t-3 -12t-16.5 -9.5q-20 -6 -56.5 -21.5t-45.5 -19.5q-44 -19 -70 -23q-25 -5 -79 2q-10 2 -9 -2t17 -19 q25 -23 67 -22q17 1 36 7t36 14t33.5 17.5t30 17t24.5 12t17.5 2.5t8.5 -11q0 -2 -1 -4.5t-4 -5t-6 -4.5t-8.5 -5t-9 -4.5t-10 -5t-9.5 -4.5q-28 -14 -67.5 -44t-66.5 -43t-49 -1q-21 11 -63 73q-22 31 -25 22q-1 -3 -1 -10q0 -25 -15 -56.5t-29.5 -55.5t-21 -58t11.5 -63 q-23 -6 -62.5 -90t-47.5 -141q-2 -18 -1.5 -69t-5.5 -59q-8 -24 -29 -3q-32 31 -36 94q-2 28 4 56q4 19 -1 18l-4 -5q-36 -65 10 -166q5 -12 25 -28t24 -20q20 -23 104 -90.5t93 -76.5q16 -15 17.5 -38t-14 -43t-45.5 -23q8 -15 29 -44.5t28 -54t7 -70.5q46 24 7 92 q-4 8 -10.5 16t-9.5 12t-2 6q3 5 13 9.5t20 -2.5q46 -52 166 -36q133 15 177 87q23 38 34 30q12 -6 10 -52q-1 -25 -23 -92q-9 -23 -6 -37.5t24 -15.5q3 19 14.5 77t13.5 90q2 21 -6.5 73.5t-7.5 97t23 70.5q15 18 51 18q1 37 34.5 53t72.5 10.5t60 -22.5zM626 1152 q3 17 -2.5 30t-11.5 15q-9 2 -9 -7q2 -5 5 -6q10 0 7 -15q-3 -20 8 -20q3 0 3 3zM1045 955q-2 8 -6.5 11.5t-13 5t-14.5 5.5q-5 3 -9.5 8t-7 8t-5.5 6.5t-4 4t-4 -1.5q-14 -16 7 -43.5t39 -31.5q9 -1 14.5 8t3.5 20zM867 1168q0 11 -5 19.5t-11 12.5t-9 3q-14 -1 -7 -7l4 -2 q14 -4 18 -31q0 -3 8 2zM921 1401q0 2 -2.5 5t-9 7t-9.5 6q-15 15 -24 15q-9 -1 -11.5 -7.5t-1 -13t-0.5 -12.5q-1 -4 -6 -10.5t-6 -9t3 -8.5q4 -3 8 0t11 9t15 9q1 1 9 1t15 2t9 7zM1486 60q20 -12 31 -24.5t12 -24t-2.5 -22.5t-15.5 -22t-23.5 -19.5t-30 -18.5 t-31.5 -16.5t-32 -15.5t-27 -13q-38 -19 -85.5 -56t-75.5 -64q-17 -16 -68 -19.5t-89 14.5q-18 9 -29.5 23.5t-16.5 25.5t-22 19.5t-47 9.5q-44 1 -130 1q-19 0 -57 -1.5t-58 -2.5q-44 -1 -79.5 -15t-53.5 -30t-43.5 -28.5t-53.5 -11.5q-29 1 -111 31t-146 43q-19 4 -51 9.5 t-50 9t-39.5 9.5t-33.5 14.5t-17 19.5q-10 23 7 66.5t18 54.5q1 16 -4 40t-10 42.5t-4.5 36.5t10.5 27q14 12 57 14t60 12q30 18 42 35t12 51q21 -73 -32 -106q-32 -20 -83 -15q-34 3 -43 -10q-13 -15 5 -57q2 -6 8 -18t8.5 -18t4.5 -17t1 -22q0 -15 -17 -49t-14 -48 q3 -17 37 -26q20 -6 84.5 -18.5t99.5 -20.5q24 -6 74 -22t82.5 -23t55.5 -4q43 6 64.5 28t23 48t-7.5 58.5t-19 52t-20 36.5q-121 190 -169 242q-68 74 -113 40q-11 -9 -15 15q-3 16 -2 38q1 29 10 52t24 47t22 42q8 21 26.5 72t29.5 78t30 61t39 54q110 143 124 195 q-12 112 -16 310q-2 90 24 151.5t106 104.5q39 21 104 21q53 1 106 -13.5t89 -41.5q57 -42 91.5 -121.5t29.5 -147.5q-5 -95 30 -214q34 -113 133 -218q55 -59 99.5 -163t59.5 -191q8 -49 5 -84.5t-12 -55.5t-20 -22q-10 -2 -23.5 -19t-27 -35.5t-40.5 -33.5t-61 -14 q-18 1 -31.5 5t-22.5 13.5t-13.5 15.5t-11.5 20.5t-9 19.5q-22 37 -41 30t-28 -49t7 -97q20 -70 1 -195q-10 -65 18 -100.5t73 -33t85 35.5q59 49 89.5 66.5t103.5 42.5q53 18 77 36.5t18.5 34.5t-25 28.5t-51.5 23.5q-33 11 -49.5 48t-15 72.5t15.5 47.5q1 -31 8 -56.5 t14.5 -40.5t20.5 -28.5t21 -19t21.5 -13t16.5 -9.5z" />
<glyph unicode="&#xf17d;" d="M1024 36q-42 241 -140 498h-2l-2 -1q-16 -6 -43 -16.5t-101 -49t-137 -82t-131 -114.5t-103 -148l-15 11q184 -150 418 -150q132 0 256 52zM839 643q-21 49 -53 111q-311 -93 -673 -93q-1 -7 -1 -21q0 -124 44 -236.5t124 -201.5q50 89 123.5 166.5t142.5 124.5t130.5 81 t99.5 48l37 13q4 1 13 3.5t13 4.5zM732 855q-120 213 -244 378q-138 -65 -234 -186t-128 -272q302 0 606 80zM1416 536q-210 60 -409 29q87 -239 128 -469q111 75 185 189.5t96 250.5zM611 1277q-1 0 -2 -1q1 1 2 1zM1201 1132q-185 164 -433 164q-76 0 -155 -19 q131 -170 246 -382q69 26 130 60.5t96.5 61.5t65.5 57t37.5 40.5zM1424 647q-3 232 -149 410l-1 -1q-9 -12 -19 -24.5t-43.5 -44.5t-71 -60.5t-100 -65t-131.5 -64.5q25 -53 44 -95q2 -6 6.5 -17.5t7.5 -16.5q36 5 74.5 7t73.5 2t69 -1.5t64 -4t56.5 -5.5t48 -6.5t36.5 -6 t25 -4.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
<glyph unicode="&#xf17e;" d="M1173 473q0 50 -19.5 91.5t-48.5 68.5t-73 49t-82.5 34t-87.5 23l-104 24q-30 7 -44 10.5t-35 11.5t-30 16t-16.5 21t-7.5 30q0 77 144 77q43 0 77 -12t54 -28.5t38 -33.5t40 -29t48 -12q47 0 75.5 32t28.5 77q0 55 -56 99.5t-142 67.5t-182 23q-68 0 -132 -15.5 t-119.5 -47t-89 -87t-33.5 -128.5q0 -61 19 -106.5t56 -75.5t80 -48.5t103 -32.5l146 -36q90 -22 112 -36q32 -20 32 -60q0 -39 -40 -64.5t-105 -25.5q-51 0 -91.5 16t-65 38.5t-45.5 45t-46 38.5t-54 16q-50 0 -75.5 -30t-25.5 -75q0 -92 122 -157.5t291 -65.5 q73 0 140 18.5t122.5 53.5t88.5 93.5t33 131.5zM1536 256q0 -159 -112.5 -271.5t-271.5 -112.5q-130 0 -234 80q-77 -16 -150 -16q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5q0 73 16 150q-80 104 -80 234q0 159 112.5 271.5t271.5 112.5q130 0 234 -80 q77 16 150 16q143 0 273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -73 -16 -150q80 -104 80 -234z" />
<glyph unicode="&#xf180;" horiz-adv-x="1664" d="M1483 512l-587 -587q-52 -53 -127.5 -53t-128.5 53l-587 587q-53 53 -53 128t53 128l587 587q53 53 128 53t128 -53l265 -265l-398 -399l-188 188q-42 42 -99 42q-59 0 -100 -41l-120 -121q-42 -40 -42 -99q0 -58 42 -100l406 -408q30 -28 67 -37l6 -4h28q60 0 99 41 l619 619l2 -3q53 -53 53 -128t-53 -128zM1406 1138l120 -120q14 -15 14 -36t-14 -36l-730 -730q-17 -15 -37 -15v0q-4 0 -6 1q-18 2 -30 14l-407 408q-14 15 -14 36t14 35l121 120q13 15 35 15t36 -15l252 -252l574 575q15 15 36 15t36 -15z" />
<glyph unicode="&#xf181;" d="M704 192v1024q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-1024q0 -14 9 -23t23 -9h480q14 0 23 9t9 23zM1376 576v640q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-640q0 -14 9 -23t23 -9h480q14 0 23 9t9 23zM1536 1344v-1408q0 -26 -19 -45t-45 -19h-1408 q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" />
<glyph unicode="&#xf182;" horiz-adv-x="1280" d="M1280 480q0 -40 -28 -68t-68 -28q-51 0 -80 43l-227 341h-45v-132l247 -411q9 -15 9 -33q0 -26 -19 -45t-45 -19h-192v-272q0 -46 -33 -79t-79 -33h-160q-46 0 -79 33t-33 79v272h-192q-26 0 -45 19t-19 45q0 18 9 33l247 411v132h-45l-227 -341q-29 -43 -80 -43 q-40 0 -68 28t-28 68q0 29 16 53l256 384q73 107 176 107h384q103 0 176 -107l256 -384q16 -24 16 -53zM864 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" />
<glyph unicode="&#xf183;" horiz-adv-x="1024" d="M1024 832v-416q0 -40 -28 -68t-68 -28t-68 28t-28 68v352h-64v-912q0 -46 -33 -79t-79 -33t-79 33t-33 79v464h-64v-464q0 -46 -33 -79t-79 -33t-79 33t-33 79v912h-64v-352q0 -40 -28 -68t-68 -28t-68 28t-28 68v416q0 80 56 136t136 56h640q80 0 136 -56t56 -136z M736 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" />
<glyph unicode="&#xf184;" d="M773 234l350 473q16 22 24.5 59t-6 85t-61.5 79q-40 26 -83 25.5t-73.5 -17.5t-54.5 -45q-36 -40 -96 -40q-59 0 -95 40q-24 28 -54.5 45t-73.5 17.5t-84 -25.5q-46 -31 -60.5 -79t-6 -85t24.5 -59zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
<glyph unicode="&#xf185;" horiz-adv-x="1792" d="M1472 640q0 117 -45.5 223.5t-123 184t-184 123t-223.5 45.5t-223.5 -45.5t-184 -123t-123 -184t-45.5 -223.5t45.5 -223.5t123 -184t184 -123t223.5 -45.5t223.5 45.5t184 123t123 184t45.5 223.5zM1748 363q-4 -15 -20 -20l-292 -96v-306q0 -16 -13 -26q-15 -10 -29 -4 l-292 94l-180 -248q-10 -13 -26 -13t-26 13l-180 248l-292 -94q-14 -6 -29 4q-13 10 -13 26v306l-292 96q-16 5 -20 20q-5 17 4 29l180 248l-180 248q-9 13 -4 29q4 15 20 20l292 96v306q0 16 13 26q15 10 29 4l292 -94l180 248q9 12 26 12t26 -12l180 -248l292 94 q14 6 29 -4q13 -10 13 -26v-306l292 -96q16 -5 20 -20q5 -16 -4 -29l-180 -248l180 -248q9 -12 4 -29z" />
<glyph unicode="&#xf186;" d="M1262 233q-54 -9 -110 -9q-182 0 -337 90t-245 245t-90 337q0 192 104 357q-201 -60 -328.5 -229t-127.5 -384q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51q144 0 273.5 61.5t220.5 171.5zM1465 318q-94 -203 -283.5 -324.5t-413.5 -121.5q-156 0 -298 61 t-245 164t-164 245t-61 298q0 153 57.5 292.5t156 241.5t235.5 164.5t290 68.5q44 2 61 -39q18 -41 -15 -72q-86 -78 -131.5 -181.5t-45.5 -218.5q0 -148 73 -273t198 -198t273 -73q118 0 228 51q41 18 72 -13q14 -14 17.5 -34t-4.5 -38z" />
<glyph unicode="&#xf187;" horiz-adv-x="1792" d="M1088 704q0 26 -19 45t-45 19h-256q-26 0 -45 -19t-19 -45t19 -45t45 -19h256q26 0 45 19t19 45zM1664 896v-960q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v960q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1728 1344v-256q0 -26 -19 -45t-45 -19h-1536 q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1536q26 0 45 -19t19 -45z" />
<glyph unicode="&#xf188;" horiz-adv-x="1664" d="M1632 576q0 -26 -19 -45t-45 -19h-224q0 -171 -67 -290l208 -209q19 -19 19 -45t-19 -45q-18 -19 -45 -19t-45 19l-198 197q-5 -5 -15 -13t-42 -28.5t-65 -36.5t-82 -29t-97 -13v896h-128v-896q-51 0 -101.5 13.5t-87 33t-66 39t-43.5 32.5l-15 14l-183 -207 q-20 -21 -48 -21q-24 0 -43 16q-19 18 -20.5 44.5t15.5 46.5l202 227q-58 114 -58 274h-224q-26 0 -45 19t-19 45t19 45t45 19h224v294l-173 173q-19 19 -19 45t19 45t45 19t45 -19l173 -173h844l173 173q19 19 45 19t45 -19t19 -45t-19 -45l-173 -173v-294h224q26 0 45 -19 t19 -45zM1152 1152h-640q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5z" />
<glyph unicode="&#xf189;" horiz-adv-x="1920" d="M1917 1016q23 -64 -150 -294q-24 -32 -65 -85q-78 -100 -90 -131q-17 -41 14 -81q17 -21 81 -82h1l1 -1l1 -1l2 -2q141 -131 191 -221q3 -5 6.5 -12.5t7 -26.5t-0.5 -34t-25 -27.5t-59 -12.5l-256 -4q-24 -5 -56 5t-52 22l-20 12q-30 21 -70 64t-68.5 77.5t-61 58 t-56.5 15.5q-3 -1 -8 -3.5t-17 -14.5t-21.5 -29.5t-17 -52t-6.5 -77.5q0 -15 -3.5 -27.5t-7.5 -18.5l-4 -5q-18 -19 -53 -22h-115q-71 -4 -146 16.5t-131.5 53t-103 66t-70.5 57.5l-25 24q-10 10 -27.5 30t-71.5 91t-106 151t-122.5 211t-130.5 272q-6 16 -6 27t3 16l4 6 q15 19 57 19l274 2q12 -2 23 -6.5t16 -8.5l5 -3q16 -11 24 -32q20 -50 46 -103.5t41 -81.5l16 -29q29 -60 56 -104t48.5 -68.5t41.5 -38.5t34 -14t27 5q2 1 5 5t12 22t13.5 47t9.5 81t0 125q-2 40 -9 73t-14 46l-6 12q-25 34 -85 43q-13 2 5 24q17 19 38 30q53 26 239 24 q82 -1 135 -13q20 -5 33.5 -13.5t20.5 -24t10.5 -32t3.5 -45.5t-1 -55t-2.5 -70.5t-1.5 -82.5q0 -11 -1 -42t-0.5 -48t3.5 -40.5t11.5 -39t22.5 -24.5q8 -2 17 -4t26 11t38 34.5t52 67t68 107.5q60 104 107 225q4 10 10 17.5t11 10.5l4 3l5 2.5t13 3t20 0.5l288 2 q39 5 64 -2.5t31 -16.5z" />
<glyph unicode="&#xf18a;" horiz-adv-x="1792" d="M675 252q21 34 11 69t-45 50q-34 14 -73 1t-60 -46q-22 -34 -13 -68.5t43 -50.5t74.5 -2.5t62.5 47.5zM769 373q8 13 3.5 26.5t-17.5 18.5q-14 5 -28.5 -0.5t-21.5 -18.5q-17 -31 13 -45q14 -5 29 0.5t22 18.5zM943 266q-45 -102 -158 -150t-224 -12 q-107 34 -147.5 126.5t6.5 187.5q47 93 151.5 139t210.5 19q111 -29 158.5 -119.5t2.5 -190.5zM1255 426q-9 96 -89 170t-208.5 109t-274.5 21q-223 -23 -369.5 -141.5t-132.5 -264.5q9 -96 89 -170t208.5 -109t274.5 -21q223 23 369.5 141.5t132.5 264.5zM1563 422 q0 -68 -37 -139.5t-109 -137t-168.5 -117.5t-226 -83t-270.5 -31t-275 33.5t-240.5 93t-171.5 151t-65 199.5q0 115 69.5 245t197.5 258q169 169 341.5 236t246.5 -7q65 -64 20 -209q-4 -14 -1 -20t10 -7t14.5 0.5t13.5 3.5l6 2q139 59 246 59t153 -61q45 -63 0 -178 q-2 -13 -4.5 -20t4.5 -12.5t12 -7.5t17 -6q57 -18 103 -47t80 -81.5t34 -116.5zM1489 1046q42 -47 54.5 -108.5t-6.5 -117.5q-8 -23 -29.5 -34t-44.5 -4q-23 8 -34 29.5t-4 44.5q20 63 -24 111t-107 35q-24 -5 -45 8t-25 37q-5 24 8 44.5t37 25.5q60 13 119 -5.5t101 -65.5z M1670 1209q87 -96 112.5 -222.5t-13.5 -241.5q-9 -27 -34 -40t-52 -4t-40 34t-5 52q28 82 10 172t-80 158q-62 69 -148 95.5t-173 8.5q-28 -6 -52 9.5t-30 43.5t9.5 51.5t43.5 29.5q123 26 244 -11.5t208 -134.5z" />
<glyph unicode="&#xf18b;" horiz-adv-x="1920" d="M805 163q-122 -67 -261 -67q-141 0 -261 67q98 61 167 149t94 191q25 -103 94 -191t167 -149zM453 1176v-344q0 -179 -89.5 -326t-234.5 -217q-129 152 -129 351q0 200 129.5 352t323.5 184zM958 991q-128 -152 -128 -351q0 -201 128 -351q-145 70 -234.5 218t-89.5 328 v341q196 -33 324 -185zM1638 163q-122 -67 -261 -67q-141 0 -261 67q98 61 167 149t94 191q25 -103 94 -191t167 -149zM1286 1176v-344q0 -179 -91 -326t-237 -217v0q133 154 133 351q0 195 -133 351q129 151 328 185zM1920 640q0 -201 -129 -351q-145 70 -234.5 218 t-89.5 328v341q194 -32 323.5 -184t129.5 -352z" />
<glyph unicode="&#xf18c;" horiz-adv-x="1792" />
<glyph unicode="&#xf18d;" horiz-adv-x="1792" />
<glyph unicode="&#xf18e;" horiz-adv-x="1792" />
<glyph unicode="&#xf500;" horiz-adv-x="1792" />
</font>
</defs></svg>

After

Width:  |  Height:  |  Size: 193 KiB

BIN
iguana/docs/supernet/site/fonts/fontawesome-webfont.ttf

Binary file not shown.

BIN
iguana/docs/supernet/site/fonts/fontawesome-webfont.woff

Binary file not shown.

BIN
iguana/docs/supernet/site/img/favicon.ico

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

183
iguana/docs/supernet/site/index.html

@ -0,0 +1,183 @@
<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SuperNET Documentation</title>
<link rel="shortcut icon" href="./img/favicon.ico">
<link href='https://fonts.googleapis.com/css?family=Lato:400,700|Roboto+Slab:400,700|Inconsolata:400,700' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="./css/theme.css" type="text/css" />
<link rel="stylesheet" href="./css/theme_extra.css" type="text/css" />
<link rel="stylesheet" href="./css/highlight.css">
<script>
// Current page data
var mkdocs_page_name = "None";
</script>
<script src="./js/jquery-2.1.1.min.js"></script>
<script src="./js/modernizr-2.8.3.min.js"></script>
<script type="text/javascript" src="./js/highlight.pack.js"></script>
<script src="./js/theme.js"></script>
</head>
<body class="wy-body-for-nav" role="document">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side stickynav">
<div class="wy-side-nav-search">
<a href="." class="icon icon-home"> SuperNET Documentation</a>
<div role="search">
<form id ="rtd-search-form" class="wy-form" action="./search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
</form>
</div>
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
<ul class="current">
<li>
<li class="toctree-l1 current">
<a class="current" href=".">Home</a>
<ul>
<li class="toctree-l3"><a href="#developers">Developers</a></li>
<li class="toctree-l3"><a href="#for-users">For Users</a></li>
</ul>
</li>
<li>
<li>
<li class="toctree-l1 ">
<a class="" href="about/">About</a>
</li>
<li>
</ul>
</div>
&nbsp;
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" role="navigation" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href=".">SuperNET Documentation</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href=".">Docs</a> &raquo;</li>
<li>Home</li>
<li class="wy-breadcrumbs-aside">
</li>
</ul>
<hr/>
</div>
<div role="main">
<div class="section">
<h1 id="developers">Developers</h1>
<ul>
<li>Getting Started</li>
<li>Desktop App SDK</li>
<li>Mobile App SDK
<strong> Android
</strong> iOS
** Windows</li>
<li>Iguana/SuperNET API Reference: Any General SuperNET specific API reference
<strong> Coins ( ablaze )
</strong> Peers ( eyedea )</li>
<li>SuperNET Apps specific API Reference: Organising Applications specific API reference and interlinking between other pages to refer if the same API is used in between these applications.
<strong> InstantDEX API
</strong> Pegged Asset Exchange (PAX) API
** Jumblr API</li>
<li>Iguana/SuperNET Core Coin API Reference: Referecing to SuperNET's core coin's API reference which might be nessary to function or build Iguana/SuperNET Application, and where it's using some different API calls than official APIs
<strong> BitcoinDark API
</strong> Bitcoin API</li>
</ul>
<h1 id="for-users">For Users</h1>
<ul>
<li>Iguana Chrome App User Manual</li>
<li>Iguana Mobile App
<strong> Android
</strong> iOS</li>
<li>InstantDEX User Manual</li>
<li>Pegged Asset Exchange (PAX) User Manual</li>
<li>Jumblr User Manual</li>
</ul>
</div>
</div>
<footer>
<div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
<a href="about/" class="btn btn-neutral float-right" title="About"/>Next <span class="icon icon-circle-arrow-right"></span></a>
</div>
<hr/>
<div role="contentinfo">
<!-- Copyright etc -->
</div>
Built with <a href="http://www.mkdocs.org">MkDocs</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<div class="rst-versions" role="note" style="cursor: pointer">
<span class="rst-current-version" data-toggle="rst-current-version">
<span style="margin-left: 15px"><a href="about/" style="color: #fcfcfc">Next &raquo;</a></span>
</span>
</div>
</body>
</html>
<!--
MkDocs version : 0.14.0
Build Date UTC : 2015-12-22 23:20:03.993414
-->

2
iguana/docs/supernet/site/js/highlight.pack.js

File diff suppressed because one or more lines are too long

4
iguana/docs/supernet/site/js/jquery-2.1.1.min.js

File diff suppressed because one or more lines are too long

1
iguana/docs/supernet/site/js/modernizr-2.8.3.min.js

File diff suppressed because one or more lines are too long

55
iguana/docs/supernet/site/js/theme.js

@ -0,0 +1,55 @@
$( document ).ready(function() {
// Shift nav in mobile when clicking the menu.
$(document).on('click', "[data-toggle='wy-nav-top']", function() {
$("[data-toggle='wy-nav-shift']").toggleClass("shift");
$("[data-toggle='rst-versions']").toggleClass("shift");
});
// Close menu when you click a link.
$(document).on('click', ".wy-menu-vertical .current ul li a", function() {
$("[data-toggle='wy-nav-shift']").removeClass("shift");
$("[data-toggle='rst-versions']").toggleClass("shift");
});
$(document).on('click', "[data-toggle='rst-current-version']", function() {
$("[data-toggle='rst-versions']").toggleClass("shift-up");
});
// Make tables responsive
$("table.docutils:not(.field-list)").wrap("<div class='wy-table-responsive'></div>");
hljs.initHighlightingOnLoad();
$('table').addClass('docutils');
});
window.SphinxRtdTheme = (function (jquery) {
var stickyNav = (function () {
var navBar,
win,
stickyNavCssClass = 'stickynav',
applyStickNav = function () {
if (navBar.height() <= win.height()) {
navBar.addClass(stickyNavCssClass);
} else {
navBar.removeClass(stickyNavCssClass);
}
},
enable = function () {
applyStickNav();
win.on('resize', applyStickNav);
},
init = function () {
navBar = jquery('nav.wy-nav-side:first');
win = jquery(window);
};
jquery(init);
return {
enable : enable
};
}());
return {
StickyNav : stickyNav
};
}($));

24
iguana/docs/supernet/site/license/highlight.js/LICENSE

@ -0,0 +1,24 @@
Copyright (c) 2006, Ivan Sagalaev
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of highlight.js nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

7
iguana/docs/supernet/site/mkdocs/js/lunr-0.5.7.min.js

File diff suppressed because one or more lines are too long

1
iguana/docs/supernet/site/mkdocs/js/mustache.min.js

File diff suppressed because one or more lines are too long

36
iguana/docs/supernet/site/mkdocs/js/require.js

@ -0,0 +1,36 @@
/*
RequireJS 2.1.16 Copyright (c) 2010-2015, The Dojo Foundation All Rights Reserved.
Available via the MIT or new BSD license.
see: http://github.com/jrburke/requirejs for details
*/
var requirejs,require,define;
(function(ba){function G(b){return"[object Function]"===K.call(b)}function H(b){return"[object Array]"===K.call(b)}function v(b,c){if(b){var d;for(d=0;d<b.length&&(!b[d]||!c(b[d],d,b));d+=1);}}function T(b,c){if(b){var d;for(d=b.length-1;-1<d&&(!b[d]||!c(b[d],d,b));d-=1);}}function t(b,c){return fa.call(b,c)}function m(b,c){return t(b,c)&&b[c]}function B(b,c){for(var d in b)if(t(b,d)&&c(b[d],d))break}function U(b,c,d,e){c&&B(c,function(c,g){if(d||!t(b,g))e&&"object"===typeof c&&c&&!H(c)&&!G(c)&&!(c instanceof
RegExp)?(b[g]||(b[g]={}),U(b[g],c,d,e)):b[g]=c});return b}function u(b,c){return function(){return c.apply(b,arguments)}}function ca(b){throw b;}function da(b){if(!b)return b;var c=ba;v(b.split("."),function(b){c=c[b]});return c}function C(b,c,d,e){c=Error(c+"\nhttp://requirejs.org/docs/errors.html#"+b);c.requireType=b;c.requireModules=e;d&&(c.originalError=d);return c}function ga(b){function c(a,k,b){var f,l,c,d,e,g,i,p,k=k&&k.split("/"),h=j.map,n=h&&h["*"];if(a){a=a.split("/");l=a.length-1;j.nodeIdCompat&&
Q.test(a[l])&&(a[l]=a[l].replace(Q,""));"."===a[0].charAt(0)&&k&&(l=k.slice(0,k.length-1),a=l.concat(a));l=a;for(c=0;c<l.length;c++)if(d=l[c],"."===d)l.splice(c,1),c-=1;else if(".."===d&&!(0===c||1==c&&".."===l[2]||".."===l[c-1])&&0<c)l.splice(c-1,2),c-=2;a=a.join("/")}if(b&&h&&(k||n)){l=a.split("/");c=l.length;a:for(;0<c;c-=1){e=l.slice(0,c).join("/");if(k)for(d=k.length;0<d;d-=1)if(b=m(h,k.slice(0,d).join("/")))if(b=m(b,e)){f=b;g=c;break a}!i&&(n&&m(n,e))&&(i=m(n,e),p=c)}!f&&i&&(f=i,g=p);f&&(l.splice(0,
g,f),a=l.join("/"))}return(f=m(j.pkgs,a))?f:a}function d(a){z&&v(document.getElementsByTagName("script"),function(k){if(k.getAttribute("data-requiremodule")===a&&k.getAttribute("data-requirecontext")===i.contextName)return k.parentNode.removeChild(k),!0})}function e(a){var k=m(j.paths,a);if(k&&H(k)&&1<k.length)return k.shift(),i.require.undef(a),i.makeRequire(null,{skipMap:!0})([a]),!0}function n(a){var k,c=a?a.indexOf("!"):-1;-1<c&&(k=a.substring(0,c),a=a.substring(c+1,a.length));return[k,a]}function p(a,
k,b,f){var l,d,e=null,g=k?k.name:null,j=a,p=!0,h="";a||(p=!1,a="_@r"+(K+=1));a=n(a);e=a[0];a=a[1];e&&(e=c(e,g,f),d=m(r,e));a&&(e?h=d&&d.normalize?d.normalize(a,function(a){return c(a,g,f)}):-1===a.indexOf("!")?c(a,g,f):a:(h=c(a,g,f),a=n(h),e=a[0],h=a[1],b=!0,l=i.nameToUrl(h)));b=e&&!d&&!b?"_unnormalized"+(O+=1):"";return{prefix:e,name:h,parentMap:k,unnormalized:!!b,url:l,originalName:j,isDefine:p,id:(e?e+"!"+h:h)+b}}function s(a){var k=a.id,b=m(h,k);b||(b=h[k]=new i.Module(a));return b}function q(a,
k,b){var f=a.id,c=m(h,f);if(t(r,f)&&(!c||c.defineEmitComplete))"defined"===k&&b(r[f]);else if(c=s(a),c.error&&"error"===k)b(c.error);else c.on(k,b)}function w(a,b){var c=a.requireModules,f=!1;if(b)b(a);else if(v(c,function(b){if(b=m(h,b))b.error=a,b.events.error&&(f=!0,b.emit("error",a))}),!f)g.onError(a)}function x(){R.length&&(ha.apply(A,[A.length,0].concat(R)),R=[])}function y(a){delete h[a];delete V[a]}function F(a,b,c){var f=a.map.id;a.error?a.emit("error",a.error):(b[f]=!0,v(a.depMaps,function(f,
d){var e=f.id,g=m(h,e);g&&(!a.depMatched[d]&&!c[e])&&(m(b,e)?(a.defineDep(d,r[e]),a.check()):F(g,b,c))}),c[f]=!0)}function D(){var a,b,c=(a=1E3*j.waitSeconds)&&i.startTime+a<(new Date).getTime(),f=[],l=[],g=!1,h=!0;if(!W){W=!0;B(V,function(a){var i=a.map,j=i.id;if(a.enabled&&(i.isDefine||l.push(a),!a.error))if(!a.inited&&c)e(j)?g=b=!0:(f.push(j),d(j));else if(!a.inited&&(a.fetched&&i.isDefine)&&(g=!0,!i.prefix))return h=!1});if(c&&f.length)return a=C("timeout","Load timeout for modules: "+f,null,
f),a.contextName=i.contextName,w(a);h&&v(l,function(a){F(a,{},{})});if((!c||b)&&g)if((z||ea)&&!X)X=setTimeout(function(){X=0;D()},50);W=!1}}function E(a){t(r,a[0])||s(p(a[0],null,!0)).init(a[1],a[2])}function I(a){var a=a.currentTarget||a.srcElement,b=i.onScriptLoad;a.detachEvent&&!Y?a.detachEvent("onreadystatechange",b):a.removeEventListener("load",b,!1);b=i.onScriptError;(!a.detachEvent||Y)&&a.removeEventListener("error",b,!1);return{node:a,id:a&&a.getAttribute("data-requiremodule")}}function J(){var a;
for(x();A.length;){a=A.shift();if(null===a[0])return w(C("mismatch","Mismatched anonymous define() module: "+a[a.length-1]));E(a)}}var W,Z,i,L,X,j={waitSeconds:7,baseUrl:"./",paths:{},bundles:{},pkgs:{},shim:{},config:{}},h={},V={},$={},A=[],r={},S={},aa={},K=1,O=1;L={require:function(a){return a.require?a.require:a.require=i.makeRequire(a.map)},exports:function(a){a.usingExports=!0;if(a.map.isDefine)return a.exports?r[a.map.id]=a.exports:a.exports=r[a.map.id]={}},module:function(a){return a.module?
a.module:a.module={id:a.map.id,uri:a.map.url,config:function(){return m(j.config,a.map.id)||{}},exports:a.exports||(a.exports={})}}};Z=function(a){this.events=m($,a.id)||{};this.map=a;this.shim=m(j.shim,a.id);this.depExports=[];this.depMaps=[];this.depMatched=[];this.pluginMaps={};this.depCount=0};Z.prototype={init:function(a,b,c,f){f=f||{};if(!this.inited){this.factory=b;if(c)this.on("error",c);else this.events.error&&(c=u(this,function(a){this.emit("error",a)}));this.depMaps=a&&a.slice(0);this.errback=
c;this.inited=!0;this.ignore=f.ignore;f.enabled||this.enabled?this.enable():this.check()}},defineDep:function(a,b){this.depMatched[a]||(this.depMatched[a]=!0,this.depCount-=1,this.depExports[a]=b)},fetch:function(){if(!this.fetched){this.fetched=!0;i.startTime=(new Date).getTime();var a=this.map;if(this.shim)i.makeRequire(this.map,{enableBuildCallback:!0})(this.shim.deps||[],u(this,function(){return a.prefix?this.callPlugin():this.load()}));else return a.prefix?this.callPlugin():this.load()}},load:function(){var a=
this.map.url;S[a]||(S[a]=!0,i.load(this.map.id,a))},check:function(){if(this.enabled&&!this.enabling){var a,b,c=this.map.id;b=this.depExports;var f=this.exports,l=this.factory;if(this.inited)if(this.error)this.emit("error",this.error);else{if(!this.defining){this.defining=!0;if(1>this.depCount&&!this.defined){if(G(l)){if(this.events.error&&this.map.isDefine||g.onError!==ca)try{f=i.execCb(c,l,b,f)}catch(d){a=d}else f=i.execCb(c,l,b,f);this.map.isDefine&&void 0===f&&((b=this.module)?f=b.exports:this.usingExports&&
(f=this.exports));if(a)return a.requireMap=this.map,a.requireModules=this.map.isDefine?[this.map.id]:null,a.requireType=this.map.isDefine?"define":"require",w(this.error=a)}else f=l;this.exports=f;if(this.map.isDefine&&!this.ignore&&(r[c]=f,g.onResourceLoad))g.onResourceLoad(i,this.map,this.depMaps);y(c);this.defined=!0}this.defining=!1;this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=!0)}}else this.fetch()}},callPlugin:function(){var a=
this.map,b=a.id,d=p(a.prefix);this.depMaps.push(d);q(d,"defined",u(this,function(f){var l,d;d=m(aa,this.map.id);var e=this.map.name,P=this.map.parentMap?this.map.parentMap.name:null,n=i.makeRequire(a.parentMap,{enableBuildCallback:!0});if(this.map.unnormalized){if(f.normalize&&(e=f.normalize(e,function(a){return c(a,P,!0)})||""),f=p(a.prefix+"!"+e,this.map.parentMap),q(f,"defined",u(this,function(a){this.init([],function(){return a},null,{enabled:!0,ignore:!0})})),d=m(h,f.id)){this.depMaps.push(f);
if(this.events.error)d.on("error",u(this,function(a){this.emit("error",a)}));d.enable()}}else d?(this.map.url=i.nameToUrl(d),this.load()):(l=u(this,function(a){this.init([],function(){return a},null,{enabled:!0})}),l.error=u(this,function(a){this.inited=!0;this.error=a;a.requireModules=[b];B(h,function(a){0===a.map.id.indexOf(b+"_unnormalized")&&y(a.map.id)});w(a)}),l.fromText=u(this,function(f,c){var d=a.name,e=p(d),P=M;c&&(f=c);P&&(M=!1);s(e);t(j.config,b)&&(j.config[d]=j.config[b]);try{g.exec(f)}catch(h){return w(C("fromtexteval",
"fromText eval for "+b+" failed: "+h,h,[b]))}P&&(M=!0);this.depMaps.push(e);i.completeLoad(d);n([d],l)}),f.load(a.name,n,l,j))}));i.enable(d,this);this.pluginMaps[d.id]=d},enable:function(){V[this.map.id]=this;this.enabling=this.enabled=!0;v(this.depMaps,u(this,function(a,b){var c,f;if("string"===typeof a){a=p(a,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap);this.depMaps[b]=a;if(c=m(L,a.id)){this.depExports[b]=c(this);return}this.depCount+=1;q(a,"defined",u(this,function(a){this.defineDep(b,
a);this.check()}));this.errback?q(a,"error",u(this,this.errback)):this.events.error&&q(a,"error",u(this,function(a){this.emit("error",a)}))}c=a.id;f=h[c];!t(L,c)&&(f&&!f.enabled)&&i.enable(a,this)}));B(this.pluginMaps,u(this,function(a){var b=m(h,a.id);b&&!b.enabled&&i.enable(a,this)}));this.enabling=!1;this.check()},on:function(a,b){var c=this.events[a];c||(c=this.events[a]=[]);c.push(b)},emit:function(a,b){v(this.events[a],function(a){a(b)});"error"===a&&delete this.events[a]}};i={config:j,contextName:b,
registry:h,defined:r,urlFetched:S,defQueue:A,Module:Z,makeModuleMap:p,nextTick:g.nextTick,onError:w,configure:function(a){a.baseUrl&&"/"!==a.baseUrl.charAt(a.baseUrl.length-1)&&(a.baseUrl+="/");var b=j.shim,c={paths:!0,bundles:!0,config:!0,map:!0};B(a,function(a,b){c[b]?(j[b]||(j[b]={}),U(j[b],a,!0,!0)):j[b]=a});a.bundles&&B(a.bundles,function(a,b){v(a,function(a){a!==b&&(aa[a]=b)})});a.shim&&(B(a.shim,function(a,c){H(a)&&(a={deps:a});if((a.exports||a.init)&&!a.exportsFn)a.exportsFn=i.makeShimExports(a);
b[c]=a}),j.shim=b);a.packages&&v(a.packages,function(a){var b,a="string"===typeof a?{name:a}:a;b=a.name;a.location&&(j.paths[b]=a.location);j.pkgs[b]=a.name+"/"+(a.main||"main").replace(ia,"").replace(Q,"")});B(h,function(a,b){!a.inited&&!a.map.unnormalized&&(a.map=p(b))});if(a.deps||a.callback)i.require(a.deps||[],a.callback)},makeShimExports:function(a){return function(){var b;a.init&&(b=a.init.apply(ba,arguments));return b||a.exports&&da(a.exports)}},makeRequire:function(a,e){function j(c,d,m){var n,
q;e.enableBuildCallback&&(d&&G(d))&&(d.__requireJsBuild=!0);if("string"===typeof c){if(G(d))return w(C("requireargs","Invalid require call"),m);if(a&&t(L,c))return L[c](h[a.id]);if(g.get)return g.get(i,c,a,j);n=p(c,a,!1,!0);n=n.id;return!t(r,n)?w(C("notloaded",'Module name "'+n+'" has not been loaded yet for context: '+b+(a?"":". Use require([])"))):r[n]}J();i.nextTick(function(){J();q=s(p(null,a));q.skipMap=e.skipMap;q.init(c,d,m,{enabled:!0});D()});return j}e=e||{};U(j,{isBrowser:z,toUrl:function(b){var d,
e=b.lastIndexOf("."),k=b.split("/")[0];if(-1!==e&&(!("."===k||".."===k)||1<e))d=b.substring(e,b.length),b=b.substring(0,e);return i.nameToUrl(c(b,a&&a.id,!0),d,!0)},defined:function(b){return t(r,p(b,a,!1,!0).id)},specified:function(b){b=p(b,a,!1,!0).id;return t(r,b)||t(h,b)}});a||(j.undef=function(b){x();var c=p(b,a,!0),e=m(h,b);d(b);delete r[b];delete S[c.url];delete $[b];T(A,function(a,c){a[0]===b&&A.splice(c,1)});e&&(e.events.defined&&($[b]=e.events),y(b))});return j},enable:function(a){m(h,a.id)&&
s(a).enable()},completeLoad:function(a){var b,c,d=m(j.shim,a)||{},g=d.exports;for(x();A.length;){c=A.shift();if(null===c[0]){c[0]=a;if(b)break;b=!0}else c[0]===a&&(b=!0);E(c)}c=m(h,a);if(!b&&!t(r,a)&&c&&!c.inited){if(j.enforceDefine&&(!g||!da(g)))return e(a)?void 0:w(C("nodefine","No define call for "+a,null,[a]));E([a,d.deps||[],d.exportsFn])}D()},nameToUrl:function(a,b,c){var d,e,h;(d=m(j.pkgs,a))&&(a=d);if(d=m(aa,a))return i.nameToUrl(d,b,c);if(g.jsExtRegExp.test(a))d=a+(b||"");else{d=j.paths;
a=a.split("/");for(e=a.length;0<e;e-=1)if(h=a.slice(0,e).join("/"),h=m(d,h)){H(h)&&(h=h[0]);a.splice(0,e,h);break}d=a.join("/");d+=b||(/^data\:|\?/.test(d)||c?"":".js");d=("/"===d.charAt(0)||d.match(/^[\w\+\.\-]+:/)?"":j.baseUrl)+d}return j.urlArgs?d+((-1===d.indexOf("?")?"?":"&")+j.urlArgs):d},load:function(a,b){g.load(i,a,b)},execCb:function(a,b,c,d){return b.apply(d,c)},onScriptLoad:function(a){if("load"===a.type||ja.test((a.currentTarget||a.srcElement).readyState))N=null,a=I(a),i.completeLoad(a.id)},
onScriptError:function(a){var b=I(a);if(!e(b.id))return w(C("scripterror","Script error for: "+b.id,a,[b.id]))}};i.require=i.makeRequire();return i}var g,x,y,D,I,E,N,J,s,O,ka=/(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,la=/[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,Q=/\.js$/,ia=/^\.\//;x=Object.prototype;var K=x.toString,fa=x.hasOwnProperty,ha=Array.prototype.splice,z=!!("undefined"!==typeof window&&"undefined"!==typeof navigator&&window.document),ea=!z&&"undefined"!==typeof importScripts,ja=
z&&"PLAYSTATION 3"===navigator.platform?/^complete$/:/^(complete|loaded)$/,Y="undefined"!==typeof opera&&"[object Opera]"===opera.toString(),F={},q={},R=[],M=!1;if("undefined"===typeof define){if("undefined"!==typeof requirejs){if(G(requirejs))return;q=requirejs;requirejs=void 0}"undefined"!==typeof require&&!G(require)&&(q=require,require=void 0);g=requirejs=function(b,c,d,e){var n,p="_";!H(b)&&"string"!==typeof b&&(n=b,H(c)?(b=c,c=d,d=e):b=[]);n&&n.context&&(p=n.context);(e=m(F,p))||(e=F[p]=g.s.newContext(p));
n&&e.configure(n);return e.require(b,c,d)};g.config=function(b){return g(b)};g.nextTick="undefined"!==typeof setTimeout?function(b){setTimeout(b,4)}:function(b){b()};require||(require=g);g.version="2.1.16";g.jsExtRegExp=/^\/|:|\?|\.js$/;g.isBrowser=z;x=g.s={contexts:F,newContext:ga};g({});v(["toUrl","undef","defined","specified"],function(b){g[b]=function(){var c=F._;return c.require[b].apply(c,arguments)}});if(z&&(y=x.head=document.getElementsByTagName("head")[0],D=document.getElementsByTagName("base")[0]))y=
x.head=D.parentNode;g.onError=ca;g.createNode=function(b){var c=b.xhtml?document.createElementNS("http://www.w3.org/1999/xhtml","html:script"):document.createElement("script");c.type=b.scriptType||"text/javascript";c.charset="utf-8";c.async=!0;return c};g.load=function(b,c,d){var e=b&&b.config||{};if(z)return e=g.createNode(e,c,d),e.setAttribute("data-requirecontext",b.contextName),e.setAttribute("data-requiremodule",c),e.attachEvent&&!(e.attachEvent.toString&&0>e.attachEvent.toString().indexOf("[native code"))&&
!Y?(M=!0,e.attachEvent("onreadystatechange",b.onScriptLoad)):(e.addEventListener("load",b.onScriptLoad,!1),e.addEventListener("error",b.onScriptError,!1)),e.src=d,J=e,D?y.insertBefore(e,D):y.appendChild(e),J=null,e;if(ea)try{importScripts(d),b.completeLoad(c)}catch(m){b.onError(C("importscripts","importScripts failed for "+c+" at "+d,m,[c]))}};z&&!q.skipDataMain&&T(document.getElementsByTagName("script"),function(b){y||(y=b.parentNode);if(I=b.getAttribute("data-main"))return s=I,q.baseUrl||(E=s.split("/"),
s=E.pop(),O=E.length?E.join("/")+"/":"./",q.baseUrl=O),s=s.replace(Q,""),g.jsExtRegExp.test(s)&&(s=I),q.deps=q.deps?q.deps.concat(s):[s],!0});define=function(b,c,d){var e,g;"string"!==typeof b&&(d=c,c=b,b=null);H(c)||(d=c,c=null);!c&&G(d)&&(c=[],d.length&&(d.toString().replace(ka,"").replace(la,function(b,d){c.push(d)}),c=(1===d.length?["require"]:["require","exports","module"]).concat(c)));if(M){if(!(e=J))N&&"interactive"===N.readyState||T(document.getElementsByTagName("script"),function(b){if("interactive"===
b.readyState)return N=b}),e=N;e&&(b||(b=e.getAttribute("data-requiremodule")),g=F[e.getAttribute("data-requirecontext")])}(g?g.defQueue:R).push([b,c,d])};define.amd={jQuery:!0};g.exec=function(b){return eval(b)};g(q)}})(this);

4
iguana/docs/supernet/site/mkdocs/js/search-results-template.mustache

@ -0,0 +1,4 @@
<article>
<h3><a href="{{location}}">{{title}}</a></h3>
<p>{{summary}}</p>
</article>

88
iguana/docs/supernet/site/mkdocs/js/search.js

@ -0,0 +1,88 @@
require([
base_url + '/mkdocs/js/mustache.min.js',
base_url + '/mkdocs/js/lunr-0.5.7.min.js',
'text!search-results-template.mustache',
'text!../search_index.json',
], function (Mustache, lunr, results_template, data) {
"use strict";
function getSearchTerm()
{
var sPageURL = window.location.search.substring(1);
var sURLVariables = sPageURL.split('&');
for (var i = 0; i < sURLVariables.length; i++)
{
var sParameterName = sURLVariables[i].split('=');
if (sParameterName[0] == 'q')
{
return decodeURIComponent(sParameterName[1].replace(/\+/g, '%20'));
}
}
}
var index = lunr(function () {
this.field('title', {boost: 10});
this.field('text');
this.ref('location');
});
data = JSON.parse(data);
var documents = {};
for (var i=0; i < data.docs.length; i++){
var doc = data.docs[i];
doc.location = base_url + doc.location;
index.add(doc);
documents[doc.location] = doc;
}
var search = function(){
var query = document.getElementById('mkdocs-search-query').value;
var search_results = document.getElementById("mkdocs-search-results");
while (search_results.firstChild) {
search_results.removeChild(search_results.firstChild);
}
if(query === ''){
return;
}
var results = index.search(query);
if (results.length > 0){
for (var i=0; i < results.length; i++){
var result = results[i];
doc = documents[result.ref];
doc.base_url = base_url;
doc.summary = doc.text.substring(0, 200);
var html = Mustache.to_html(results_template, doc);
search_results.insertAdjacentHTML('beforeend', html);
}
} else {
search_results.insertAdjacentHTML('beforeend', "<p>No results found</p>");
}
if(jQuery){
/*
* We currently only automatically hide bootstrap models. This
* requires jQuery to work.
*/
jQuery('#mkdocs_search_modal a').click(function(){
jQuery('#mkdocs_search_modal').modal('hide');
})
}
};
var search_input = document.getElementById('mkdocs-search-query');
var term = getSearchTerm();
if (term){
search_input.value = term;
search();
}
search_input.addEventListener("keyup", search);
});

390
iguana/docs/supernet/site/mkdocs/js/text.js

@ -0,0 +1,390 @@
/**
* @license RequireJS text 2.0.12 Copyright (c) 2010-2014, The Dojo Foundation All Rights Reserved.
* Available via the MIT or new BSD license.
* see: http://github.com/requirejs/text for details
*/
/*jslint regexp: true */
/*global require, XMLHttpRequest, ActiveXObject,
define, window, process, Packages,
java, location, Components, FileUtils */
define(['module'], function (module) {
'use strict';
var text, fs, Cc, Ci, xpcIsWindows,
progIds = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'],
xmlRegExp = /^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im,
bodyRegExp = /<body[^>]*>\s*([\s\S]+)\s*<\/body>/im,
hasLocation = typeof location !== 'undefined' && location.href,
defaultProtocol = hasLocation && location.protocol && location.protocol.replace(/\:/, ''),
defaultHostName = hasLocation && location.hostname,
defaultPort = hasLocation && (location.port || undefined),
buildMap = {},
masterConfig = (module.config && module.config()) || {};
text = {
version: '2.0.12',
strip: function (content) {
//Strips <?xml ...?> declarations so that external SVG and XML
//documents can be added to a document without worry. Also, if the string
//is an HTML document, only the part inside the body tag is returned.
if (content) {
content = content.replace(xmlRegExp, "");
var matches = content.match(bodyRegExp);
if (matches) {
content = matches[1];
}
} else {
content = "";
}
return content;
},
jsEscape: function (content) {
return content.replace(/(['\\])/g, '\\$1')
.replace(/[\f]/g, "\\f")
.replace(/[\b]/g, "\\b")
.replace(/[\n]/g, "\\n")
.replace(/[\t]/g, "\\t")
.replace(/[\r]/g, "\\r")
.replace(/[\u2028]/g, "\\u2028")
.replace(/[\u2029]/g, "\\u2029");
},
createXhr: masterConfig.createXhr || function () {
//Would love to dump the ActiveX crap in here. Need IE 6 to die first.
var xhr, i, progId;
if (typeof XMLHttpRequest !== "undefined") {
return new XMLHttpRequest();
} else if (typeof ActiveXObject !== "undefined") {
for (i = 0; i < 3; i += 1) {
progId = progIds[i];
try {
xhr = new ActiveXObject(progId);
} catch (e) {}
if (xhr) {
progIds = [progId]; // so faster next time
break;
}
}
}
return xhr;
},
/**
* Parses a resource name into its component parts. Resource names
* look like: module/name.ext!strip, where the !strip part is
* optional.
* @param {String} name the resource name
* @returns {Object} with properties "moduleName", "ext" and "strip"
* where strip is a boolean.
*/
parseName: function (name) {
var modName, ext, temp,
strip = false,
index = name.indexOf("."),
isRelative = name.indexOf('./') === 0 ||
name.indexOf('../') === 0;
if (index !== -1 && (!isRelative || index > 1)) {
modName = name.substring(0, index);
ext = name.substring(index + 1, name.length);
} else {
modName = name;
}
temp = ext || modName;
index = temp.indexOf("!");
if (index !== -1) {
//Pull off the strip arg.
strip = temp.substring(index + 1) === "strip";
temp = temp.substring(0, index);
if (ext) {
ext = temp;
} else {
modName = temp;
}
}
return {
moduleName: modName,
ext: ext,
strip: strip
};
},
xdRegExp: /^((\w+)\:)?\/\/([^\/\\]+)/,
/**
* Is an URL on another domain. Only works for browser use, returns
* false in non-browser environments. Only used to know if an
* optimized .js version of a text resource should be loaded
* instead.
* @param {String} url
* @returns Boolean
*/
useXhr: function (url, protocol, hostname, port) {
var uProtocol, uHostName, uPort,
match = text.xdRegExp.exec(url);
if (!match) {
return true;
}
uProtocol = match[2];
uHostName = match[3];
uHostName = uHostName.split(':');
uPort = uHostName[1];
uHostName = uHostName[0];
return (!uProtocol || uProtocol === protocol) &&
(!uHostName || uHostName.toLowerCase() === hostname.toLowerCase()) &&
((!uPort && !uHostName) || uPort === port);
},
finishLoad: function (name, strip, content, onLoad) {
content = strip ? text.strip(content) : content;
if (masterConfig.isBuild) {
buildMap[name] = content;
}
onLoad(content);
},
load: function (name, req, onLoad, config) {
//Name has format: some.module.filext!strip
//The strip part is optional.
//if strip is present, then that means only get the string contents
//inside a body tag in an HTML string. For XML/SVG content it means
//removing the <?xml ...?> declarations so the content can be inserted
//into the current doc without problems.
// Do not bother with the work if a build and text will
// not be inlined.
if (config && config.isBuild && !config.inlineText) {
onLoad();
return;
}
masterConfig.isBuild = config && config.isBuild;
var parsed = text.parseName(name),
nonStripName = parsed.moduleName +
(parsed.ext ? '.' + parsed.ext : ''),
url = req.toUrl(nonStripName),
useXhr = (masterConfig.useXhr) ||
text.useXhr;
// Do not load if it is an empty: url
if (url.indexOf('empty:') === 0) {
onLoad();
return;
}
//Load the text. Use XHR if possible and in a browser.
if (!hasLocation || useXhr(url, defaultProtocol, defaultHostName, defaultPort)) {
text.get(url, function (content) {
text.finishLoad(name, parsed.strip, content, onLoad);
}, function (err) {
if (onLoad.error) {
onLoad.error(err);
}
});
} else {
//Need to fetch the resource across domains. Assume
//the resource has been optimized into a JS module. Fetch
//by the module name + extension, but do not include the
//!strip part to avoid file system issues.
req([nonStripName], function (content) {
text.finishLoad(parsed.moduleName + '.' + parsed.ext,
parsed.strip, content, onLoad);
});
}
},
write: function (pluginName, moduleName, write, config) {
if (buildMap.hasOwnProperty(moduleName)) {
var content = text.jsEscape(buildMap[moduleName]);
write.asModule(pluginName + "!" + moduleName,
"define(function () { return '" +
content +
"';});\n");
}
},
writeFile: function (pluginName, moduleName, req, write, config) {
var parsed = text.parseName(moduleName),
extPart = parsed.ext ? '.' + parsed.ext : '',
nonStripName = parsed.moduleName + extPart,
//Use a '.js' file name so that it indicates it is a
//script that can be loaded across domains.
fileName = req.toUrl(parsed.moduleName + extPart) + '.js';
//Leverage own load() method to load plugin value, but only
//write out values that do not have the strip argument,
//to avoid any potential issues with ! in file names.
text.load(nonStripName, req, function (value) {
//Use own write() method to construct full module value.
//But need to create shell that translates writeFile's
//write() to the right interface.
var textWrite = function (contents) {
return write(fileName, contents);
};
textWrite.asModule = function (moduleName, contents) {
return write.asModule(moduleName, fileName, contents);
};
text.write(pluginName, nonStripName, textWrite, config);
}, config);
}
};
if (masterConfig.env === 'node' || (!masterConfig.env &&
typeof process !== "undefined" &&
process.versions &&
!!process.versions.node &&
!process.versions['node-webkit'])) {
//Using special require.nodeRequire, something added by r.js.
fs = require.nodeRequire('fs');
text.get = function (url, callback, errback) {
try {
var file = fs.readFileSync(url, 'utf8');
//Remove BOM (Byte Mark Order) from utf8 files if it is there.
if (file.indexOf('\uFEFF') === 0) {
file = file.substring(1);
}
callback(file);
} catch (e) {
if (errback) {
errback(e);
}
}
};
} else if (masterConfig.env === 'xhr' || (!masterConfig.env &&
text.createXhr())) {
text.get = function (url, callback, errback, headers) {
var xhr = text.createXhr(), header;
xhr.open('GET', url, true);
//Allow plugins direct access to xhr headers
if (headers) {
for (header in headers) {
if (headers.hasOwnProperty(header)) {
xhr.setRequestHeader(header.toLowerCase(), headers[header]);
}
}
}
//Allow overrides specified in config
if (masterConfig.onXhr) {
masterConfig.onXhr(xhr, url);
}
xhr.onreadystatechange = function (evt) {
var status, err;
//Do not explicitly handle errors, those should be
//visible via console output in the browser.
if (xhr.readyState === 4) {
status = xhr.status || 0;
if (status > 399 && status < 600) {
//An http 4xx or 5xx error. Signal an error.
err = new Error(url + ' HTTP status: ' + status);
err.xhr = xhr;
if (errback) {
errback(err);
}
} else {
callback(xhr.responseText);
}
if (masterConfig.onXhrComplete) {
masterConfig.onXhrComplete(xhr, url);
}
}
};
xhr.send(null);
};
} else if (masterConfig.env === 'rhino' || (!masterConfig.env &&
typeof Packages !== 'undefined' && typeof java !== 'undefined')) {
//Why Java, why is this so awkward?
text.get = function (url, callback) {
var stringBuffer, line,
encoding = "utf-8",
file = new java.io.File(url),
lineSeparator = java.lang.System.getProperty("line.separator"),
input = new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(file), encoding)),
content = '';
try {
stringBuffer = new java.lang.StringBuffer();
line = input.readLine();
// Byte Order Mark (BOM) - The Unicode Standard, version 3.0, page 324
// http://www.unicode.org/faq/utf_bom.html
// Note that when we use utf-8, the BOM should appear as "EF BB BF", but it doesn't due to this bug in the JDK:
// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058
if (line && line.length() && line.charAt(0) === 0xfeff) {
// Eat the BOM, since we've already found the encoding on this file,
// and we plan to concatenating this buffer with others; the BOM should
// only appear at the top of a file.
line = line.substring(1);
}
if (line !== null) {
stringBuffer.append(line);
}
while ((line = input.readLine()) !== null) {
stringBuffer.append(lineSeparator);
stringBuffer.append(line);
}
//Make sure we return a JavaScript string and not a Java string.
content = String(stringBuffer.toString()); //String
} finally {
input.close();
}
callback(content);
};
} else if (masterConfig.env === 'xpconnect' || (!masterConfig.env &&
typeof Components !== 'undefined' && Components.classes &&
Components.interfaces)) {
//Avert your gaze!
Cc = Components.classes;
Ci = Components.interfaces;
Components.utils['import']('resource://gre/modules/FileUtils.jsm');
xpcIsWindows = ('@mozilla.org/windows-registry-key;1' in Cc);
text.get = function (url, callback) {
var inStream, convertStream, fileObj,
readData = {};
if (xpcIsWindows) {
url = url.replace(/\//g, '\\');
}
fileObj = new FileUtils.File(url);
//XPCOM, you so crazy
try {
inStream = Cc['@mozilla.org/network/file-input-stream;1']
.createInstance(Ci.nsIFileInputStream);
inStream.init(fileObj, 1, 0, false);
convertStream = Cc['@mozilla.org/intl/converter-input-stream;1']
.createInstance(Ci.nsIConverterInputStream);
convertStream.init(inStream, "utf-8", inStream.available(),
Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
convertStream.readString(inStream.available(), readData);
convertStream.close();
inStream.close();
callback(readData.value);
} catch (e) {
throw new Error((fileObj && fileObj.path || '') + ': ' + e);
}
};
}
return text;
});

29
iguana/docs/supernet/site/mkdocs/search_index.json

@ -0,0 +1,29 @@
{
"docs": [
{
"location": "/",
"text": "Developers\n\n\n\n\nGetting Started\n\n\nDesktop App SDK\n\n\nMobile App SDK\n\n Android\n\n iOS\n** Windows\n\n\nIguana/SuperNET API Reference: Any General SuperNET specific API reference\n\n Coins ( ablaze )\n\n Peers ( eyedea )\n\n\nSuperNET Apps specific API Reference: Organising Applications specific API reference and interlinking between other pages to refer if the same API is used in between these applications.\n\n InstantDEX API\n\n Pegged Asset Exchange (PAX) API\n** Jumblr API\n\n\nIguana/SuperNET Core Coin API Reference: Referecing to SuperNET's core coin's API reference which might be nessary to function or build Iguana/SuperNET Application, and where it's using some different API calls than official APIs\n\n BitcoinDark API\n\n Bitcoin API\n\n\n\n\nFor Users\n\n\n\n\nIguana Chrome App User Manual\n\n\nIguana Mobile App\n\n Android\n\n iOS\n\n\nInstantDEX User Manual\n\n\nPegged Asset Exchange (PAX) User Manual\n\n\nJumblr User Manual",
"title": "Home"
},
{
"location": "/#developers",
"text": "Getting Started Desktop App SDK Mobile App SDK Android iOS\n** Windows Iguana/SuperNET API Reference: Any General SuperNET specific API reference Coins ( ablaze ) Peers ( eyedea ) SuperNET Apps specific API Reference: Organising Applications specific API reference and interlinking between other pages to refer if the same API is used in between these applications. InstantDEX API Pegged Asset Exchange (PAX) API\n** Jumblr API Iguana/SuperNET Core Coin API Reference: Referecing to SuperNET's core coin's API reference which might be nessary to function or build Iguana/SuperNET Application, and where it's using some different API calls than official APIs BitcoinDark API Bitcoin API",
"title": "Developers"
},
{
"location": "/#for-users",
"text": "Iguana Chrome App User Manual Iguana Mobile App Android iOS InstantDEX User Manual Pegged Asset Exchange (PAX) User Manual Jumblr User Manual",
"title": "For Users"
},
{
"location": "/about/",
"text": "About Us",
"title": "About"
},
{
"location": "/about/#about-us",
"text": "",
"title": "About Us"
}
]
}

138
iguana/docs/supernet/site/search.html

@ -0,0 +1,138 @@
<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SuperNET Documentation</title>
<link rel="shortcut icon" href="./img/favicon.ico">
<link href='https://fonts.googleapis.com/css?family=Lato:400,700|Roboto+Slab:400,700|Inconsolata:400,700' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="./css/theme.css" type="text/css" />
<link rel="stylesheet" href="./css/theme_extra.css" type="text/css" />
<link rel="stylesheet" href="./css/highlight.css">
<script src="./js/jquery-2.1.1.min.js"></script>
<script src="./js/modernizr-2.8.3.min.js"></script>
<script type="text/javascript" src="./js/highlight.pack.js"></script>
<script src="./js/theme.js"></script>
<script>var base_url = '.';</script>
<script data-main="./mkdocs/js/search.js" src="./mkdocs/js/require.js"></script>
</head>
<body class="wy-body-for-nav" role="document">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side stickynav">
<div class="wy-side-nav-search">
<a href="." class="icon icon-home"> SuperNET Documentation</a>
<div role="search">
<form id ="rtd-search-form" class="wy-form" action="./search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
</form>
</div>
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
<ul class="current">
<li>
<li class="toctree-l1 ">
<a class="" href=".">Home</a>
</li>
<li>
<li>
<li class="toctree-l1 ">
<a class="" href="about/">About</a>
</li>
<li>
</ul>
</div>
&nbsp;
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" role="navigation" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href=".">SuperNET Documentation</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href=".">Docs</a> &raquo;</li>
<li class="wy-breadcrumbs-aside">
</li>
</ul>
<hr/>
</div>
<div role="main">
<div class="section">
<h1 id="search">Search Results</h1>
<form id="content_search" action="search.html">
<span role="status" aria-live="polite" class="ui-helper-hidden-accessible"></span>
<input name="q" id="mkdocs-search-query" type="text" class="search_input search-query ui-autocomplete-input" placeholder="Search the Docs" autocomplete="off" autofocus>
</form>
<div id="mkdocs-search-results">
Sorry, page not found.
</div>
</div>
</div>
<footer>
<hr/>
<div role="contentinfo">
<!-- Copyright etc -->
</div>
Built with <a href="http://www.mkdocs.org">MkDocs</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<div class="rst-versions" role="note" style="cursor: pointer">
<span class="rst-current-version" data-toggle="rst-current-version">
</span>
</div>
</body>
</html>

20
iguana/docs/supernet/site/sitemap.xml

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>None/</loc>
<lastmod>2015-12-22</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>None/about/</loc>
<lastmod>2015-12-22</lastmod>
<changefreq>daily</changefreq>
</url>
</urlset>

281
iguana/example.js

@ -0,0 +1,281 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
function moduleDidLoad() {
common.hideModule();
}
function $(id) {
return document.getElementById(id);
}
/*
* file system functions
*
*/
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
function errorHandler(e,callback,name) {
var msg = '';
switch (e.code) {
case FileError.QUOTA_EXCEEDED_ERR:
msg = 'QUOTA_EXCEEDED_ERR';
break;
case FileError.NOT_FOUND_ERR:
msg = 'NOT_FOUND_ERR';
callback(name);
break;
case FileError.SECURITY_ERR:
msg = 'SECURITY_ERR';
break;
case FileError.INVALID_MODIFICATION_ERR:
msg = 'INVALID_MODIFICATION_ERR';
break;
case FileError.INVALID_STATE_ERR:
msg = 'INVALID_STATE_ERR';
break;
default:
msg = 'Unknown Error';
break;
};
console.log('Error: ' + msg);
}
var fileSystem=null;
var files={};
function onInitFs(fs) {
console.log('Opened file system: ' + fs.name);
fileSystem = fs;
}
// Called by the common.js module.
function domContentLoaded(name, tc, config, width, height) {
navigator.webkitPersistentStorage.requestQuota(10000000000,
function(bytes){
window.requestFileSystem(PERSISTENT, bytes, onInitFs, errorHandler);
common.updateStatus(
'Allocated ' + bytes + ' bytes of persistent storage. Running the first time will take 17 seconds to load');
common.attachDefaultListeners();
common.createNaClModule(name, tc, config, width, height);
}, function(e){
console.log('Error', e);
});
}
var check_files=function(){
var coins= coinManagement.getCoinSymbols();
var files=["_hdrs.txt","_peers.txt"];
for(var i=0;i<coins.length;i++){
for(var j=0;j<files.length;j++){
var name="confs/"+coins[i]+files[j];
console.log("checking file "+name);
files[name]=null;
check_if_file_present(name);
}
}
};
var check_if_file_present=function(filename,callback){
fileSystem.root.getFile(filename, {}, function(fileEntry) {
//console.log("entered file fu");
// Get a File object representing the file,
// then use FileReader to read its contents.
fileEntry.file(function(file) {
var reader = new FileReader();
reader.onloadend = function(e) {
//var txtArea = document.createElement('textarea');
//console.log("Configuration file text: "+this.result.toString());
console.log("File already present in HTML5 system:"+fileEntry.fullPath);
//SPNAPI.conf_files[filename]=this.result.toString();
};
reader.readAsText(file);
}, function(e){
errorHandler(e,access_and_save_conf_file,filename);
});
}, function(e){
errorHandler(e,access_and_save_conf_file,filename);
});
};
var access_and_save_conf_file=function(name){
console.log("access file called for "+name);
$.ajax({
type: "GET",
url: name,
//async: false,
success: function (data){
save_contents(data,name);
}
});
};
var save_contents=function(contents,name){
fileSystem.root.getFile(name, {create: true}, function(fileEntry) {
// Create a FileWriter object for our FileEntry (log.txt).
fileEntry.createWriter(function(fileWriter) {
fileWriter.onwriteend = function(e) {
console.log('Write completed.');
};
fileWriter.onerror = function(e) {
console.log('Write failed: ' + e.toString());
};
// Create a new Blob and write it to log.txt.
var blob = new Blob([contents], {type: 'text/plain'});
fileWriter.write(blob);
}, errorHandler);
}, errorHandler);
};
// Called by the common.js module.
function attachListeners() {
var radioEls = document.querySelectorAll('input[type="radio"]');
for (var i = 0; i < radioEls.length; ++i) {
radioEls[i].addEventListener('click', onRadioClicked);
}
// Wire up the 'click' event for each function's button.
var functionEls = document.querySelectorAll('.function');
for (var i = 0; i < functionEls.length; ++i) {
var functionEl = functionEls[i];
var id = functionEl.getAttribute('id');
var buttonEl = functionEl.querySelector('button');
// The function name matches the element id.
var func = window[id];
buttonEl.addEventListener('click', func);
}
//$('pipe_input_box').addEventListener('keypress', onPipeInput)
//$('pipe_output').disabled = true;
//$('pipe_name').addEventListener('change', function() { $('pipe_output').value = ''; })
}
// Called with keypress events on the pipe input box
function onPipeInput(e) {
// Create an arraybuffer containing the 16-bit char code
// from the keypress event.
var buffer = new ArrayBuffer(1*2);
var bufferView = new Uint16Array(buffer);
bufferView[0] = e.charCode;
// Pass the buffer in a dictionary over the NaCl module
var pipeSelect = $('pipe_name');
var pipeName = pipeSelect[pipeSelect.selectedIndex].value;
var message = {
pipe: pipeName,
operation: 'write',
payload: buffer,
};
nacl_module.postMessage(message);
e.preventDefault();
return false;
}
function onRadioClicked(e) {
var divId = this.id.slice(5); // skip "radio"
var functionEls = document.querySelectorAll('.function');
for (var i = 0; i < functionEls.length; ++i) {
var visible = functionEls[i].id === divId;
if (functionEls[i].id === divId)
functionEls[i].removeAttribute('hidden');
else
functionEls[i].setAttribute('hidden', '');
}
}
function addNameToSelectElements(cssClass, handle, name) {
var text = '[' + handle + '] ' + name;
var selectEls = document.querySelectorAll(cssClass);
for (var i = 0; i < selectEls.length; ++i) {
var optionEl = document.createElement('option');
optionEl.setAttribute('value', handle);
optionEl.appendChild(document.createTextNode(text));
selectEls[i].appendChild(optionEl);
}
}
function removeNameFromSelectElements(cssClass, handle) {
var optionEls = document.querySelectorAll(cssClass + ' > option');
for (var i = 0; i < optionEls.length; ++i) {
var optionEl = optionEls[i];
if (optionEl.value == handle) {
var selectEl = optionEl.parentNode;
selectEl.removeChild(optionEl);
}
}
}
var funcToCallback = {};
function postCall(func) {
var callback = arguments[arguments.length - 1];
funcToCallback[func] = callback;
nacl_module.postMessage({
cmd: func,
args: Array.prototype.slice.call(arguments, 1, -1)
});
}
function ArrayBufferToString(buf) { return String.fromCharCode.apply(null, new Uint16Array(buf)); }
// Called by the common.js module.
function handleMessage(message_event) {
var data = message_event.data;
if ((typeof(data) === 'string' || data instanceof String)) {
common.logMessage(data);
}
else if (data instanceof Object)
{
var pipeName = data['pipe']
if ( pipeName !== undefined )
{
// Message for JavaScript I/O pipe
var operation = data['operation'];
if (operation == 'write') {
$('pipe_output').value += ArrayBufferToString(data['payload']);
} else if (operation == 'ack') {
common.logMessage(pipeName + ": ack:" + data['payload']);
} else {
common.logMessage('Got unexpected pipe operation: ' + operation);
}
}
else
{
// Result from a function call.
var params = data.args;
var funcName = data.cmd;
var callback = funcToCallback[funcName];
if (!callback)
{
common.logMessage('Error: Bad message ' + funcName + ' received from NaCl module.');
return;
}
delete funcToCallback[funcName];
callback.apply(null, params);
}
} else {
common.logMessage('Error: Unknow message `' + data + '` received from NaCl module.');
}
}

110
iguana/exchanges/PAX.c

@ -0,0 +1,110 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#define EXCHANGE_NAME "PAX"
#define UPDATE PAX ## _price
#define SUPPORTS PAX ## _supports
#define SIGNPOST PAX ## _signpost
#define TRADE PAX ## _trade
#define ORDERSTATUS PAX ## _orderstatus
#define CANCELORDER PAX ## _cancelorder
#define OPENORDERS PAX ## _openorders
#define TRADEHISTORY PAX ## _tradehistory
#define BALANCES PAX ## _balances
#define PARSEBALANCE PAX ## _parsebalance
#define WITHDRAW PAX ## _withdraw
#define CHECKBALANCE PAX ## _checkbalance
#define ALLPAIRS PAX ## _allpairs
#define FUNCS PAX ## _funcs
#define BASERELS PAX ## _baserels
#include "../peggy.h"
char *peggy_bases[64] =
{
"BTCD", "USD", "EUR", "JPY", "GBP", "AUD", "CAD", "CHF", "NZD", // major currencies
"CNY", "RUB", "MXN", "BRL", "INR", "HKD", "TRY", "ZAR", "PLN", "NOK", "SEK", "DKK", "CZK", "HUF", "ILS", "KRW", "MYR", "PHP", "RON", "SGD", "THB", "BGN", "IDR", "HRK",
"BTCUSD", "NXTBTC", "SuperNET", "ETHBTC", "LTCBTC", "XMRBTC", "BTSBTC", "XCPBTC", // BTC priced
"XAUUSD", "XAGUSD", "XPTUSD", "XPDUSD", "COPPER", "NGAS", "UKOIL", "USOIL", // USD priced
"BUND", "NAS100", "SPX500", "US30", "EUSTX50", "UK100", "JPN225", "GER30", "SUI30", "AUS200", "HKG33", "XAUUSD", "BTCRUB", "BTCCNY", "BTCUSD" // abstract
};
char *ALLPAIRS(struct exchange_info *exchange,cJSON *argjson)
{
return(clonestr("{\"error\":\"PAX is not yet\"}"));
}
int32_t SUPPORTS(struct exchange_info *exchange,char *base,char *rel,cJSON *argjson)
{
return(0);
}
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert)
{
return(0);
}
cJSON *SIGNPOST(void **cHandlep,int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *payload,char *path)
{
if ( retstrp != 0 )
*retstrp = clonestr("{\"error\":\"PAX signing is not yet\"}");
return(cJSON_Parse("{}"));
}
char *PARSEBALANCE(struct exchange_info *exchange,double *balancep,char *coinstr,cJSON *argjson)
{
return(clonestr("{\"error\":\"PAX parsebalance is not yet\"}"));
}
cJSON *BALANCES(struct exchange_info *exchange,cJSON *argjson)
{
return(cJSON_Parse("{\"error\":\"PAX balances is not yet\"}"));
}
uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *base,char *rel,int32_t dir,double price,double volume,cJSON *argjson)
{
return(0);
}
char *ORDERSTATUS(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson)
{
return(clonestr("{\"error\":\"PAX orderstatus is not yet\"}"));
}
char *CANCELORDER(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson)
{
return(clonestr("{\"error\":\"PAX cancel order is not yet\"}"));
}
char *OPENORDERS(struct exchange_info *exchange,cJSON *argjson)
{
return(clonestr("{\"error\":\"PAX open orders is not yet\"}"));
}
char *TRADEHISTORY(struct exchange_info *exchange,cJSON *argjson)
{
return(clonestr("{\"error\":\"PAX tradehistory is not yet\"}"));
}
char *WITHDRAW(struct exchange_info *exchange,char *base,double amount,char *destaddr,cJSON *argjson)
{
return(clonestr("{\"error\":\"PAX redeem is not yet\"}"));
}
struct exchange_funcs PAX_funcs = EXCHANGE_FUNCS(PAX,EXCHANGE_NAME);
#include "exchange_undefs.h"

1280
iguana/exchanges/bitcoin.c

File diff suppressed because it is too large

42
iguana/exchanges/bitcoin.h

@ -0,0 +1,42 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include "../../includes/openssl/ec.h"
#include "../../includes/openssl/ecdsa.h"
#include "../../includes/openssl/obj_mac.h"
#define SIGHASH_ALL 1
#define SIGHASH_NONE 2
#define SIGHASH_SINGLE 3
#define SIGHASH_ANYONECANPAY 0x80
#define SCRIPT_OP_TRUE 0x51
#define SCRIPT_OP_2 0x52
#define SCRIPT_OP_3 0x53
#define SCRIPT_OP_IF 0x63
#define SCRIPT_OP_ELSE 0x67
#define SCRIPT_OP_RETURN 0x6a
#define SCRIPT_OP_DUP 0x76
#define SCRIPT_OP_ENDIF 0x68
#define OP_DROP 0x75
#define SCRIPT_OP_EQUALVERIFY 0x88
#define SCRIPT_OP_HASH160 0xa9
#define SCRIPT_OP_EQUAL 0x87
#define SCRIPT_OP_CHECKSIG 0xac
#define SCRIPT_OP_CHECKMULTISIG 0xae
#define OP_CHECKSEQUENCEVERIFY 0xb2
#define OP_CHECKLOCKTIMEVERIFY 0xb1
struct bp_key { EC_KEY *k; };

251
iguana/exchanges/bitfinex.c

@ -0,0 +1,251 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#define EXCHANGE_NAMESTR "bitfinex"
#define EXCHANGE_NAME #bitfinex
#define UPDATE bitfinex ## _price
#define SUPPORTS bitfinex ## _supports
#define SIGNPOST bitfinex ## _signpost
#define TRADE bitfinex ## _trade
#define ORDERSTATUS bitfinex ## _orderstatus
#define CANCELORDER bitfinex ## _cancelorder
#define OPENORDERS bitfinex ## _openorders
#define TRADEHISTORY bitfinex ## _tradehistory
#define BALANCES bitfinex ## _balances
#define PARSEBALANCE bitfinex ## _parsebalance
#define WITHDRAW bitfinex ## _withdraw
#define CHECKBALANCE bitfinex ## _checkbalance
#define ALLPAIRS bitfinex ## _allpairs
#define FUNCS bitfinex ## _funcs
#define BASERELS bitfinex ## _baserels
static char *BASERELS[][2] = { {"btc","usd"}, {"ltc","usd"}, {"ltc","btc"}, {"",""} };
#include "exchange_supports.h"
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert)
{
char url[1024];
sprintf(url,"https://api.bitfinex.com/v1/book/%s%s",base,rel);
return(exchanges777_standardprices(exchange,commission,base,rel,url,quotes,"price","amount",maxdepth,0,invert));
}
char *PARSEBALANCE(struct exchange_info *exchange,double *balancep,char *coinstr,cJSON *argjson)
{
//[[{"type":"deposit","currency":"btc","amount":"0.0","available":"0.0"},{"type":"deposit","currency":"usd","amount":"0.0","available":"0.0"},{"type":"exchange","currency":"btc","amount":"0.01065851","available":"0.01065851"},{"type":"exchange","currency":"usd","amount":"23386.37278962","available":"0.00378962"},{"type":"trading","currency":"btc","amount":"0.0","available":"0.0"},{"type":"trading","currency":"usd","amount":"0.0","available":"0.0"}]]
int32_t i,n,ind; char field[64],*str,*typestr,*itemstr = 0; cJSON *item,*obj,*array; double amounts[3],avail[3],val0,val1;
*balancep = 0.;
strcpy(field,coinstr), tolowercase(field);
memset(amounts,0,sizeof(amounts));
memset(avail,0,sizeof(avail));
if ( argjson != 0 && is_cJSON_Array(argjson) != 0 && (n= cJSON_GetArraySize(argjson)) > 0 )
{
for (i=0; i<n; i++)
{
if ( (item= jitem(argjson,i)) != 0 )
{
if ( (str= jstr(item,"currency")) != 0 && strcmp(field,str) == 0 )
{
val0 = jdouble(item,"amount");
val1 = jdouble(item,"available");
if ( (typestr= jstr(item,"type")) != 0 )
{
if ( strcmp(typestr,"deposit") == 0 )
ind = 0;
else if ( strcmp(typestr,"exchange") == 0 )
ind = 1;
else if ( strcmp(typestr,"trading") == 0 )
ind = 2;
else ind = -1;
if ( ind >= 0 )
{
amounts[ind] = val0;
avail[ind] = val1;
}
}
}
}
}
if ( (obj= cJSON_CreateObject()) != 0 )
{
touppercase(field);
*balancep = avail[0] + avail[1] + avail[2];
jaddstr(obj,"base",field);
jaddnum(obj,"balance",*balancep);
jaddnum(obj,"total",amounts[0]+amounts[1]+amounts[2]);
array = cJSON_CreateArray(), jaddinum(array,avail[0]), jaddinum(array,amounts[0]), jadd(obj,"deposit",array);
array = cJSON_CreateArray(), jaddinum(array,avail[1]), jaddinum(array,amounts[1]), jadd(obj,"exchange",array);
array = cJSON_CreateArray(), jaddinum(array,avail[2]), jaddinum(array,amounts[2]), jadd(obj,"trading",array);
itemstr = jprint(obj,1);
}
}
if ( itemstr == 0 )
return(clonestr("{\"error\":\"cant find coin balance\"}"));
return(itemstr);
}
cJSON *SIGNPOST(void **cHandlep,int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *payload,char *method)
{
char dest[1025],url[1024],hdr1[512],hdr2[512],hdr3[512],hdr4[512],req[1024],*sig,*data = 0; cJSON *json;
hdr1[0] = hdr2[0] = hdr3[0] = hdr4[0] = 0;
json = 0;
nn_base64_encode((void *)payload,strlen(payload),req,sizeof(req));
if ( (sig= hmac_sha384_str(dest,exchange->apisecret,(int32_t)strlen(exchange->apisecret),req)) != 0 )
{
sprintf(hdr1,"X-BFX-APIKEY:%s",exchange->apikey);
sprintf(hdr2,"X-BFX-PAYLOAD:%s",req);
sprintf(hdr3,"X-BFX-SIGNATURE:%s",sig);
//printf("req.(%s) H0.(%s) H1.(%s) H2.(%s)\n",req,hdr1,hdr2,hdr3);
sprintf(url,"https://api.bitfinex.com/v1/%s",method);
if ( dotrade == 0 )
data = exchange_would_submit(req,hdr1,hdr2,hdr3,hdr4);
else if ( (data= curl_post(&exchange->cHandle,url,0,req,hdr1,hdr2,hdr3,hdr4)) != 0 )
json = cJSON_Parse(data);
if ( retstrp != 0 )
*retstrp = data;
else if ( data != 0 )
free(data);
}
return(json);
}
cJSON *BALANCES(struct exchange_info *exchange,cJSON *argjson)
{
char payload[1024],*method;
method = "balances";
sprintf(payload,"{\"request\":\"/v1/%s\",\"nonce\":\"%llu\"}",method,(long long)exchange_nonce(exchange));
return(SIGNPOST(&exchange->cHandle,1,0,exchange,payload,method));
}
#include "checkbalance.c"
uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *base,char *rel,int32_t dir,double price,double volume,cJSON *argjson)
{
char payload[1024],pairstr[512],*typestr,*method,*extra; cJSON *json; uint64_t txid = 0;
if ( (extra= *retstrp) != 0 )
*retstrp = 0;
if ( (dir= flipstr_for_exchange(exchange,pairstr,"%s%s",dir,&price,&volume,base,rel,argjson)) == 0 )
{
printf("cant find baserel (%s/%s)\n",base,rel);
return(0);
}
method = "order/new";
//Either "market" / "limit" / "stop" / "trailing-stop" / "fill-or-kill" / "exchange market" / "exchange limit" / "exchange stop" / "exchange trailing-stop" / "exchange fill-or-kill". (type starting by "exchange " are exchange orders, others are margin trading orders)
if ( (typestr= extra) == 0 )
typestr = "exchange limit";
sprintf(payload,"{\"request\":\"/v1/%s\",\"nonce\":\"%llu\",\"exchange\":\"bitfinex\",\"side\":\"%s\",\"type\":\"%s\",\"price\":\"%.8f\",\"amount\":\"%.8f\",\"symbol\":\"%s\"}",method,(long long)exchange_nonce(exchange),dir>0?"buy":"sell",typestr,price,volume,pairstr);
if ( CHECKBALANCE(retstrp,dotrade,exchange,dir,base,rel,price,volume,argjson) == 0 && (json= SIGNPOST(&exchange->cHandle,dotrade,retstrp,exchange,payload,method)) != 0 )
{
if ( (txid= j64bits(json,"order_id")) == 0 )
{
if ( dir != 0 )
printf("bitfinex: no txid error\n");
}
free_json(json);
}
return(txid);
}
char *ORDERSTATUS(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson)
{
char payload[1024],*method,*retstr = 0; cJSON *json;
method = "order/status";
sprintf(payload,"{\"request\":\"/v1/%s\",\"nonce\":\"%llu\",\"order_id\":%llu}",method,(long long)exchange_nonce(exchange),(long long)quoteid);
if ( (json= SIGNPOST(&exchange->cHandle,1,&retstr,exchange,payload,method)) != 0 )
{
free_json(json);
}
return(retstr); // return standardized orderstatus
}
char *CANCELORDER(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson)
{
char payload[1024],*method,*retstr = 0; cJSON *json;
method = "order/cancel";
sprintf(payload,"{\"request\":\"/v1/%s\",\"nonce\":\"%llu\",\"order_id\":%llu}",method,(long long)exchange_nonce(exchange),(long long)quoteid);
if ( (json= SIGNPOST(&exchange->cHandle,1,&retstr,exchange,payload,method)) != 0 )
{
free_json(json);
}
return(retstr); // return standardized cancelorder
}
char *OPENORDERS(struct exchange_info *exchange,cJSON *argjson)
{
char payload[1024],*method,*retstr = 0; cJSON *json;
method = "orders";
sprintf(payload,"{\"request\":\"/v1/%s\",\"nonce\":\"%llu\"}",method,(long long)exchange_nonce(exchange));
if ( (json= SIGNPOST(&exchange->cHandle,1,&retstr,exchange,payload,method)) != 0 )
{
free_json(json);
}
return(retstr); // return standardized open orders
}
char *TRADEHISTORY(struct exchange_info *exchange,cJSON *argjson)
{
char payload[1024],baserel[16],*method,*base,*rel,*retstr = 0; uint32_t timestamp; cJSON *json;
method = "mytrades";
base = jstr(argjson,"base");
rel = jstr(argjson,"rel");
if ( base == 0 || rel == 0 )
{
base = "BTC";
rel = "USD";
}
sprintf(baserel,"%s%s",base,rel);
timestamp = juint(argjson,"start");
sprintf(payload,"{\"request\":\"/v1/%s\",\"nonce\":\"%llu\",\"symbol\":\"%s\",\"timestamp\":%u}",method,(long long)exchange_nonce(exchange),baserel,timestamp);
//printf("TRADEHISTORY.(%s)\n",payload);
if ( (json= SIGNPOST(&exchange->cHandle,1,&retstr,exchange,payload,method)) != 0 )
{
free_json(json);
}
return(retstr); // return standardized tradehistory
}
char *WITHDRAW(struct exchange_info *exchange,char *base,double amount,char *destaddr,cJSON *argjson)
{
char payload[1024],*method,*type,*retstr = 0; cJSON *json;
if ( base == 0 || base[0] == 0 )
return(clonestr("{\"error\":\"base not specified\"}"));
if ( destaddr == 0 || destaddr[0] == 0 )
return(clonestr("{\"error\":\"destaddr not specified\"}"));
if ( amount < SMALLVAL )
return(clonestr("{\"error\":\"amount not specified\"}"));
if ( base == 0 )
base = "bitcoin";
else if ( strcmp(base,"BTC") == 0 )
base = "bitcoin";
else if ( strcmp(base,"LTC") == 0 )
base = "litecoin";
else if ( strcmp(base,"DRK") == 0 )
base = "darkcoin";
else return(clonestr("{\"error\":\"invalid base specified\"}"));
if ( (type= jstr(argjson,"extra")) == 0 )
type = "exchange";
else if ( strcmp(type,"exchange") != 0 && strcmp(type,"trading") != 0 && strcmp(type,"deposit") != 0 )
return(clonestr("{\"error\":\"invalid wallet type specified\"}"));
method = "withdraw";
sprintf(payload,"{\"request\":\"/v1/%s\",\"nonce\":\"%llu\",\"amount\":\"%.6f\",\"withdraw_type\":\"%s\",\"walletselected\":\"%s\",\"address\":\"%s\"}",method,(long long)exchange_nonce(exchange),amount,base,type,destaddr);
if ( (json= SIGNPOST(&exchange->cHandle,1,&retstr,exchange,payload,method)) != 0 )
{
free_json(json);
}
return(retstr); // return standardized withdraw
}
struct exchange_funcs FUNCS = EXCHANGE_FUNCS(bitfinex,EXCHANGE_NAMESTR);
#include "exchange_undefs.h"

157
iguana/exchanges/bitstamp.c

@ -0,0 +1,157 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#define EXCHANGE_NAME "bitstamp"
#define UPDATE bitstamp ## _price
#define SUPPORTS bitstamp ## _supports
#define SIGNPOST bitstamp ## _signpost
#define TRADE bitstamp ## _trade
#define ORDERSTATUS bitstamp ## _orderstatus
#define CANCELORDER bitstamp ## _cancelorder
#define OPENORDERS bitstamp ## _openorders
#define TRADEHISTORY bitstamp ## _tradehistory
#define BALANCES bitstamp ## _balances
#define PARSEBALANCE bitstamp ## _parsebalance
#define WITHDRAW bitstamp ## _withdraw
#define EXCHANGE_AUTHURL "https://www.bitstamp.net/api"
#define CHECKBALANCE bitstamp ## _checkbalance
#define ALLPAIRS bitstamp ## _allpairs
#define FUNCS bitstamp ## _funcs
#define BASERELS bitstamp ## _baserels
static char *BASERELS[][2] = { {"btc","usd"} };
#include "exchange_supports.h"
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert)
{
char url[1024];
sprintf(url,"https://www.bitstamp.net/api/order_book/");
return(exchanges777_standardprices(exchange,commission,base,rel,url,quotes,0,0,maxdepth,0,invert));
}
cJSON *SIGNPOST(void **cHandlep,int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *method,char *payload)
{
/*signature is a HMAC-SHA256 encoded message containing: nonce, customer ID (can be found here) and API key. The HMAC-SHA256 code must be generated using a secret key that was generated with your API key. This code must be converted to it's hexadecimal representation (64 uppercase characters).Example (Python):
message = nonce + customer_id + api_key
signature = hmac.new(API_SECRET, msg=message, digestmod=hashlib.sha256).hexdigest().upper()
key - API key
signature - signature
nonce - nonce
*/
char dest[1025],url[1024],req[1024],hdr1[512],hdr2[512],hdr3[512],hdr4[512],*sig,*data = 0;
cJSON *json; uint64_t nonce;
hdr1[0] = hdr2[0] = hdr3[0] = hdr4[0] = 0;
nonce = exchange_nonce(exchange);
sprintf(req,"%llu%s%s",(long long)nonce,exchange->userid,exchange->apikey);
json = 0;
if ( (sig= hmac_sha256_str(dest,exchange->apisecret,(int32_t)strlen(exchange->apisecret),req)) != 0 )
{
//touppercase(sig);
//printf("req.(%s) sig.(%s)\n",req,sig);
//sprintf(req,"{\"key\":\"%s\",\"signature\":\"%s\",\"nonce\":%llu%s}",exchange->apikey,sig,(long long)nonce,payload);
sprintf(req,"key=%s&signature=%s&nonce=%llu%s",exchange->apikey,sig,(long long)nonce,payload);
//printf("submit.(%s)\n",req);
sprintf(url,"%s/%s/",EXCHANGE_AUTHURL,method);
if ( dotrade == 0 )
data = exchange_would_submit(req,hdr1,hdr2,hdr3,hdr4);
else if ( (data= curl_post(&exchange->cHandle,url,0,req,req,hdr2,hdr3,hdr4)) != 0 )
json = cJSON_Parse(data);
}
if ( retstrp != 0 )
*retstrp = data;
else if ( data != 0 )
free(data);
return(json);
}
char *PARSEBALANCE(struct exchange_info *exchange,double *balancep,char *coinstr,cJSON *argjson)
{
char field[128],*itemstr = 0; cJSON *obj,*item;
*balancep = 0.;
strcpy(field,coinstr);
tolowercase(field);
if ( argjson != 0 && (obj= jobj(argjson,"return")) != 0 && (item= jobj(obj,"funds")) != 0 )
{
*balancep = jdouble(item,field);
obj = cJSON_CreateObject();
touppercase(field);
jaddstr(obj,"base",field);
jaddnum(obj,"balance",*balancep);
itemstr = jprint(obj,1);
}
if ( itemstr == 0 )
return(clonestr("{\"error\":\"cant find coin balance\"}"));
return(itemstr);
}
cJSON *BALANCES(struct exchange_info *exchange,cJSON *argjson)
{
return(SIGNPOST(&exchange->cHandle,1,0,exchange,"balance",""));
}
#include "checkbalance.c"
uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *base,char *rel,int32_t dir,double price,double volume,cJSON *argjson)
{
char payload[1024],url[512],pairstr[512],*extra; cJSON *json; uint64_t txid = 0;
if ( (extra= *retstrp) != 0 )
*retstrp = 0;
if ( (dir= flipstr_for_exchange(exchange,pairstr,"%s%s",dir,&price,&volume,base,rel,argjson)) == 0 )
{
printf("cant find baserel (%s/%s)\n",base,rel);
return(0);
}
sprintf(url,"%s/%s/",EXCHANGE_AUTHURL,dir>0 ? "buy" : "sell");
if ( CHECKBALANCE(retstrp,dotrade,exchange,dir,base,rel,price,volume,argjson) == 0 && (json= SIGNPOST(&exchange->cHandle,dotrade,retstrp,exchange,url,payload)) != 0 )
{
// parse json and set txid
free_json(json);
}
return(txid);
}
char *ORDERSTATUS(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson)
{
char jsonbuf[128];
sprintf(jsonbuf,"&id=%llu",(long long)quoteid);
return(jprint(SIGNPOST(&exchange->cHandle,1,0,exchange,"order_status",jsonbuf),1));
}
char *CANCELORDER(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson)
{
char jsonbuf[128];
sprintf(jsonbuf,"&id=%llu",(long long)quoteid);
return(jprint(SIGNPOST(&exchange->cHandle,1,0,exchange,"cancel_order",jsonbuf),1));
}
char *OPENORDERS(struct exchange_info *exchange,cJSON *argjson)
{
return(jprint(SIGNPOST(&exchange->cHandle,1,0,exchange,"open_orders",""),1));
}
char *TRADEHISTORY(struct exchange_info *exchange,cJSON *argjson)
{
return(jprint(SIGNPOST(&exchange->cHandle,1,0,exchange,"user_transactions",""),1));
}
char *WITHDRAW(struct exchange_info *exchange,char *base,double amount,char *destaddr,cJSON *argjson)
{
return(clonestr("{\"error\":\"withdraw not yet\"}"));
}
struct exchange_funcs bitstamp_funcs = EXCHANGE_FUNCS(bitstamp,EXCHANGE_NAME);
#include "exchange_undefs.h"

268
iguana/exchanges/bittrex.c

@ -0,0 +1,268 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#define EXCHANGE_NAME "bittrex"
#define UPDATE bittrex ## _price
#define SUPPORTS bittrex ## _supports
#define SIGNPOST bittrex ## _signpost
#define TRADE bittrex ## _trade
#define ORDERSTATUS bittrex ## _orderstatus
#define CANCELORDER bittrex ## _cancelorder
#define OPENORDERS bittrex ## _openorders
#define TRADEHISTORY bittrex ## _tradehistory
#define BALANCES bittrex ## _balances
#define PARSEBALANCE bittrex ## _parsebalance
#define WITHDRAW bittrex ## _withdraw
#define CHECKBALANCE bittrex ## _checkbalance
#define ALLPAIRS bittrex ## _allpairs
#define FUNCS bittrex ## _funcs
static char *(*bittrex_baserels)[][2];
char *ALLPAIRS(struct exchange_info *exchange,cJSON *argjson)
{
static int32_t num;
char *jsonstr,*base,*rel; int32_t i; cJSON *json,*array,*item;
if ( num == 0 || (*bittrex_baserels) == 0 )
{
jsonstr = issue_curl("https://bittrex.com/api/v1.1/public/getmarkets");
if ( (json= cJSON_Parse(jsonstr)) != 0 )
{
if ( (array= jarray(&num,json,"result")) != 0 )
{
bittrex_baserels = calloc(num,sizeof(char *) * 2);
for (i=0; i<num; i++)
{
item = jitem(array,i);
base = jstr(item,"MarketCurrency");
rel = jstr(item,"BaseCurrency");
if ( base != 0 && rel != 0 )
{
(*bittrex_baserels)[i][0] = clonestr(base);
(*bittrex_baserels)[i][1] = clonestr(rel);
}
}
}
free_json(json);
}
free(jsonstr);
}
return(jprint(exchanges777_allpairs((*bittrex_baserels),num),1));
}
int32_t SUPPORTS(struct exchange_info *exchange,char *base,char *rel,cJSON *argjson)
{
if ( strlen(base) > 5 || strlen(rel) > 5 || strcmp(rel,"CNY") == 0 || strcmp(base,"CNY") == 0 || strcmp(rel,"USD") == 0 || strcmp(base,"USD") == 0 )
return(0);
if ( strcmp(rel,"BTC") == 0 )
return(1);
else if ( strcmp(base,"BTC") == 0 )
return(-1);
else return(0);
}
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert)
{
cJSON *json,*obj; char *jsonstr,market[128],url[1024]; double hbla = 0.;
sprintf(market,"%s-%s",rel,base);
sprintf(url,"https://bittrex.com/api/v1.1/public/getorderbook?market=%s&type=both&depth=%d",market,maxdepth);
jsonstr = issue_curl(url);
if ( jsonstr != 0 )
{
if ( (json = cJSON_Parse(jsonstr)) != 0 )
{
if ( (obj= cJSON_GetObjectItem(json,"success")) != 0 && is_cJSON_True(obj) != 0 )
hbla = exchanges777_json_orderbook(exchange,commission,base,rel,quotes,maxdepth,json,"result","buy","sell","Rate","Quantity",invert);
free_json(json);
}
free(jsonstr);
}
return(hbla);
}
cJSON *SIGNPOST(void **cHandlep,int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *url,char *payload)
{
char dest[(512>>3)*2+1],hdr1[512],hdr2[512],hdr3[512],hdr4[512],*data,*sig; cJSON *json;
hdr1[0] = hdr2[0] = hdr3[0] = hdr4[0] = 0;
json = 0;
if ( (sig= hmac_sha512_str(dest,exchange->apisecret,(int32_t)strlen(exchange->apisecret),payload)) != 0 )
sprintf(hdr1,"apisign:%s",sig);
if ( dotrade == 0 )
data = exchange_would_submit(payload,hdr1,hdr2,hdr3,hdr4);
else if ( (data= curl_post(&exchange->cHandle,url,0,payload,hdr1,hdr2,hdr3,hdr4)) != 0 )
json = cJSON_Parse(data);
if ( retstrp != 0 )
*retstrp = data;
else if ( data != 0 )
free(data);
return(json);
}
cJSON *BALANCES(struct exchange_info *exchange,cJSON *argjson)
{
char payload[1024];
sprintf(payload,"https://bittrex.com/api/v1.1/account/getbalances?apikey=%s&nonce=%llu",exchange->apikey,(long long)exchange_nonce(exchange));
return(SIGNPOST(&exchange->cHandle,1,0,exchange,payload,payload));
}
char *PARSEBALANCE(struct exchange_info *exchange,double *balancep,char *coinstr,cJSON *argjson)
{
int32_t i,n; char *str,*itemstr = 0; cJSON *item,*array,*obj; double total,pending;
*balancep = 0.;
if ( argjson != 0 && (array= jarray(&n,argjson,"result")) != 0 )
{
for (i=0; i<n; i++)
{
if ( (item= jitem(array,i)) != 0 )
{
if ( (str= jstr(item,"Currency")) != 0 && strcmp(coinstr,str) == 0 )
{
itemstr = jprint(item,0);
*balancep = jdouble(item,"Available");
total = jdouble(item,"Balance");
pending = jdouble(item,"Pending");
if ( (obj= cJSON_Parse(itemstr)) != 0 )
{
jaddnum(obj,"balance",*balancep);
jaddnum(obj,"total",total);
jaddnum(obj,"pending",pending);
if ( (str= jstr(obj,"CryptoAddress")) != 0 )
jaddstr(obj,"deposit_address",str);
free(itemstr);
itemstr = jprint(obj,1);
}
break;
}
}
}
}
if ( itemstr == 0 )
return(clonestr("{\"error\":\"cant find coin balance, are you sure it isnt empty account?\"}"));
return(itemstr);
}
#include "checkbalance.c"
uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *base,char *rel,int32_t dir,double price,double volume,cJSON *argjson)
{
char payload[1024],pairstr[512],*extra; cJSON *json,*resultobj; uint64_t txid = 0; int32_t i,j,n;
struct destbuf uuidstr; uint8_t databuf[512];
if ( (extra= *retstrp) != 0 )
*retstrp = 0;
if ( (dir= flip_for_exchange(pairstr,"%s-%s","BTC",dir,&price,&volume,base,rel)) == 0 )
{
return(0);
}
sprintf(payload,"https://bittrex.com/api/v1.1/market/%slimit?apikey=%s&nonce=%llu&market=%s&rate=%.8f&quantity=%.8f",dir>0?"buy":"sell",exchange->apikey,(long long)exchange_nonce(exchange),pairstr,price,volume);
if ( CHECKBALANCE(retstrp,dotrade,exchange,dir,base,rel,price,volume,argjson) == 0 && (json= SIGNPOST(&exchange->cHandle,dotrade,retstrp,exchange,payload,payload)) != 0 )
{
if ( is_cJSON_True(cJSON_GetObjectItem(json,"success")) != 0 && (resultobj= cJSON_GetObjectItem(json,"result")) != 0 )
{
copy_cJSON(&uuidstr,cJSON_GetObjectItem(resultobj,"uuid"));
for (i=j=0; uuidstr.buf[i]!=0; i++)
if ( uuidstr.buf[i] != '-' )
uuidstr.buf[j++] = uuidstr.buf[i];
uuidstr.buf[j] = 0;
n = (int32_t)strlen(uuidstr.buf);
printf("-> uuidstr.(%s).%d\n",uuidstr.buf,n);
decode_hex(databuf,n/2,uuidstr.buf);
if ( n >= 16 )
for (i=0; i<8; i++)
databuf[i] ^= databuf[8 + i];
memcpy(&txid,databuf,8);
printf("-> %llx\n",(long long)txid);
}
free_json(json);
}
return(txid);
}
char *ORDERSTATUS(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson)
{
char payload[1024],*retstr = 0; cJSON *json;
sprintf(payload,"https://bittrex.com/api/v1.1/account/getorder?apikey=%s&nonce=%llu&uuid=%llu",exchange->apikey,(long long)exchange_nonce(exchange),(long long)quoteid);
if ( (json= SIGNPOST(&exchange->cHandle,1,&retstr,exchange,payload,payload)) != 0 )
{
free_json(json);
}
return(retstr); // return standardized orderstatus
}
char *CANCELORDER(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson)
{
char payload[1024],*retstr = 0; cJSON *json;
sprintf(payload,"https://bittrex.com/api/v1.1/market/cancel?apikey=%s&nonce=%llu&uuid=%llu",exchange->apikey,(long long)exchange_nonce(exchange),(long long)quoteid);
if ( (json= SIGNPOST(&exchange->cHandle,1,&retstr,exchange,payload,payload)) != 0 )
{
free_json(json);
}
return(retstr); // return standardized cancelorder
}
char *OPENORDERS(struct exchange_info *exchange,cJSON *argjson)
{
char payload[1024],market[64],*base,*rel,*retstr = 0; cJSON *json;
sprintf(payload,"https://bittrex.com/api/v1.1/market/getopenorders?apikey=%s&nonce=%llu",exchange->apikey,(long long)exchange_nonce(exchange));
if ( (base= jstr(argjson,"base")) != 0 && (rel= jstr(argjson,"rel")) != 0 )
{
sprintf(market,"%s-%s",rel,base);
sprintf(payload + strlen(payload),"&market=%s",market);
}
if ( (json= SIGNPOST(&exchange->cHandle,1,&retstr,exchange,payload,payload)) != 0 )
{
free_json(json);
}
return(retstr); // return standardized open orders
}
char *TRADEHISTORY(struct exchange_info *exchange,cJSON *argjson)
{
char payload[1024],market[64],*base,*rel,*retstr = 0; cJSON *json;
sprintf(payload,"https://bittrex.com/api/v1.1/account/getorderhistory?apikey=%s&nonce=%llu",exchange->apikey,(long long)exchange_nonce(exchange));
if ( (base= jstr(argjson,"base")) != 0 && (rel= jstr(argjson,"rel")) != 0 )
{
sprintf(market,"%s-%s",rel,base);
sprintf(payload + strlen(payload),"&market=%s",market);
}
if ( (json= SIGNPOST(&exchange->cHandle,1,&retstr,exchange,payload,payload)) != 0 )
{
free_json(json);
}
return(retstr); // return standardized tradehistory
}
char *WITHDRAW(struct exchange_info *exchange,char *base,double amount,char *destaddr,cJSON *argjson)
{
char payload[1024],*paymentid,*retstr = 0; cJSON *json;
if ( base == 0 || base[0] == 0 )
return(clonestr("{\"error\":\"base not specified\"}"));
if ( destaddr == 0 || destaddr[0] == 0 )
return(clonestr("{\"error\":\"destaddr not specified\"}"));
if ( amount < SMALLVAL )
return(clonestr("{\"error\":\"amount not specified\"}"));
paymentid = jstr(argjson,"paymentid");
sprintf(payload,"https://bittrex.com/api/v1.1/account/withdraw?apikey=%s&nonce=%llu&currency=%s&amount=%.4f&address=%s",exchange->apikey,(long long)exchange_nonce(exchange),base,amount,destaddr);
if ( paymentid != 0 )
sprintf(payload + strlen(payload),"&paymentid=%s",paymentid);
if ( (json= SIGNPOST(&exchange->cHandle,1,&retstr,exchange,payload,payload)) != 0 )
{
free_json(json);
}
return(retstr); // return standardized withdraw
}
struct exchange_funcs bittrex_funcs = EXCHANGE_FUNCS(bittrex,EXCHANGE_NAME);
#include "exchange_undefs.h"

332
iguana/exchanges/btc38.c

@ -0,0 +1,332 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#define EXCHANGE_NAME "btc38"
#define UPDATE btc38 ## _price
#define SUPPORTS btc38 ## _supports
#define SIGNPOST btc38 ## _signpost
#define TRADE btc38 ## _trade
#define ORDERSTATUS btc38 ## _orderstatus
#define CANCELORDER btc38 ## _cancelorder
#define OPENORDERS btc38 ## _openorders
#define TRADEHISTORY btc38 ## _tradehistory
#define BALANCES btc38 ## _balances
#define PARSEBALANCE btc38 ## _parsebalance
#define WITHDRAW btc38 ## _withdraw
#define EXCHANGE_AUTHURL "http://www.btc38.com/trade/t_api"
#define CHECKBALANCE btc38 ## _checkbalance
#define ALLPAIRS btc38 ## _allpairs
#define FUNCS btc38 ## _funcs
char *btc38_cnypairs[] = { "BTC", "LTC", "DOGE", "XRP", "BTS", "XLM", "NXT", "BLK", "BC", "VPN", "BILS", "BOST", "PPC", "APC", "ZCC", "XPM", "DGC", "MEC", "WDC", "QRK", "BEC", "ANC", "UNC", "RIC", "SRC", "TAG" };
char *btc38_btcpairs[] = { "TMC", "LTC", "DOGE", "XRP", "BTS", "XEM", "XCN", "VOOT", "SYS", "NRS", "NAS", "SYNC", "MED", "EAC" };
char *ALLPAIRS(struct exchange_info *exchange,cJSON *argjson)
{
int32_t i; char str[65]; cJSON *json,*item,*array = cJSON_CreateArray();
for (i=0; i<sizeof(btc38_btcpairs)/sizeof(*btc38_btcpairs); i++)
{
item = cJSON_CreateArray();
jaddistr(item,uppercase_str(str,btc38_btcpairs[i]));
jaddistr(item,"BTC");
jaddi(array,item);
}
for (i=0; i<sizeof(btc38_cnypairs)/sizeof(*btc38_cnypairs); i++)
{
item = cJSON_CreateArray();
jaddistr(item,uppercase_str(str,btc38_cnypairs[i]));
jaddistr(item,"CNY");
jaddi(array,item);
}
json = cJSON_CreateObject();
jadd(json,"result",array);
return(jprint(json,1));
}
int32_t SUPPORTS(struct exchange_info *exchange,char *_base,char *_rel,cJSON *argjson)
{
int32_t i; char base[64],rel[64];
strcpy(base,_base), strcpy(rel,_rel);
touppercase(base), touppercase(rel);
if ( strlen(base) > 5 || strlen(rel) > 5 )
return(0);
if ( strcmp(base,"BTC") == 0 && strcmp(rel,"CNY") == 0 )
return(1);
else if ( strcmp(base,"CNY") == 0 && strcmp(rel,"BTC") == 0 )
return(-1);
else if ( strcmp(base,"BTC") == 0 )
{
for (i=0; i<sizeof(btc38_btcpairs)/sizeof(*btc38_btcpairs); i++)
if ( strcmp(btc38_btcpairs[i],rel) == 0 )
return(-1);
}
else if ( strcmp(rel,"BTC") == 0 )
{
for (i=0; i<sizeof(btc38_btcpairs)/sizeof(*btc38_btcpairs); i++)
if ( strcmp(btc38_btcpairs[i],base) == 0 )
return(1);
}
else if ( strcmp(base,"CNY") == 0 )
{
for (i=0; i<sizeof(btc38_cnypairs)/sizeof(*btc38_cnypairs); i++)
if ( strcmp(btc38_cnypairs[i],rel) == 0 )
return(-1);
}
else if ( strcmp(rel,"CNY") == 0 )
{
for (i=0; i<sizeof(btc38_cnypairs)/sizeof(*btc38_cnypairs); i++)
if ( strcmp(btc38_cnypairs[i],base) == 0 )
return(1);
}
//printf("BTC38 doesnt support (%s/%s)\n",base,rel);
return(0);
}
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert)
{
char url[1024],lrel[16],lbase[16];
strcpy(lrel,rel), strcpy(lbase,base);
tolowercase(lrel), tolowercase(lbase);
if ( strcmp(lbase,"cny") == 0 && strcmp(lrel,"btc") == 0 )
sprintf(url,"http://api.btc38.com/v1/depth.php?c=%s&mk_type=%s","btc","cny");
else sprintf(url,"http://api.btc38.com/v1/depth.php?c=%s&mk_type=%s",lbase,lrel);
return(exchanges777_standardprices(exchange,commission,base,rel,url,quotes,0,0,maxdepth,0,invert));
}
cJSON *SIGNPOST(void **cHandlep,int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *payload,char *path)
{
char cmdbuf[2048],url[1024],buf[1024],hdr1[512],hdr2[512],hdr3[512],hdr4[512],digest[33],*data;
cJSON *json; uint64_t nonce;
hdr1[0] = hdr2[0] = hdr3[0] = hdr4[0] = 0;
json = 0;
nonce = exchange_nonce(exchange);
sprintf(buf,"%s_%s_%s_%llu",exchange->apikey,exchange->userid,exchange->apisecret,(long long)nonce);
//printf("MD5.(%s)\n",buf);
calc_md5(digest,buf,(int32_t)strlen(buf));
sprintf(cmdbuf,"key=%s&time=%llu&md5=%s%s",exchange->apikey,(long long)nonce,digest,payload);
sprintf(url,"%s/%s",EXCHANGE_AUTHURL,path);
if ( dotrade == 0 )
data = exchange_would_submit(payload,hdr1,hdr2,hdr3,hdr4);
else if ( (data= curl_post(&exchange->cHandle,url,0,cmdbuf,hdr1,hdr2,hdr3,hdr4)) != 0 )
json = cJSON_Parse(data);
if ( retstrp != 0 )
*retstrp = data;
else if ( data != 0 )
free(data);
return(json);
}
/* $ Stamp = $ date-> getTimestamp ();
type, 1 for the purchase of Entry, 2 entry order to sell, can not be empty / the type of the order
$ Mdt = "_ public here to write here write here to write user ID_ private _" $ stamp.;
$ Mdt = md5 ($ mdt);
$ Data = array ("key" => "here to write public", "time" => $ stamp, "md5" => $ mdt, "type" => 1, "mk_type" => "cny",
"Price" => "0.0001", "amount" => "100", "coinname" => "XRP");
// $ Data_string = json_encode ($ data);
$ Ch = curl_init ();
curl_setopt ($ ch, CURLOPT_URL, 'http://www.btc38.com/trade/t_api/submitOrder.php');
curl_setopt ($ ch, CURLOPT_POST, 1);
curl_setopt ($ ch, CURLOPT_POSTFIELDS, $ data);
curl_setopt ($ ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ ch, CURLOPT_HEADER, 0); */
/*
static CURL *cHandle;
char *data,*path,url[1024],cmdbuf[8192],buf[512],digest[33],market[16],base[64],rel[64],coinname[16],fmtstr[512],*pricefmt,*volfmt = "%.3f";
cJSON *json,*resultobj; uint64_t nonce,txid = 0;
if ( _base != 0 && _rel != 0 )
{
strcpy(base,_base), strcpy(rel,_rel);
touppercase(base), touppercase(rel);
if ( btc38_supports(base,rel) == 0 )
{
*retstrp = clonestr("{\"error\":\"invalid contract pair\"}");
return(0);
}
}
nonce = exchange_nonce(exchange);
sprintf(buf,"%s_%s_%s_%llu",exchange->apikey,exchange->userid,exchange->apisecret,(long long)nonce);
//printf("MD5.(%s)\n",buf);
calc_md5(digest,buf,(int32_t)strlen(buf));
*retstrp = 0;
if ( dir == 0 )
{
path = "getMyBalance.php";
sprintf(cmdbuf,"key=%s&time=%llu&md5=%s",exchange->apikey,(long long)nonce,digest);
}
else
{
if ( (data= curl_post(&cHandle,url,0,cmdbuf,0,0,0,0)) != 0 )
{
//printf("submit cmd.(%s) [%s]\n",cmdbuf,data);
if ( (json= cJSON_Parse(data)) != 0 )
{
if ( juint(json,"success") > 0 && (resultobj= cJSON_GetObjectItem(json,"return")) != 0 )
{
if ( (txid= get_API_nxt64bits(cJSON_GetObjectItem(resultobj,"order_id"))) == 0 )
{
if ( get_API_nxt64bits(cJSON_GetObjectItem(resultobj,"remains")) == 0 )
txid = _crc32(0,cmdbuf,strlen(cmdbuf));
}
}
free_json(json);
}
} else fprintf(stderr,"submit err cmd.(%s)\n",cmdbuf);
if ( retstrp != 0 && data != 0 )
{
if ( (json= cJSON_Parse(data)) == 0 )
{
json = cJSON_CreateObject();
jaddstr(json,"result",data);
data = jprint(json,1);
} else free_json(json);
//printf("btc38 returning.(%s) in %p\n",data,data);
*retstrp = data;
}
else if ( data != 0 )
free(data);
return(txid);
*/
cJSON *BALANCES(struct exchange_info *exchange,cJSON *argjson)
{
return(SIGNPOST(&exchange->cHandle,1,0,exchange,"","getMyBalance.php"));
}
char *PARSEBALANCE(struct exchange_info *exchange,double *balancep,char *coinstr,cJSON *argjson)
{
char field[128],*str,*itemstr = 0; cJSON *obj; double lockbalance,imma;
*balancep = 0.;
strcpy(field,coinstr);
tolowercase(field);
strcat(field,"_balance");
if ( argjson != 0 && (str= jstr(argjson,field)) != 0 )
{
*balancep = jdouble(argjson,field);
strcpy(field,coinstr), tolowercase(field), strcat(field,"_balance_lock");
lockbalance = jdouble(argjson,field);
strcpy(field,coinstr), tolowercase(field), strcat(field,"_balance_imma");
imma = jdouble(argjson,field);
obj = cJSON_CreateObject();
jaddnum(obj,"balance",*balancep);
jaddnum(obj,"locked_balance",lockbalance);
jaddnum(obj,"imma_balance",imma);
itemstr = jprint(obj,1);
}
if ( itemstr == 0 )
return(clonestr("{\"error\":\"cant find coin balance\"}"));
return(itemstr);
}
#include "checkbalance.c"
uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *base,char *rel,int32_t dir,double price,double volume,cJSON *argjson)
{
char payload[1024],market[16],coinname[16],fmtstr[512],*pricefmt,*extra,*volfmt = "%.3f";
cJSON *json,*resultobj; uint64_t txid = 0;
if ( (extra= *retstrp) != 0 )
*retstrp = 0;
if ( (dir= cny_flip(market,coinname,base,rel,dir,&price,&volume)) == 0 )
{
fprintf(stderr,"btc38_trade illegal base.(%s) or rel.(%s)\n",base,rel);
return(0);
}
if ( strcmp(market,"cny") == 0 )
pricefmt = "%.5f";
else pricefmt = "%.6f";
//sprintf(fmtstr,"key=%%s&time=%%llu&md5=%%s&type=%%s&mk_type=%%s&coinname=%%s&price=%s&amount=%s",pricefmt,volfmt);
//sprintf(payload,fmtstr,exchange->apikey,(long long)nonce,digest,dir>0?"1":"2",market,coinname,price,volume);
sprintf(fmtstr,"&type=%%s&mk_type=%%s&coinname=%%s&price=%s&amount=%s",pricefmt,volfmt);
sprintf(payload,fmtstr,dir>0?"1":"2",market,coinname,price,volume);
if ( CHECKBALANCE(retstrp,dotrade,exchange,dir,base,rel,price,volume,argjson) == 0 && (json= SIGNPOST(&exchange->cHandle,dotrade,retstrp,exchange,payload,"submitOrder.php")) != 0 )
{
if ( juint(json,"success") > 0 && (resultobj= jobj(json,"return")) != 0 )
{
if ( (txid= j64bits(resultobj,"order_id")) == 0 )
{
if ( j64bits(resultobj,"remains") == 0 )
txid = calc_crc32(0,payload,strlen(payload));
}
}
free_json(json);
if ( retstrp != 0 && *retstrp != 0 )
{
if ( (json= cJSON_Parse(*retstrp)) == 0 )
{
json = cJSON_CreateObject();
jaddstr(json,"result",*retstrp);
free(*retstrp);
*retstrp = jprint(json,1);
} else free_json(json);
}
}
return(txid);
}
char *CANCELORDER(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson)
{
char payload[1024],*rel,*retstr = 0; cJSON *json;
if ( (rel= jstr(argjson,"rel")) == 0 )
rel = "cny";
sprintf(payload,"&mk_type=%s&order_id=%llu",rel,(long long)quoteid);
if ( (json= SIGNPOST(&exchange->cHandle,1,&retstr,exchange,payload,"cancelOrder.php")) != 0 )
{
free_json(json);
}
return(retstr); // return standardized cancelorder
}
char *OPENORDERS(struct exchange_info *exchange,cJSON *argjson)
{
char payload[1024],*base,*rel,*retstr = 0; cJSON *json;
if ( (rel= jstr(argjson,"rel")) == 0 )
rel = "cny";
sprintf(payload,"&mk_type=%s",rel);
if ( (base= jstr(argjson,"base")) != 0 )
sprintf(payload + strlen(payload),"&coinname=%s",base);
if ( (json= SIGNPOST(&exchange->cHandle,1,&retstr,exchange,payload,"getOrderList.php")) != 0 )
{
free_json(json);
}
return(retstr); // return standardized open orders
}
char *TRADEHISTORY(struct exchange_info *exchange,cJSON *argjson)
{
return(clonestr("{\"error\":\"btc38 doesnt seem to have trade history api!\"}"));
}
char *WITHDRAW(struct exchange_info *exchange,char *base,double amount,char *destaddr,cJSON *argjson)
{
return(clonestr("{\"error\":\"btc38 doesnt seem to have withdraw api!\"}"));
}
char *ORDERSTATUS(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson)
{
char *status,*retstr;
status = OPENORDERS(exchange,argjson);
if ( (retstr= exchange_extractorderid(0,status,quoteid,"order_id")) != 0 )
{
free(status);
return(retstr);
}
free(status);
return(clonestr("{\"result\":\"order not pending\"}"));
}
struct exchange_funcs btc38_funcs = EXCHANGE_FUNCS(btc38,EXCHANGE_NAME);
#include "exchange_undefs.h"

204
iguana/exchanges/btce.c

@ -0,0 +1,204 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#define EXCHANGE_NAME "btce"
#define UPDATE btce ## _price
#define SUPPORTS btce ## _supports
#define SIGNPOST btce ## _signpost
#define TRADE btce ## _trade
#define ORDERSTATUS btce ## _orderstatus
#define CANCELORDER btce ## _cancelorder
#define OPENORDERS btce ## _openorders
#define TRADEHISTORY btce ## _tradehistory
#define BALANCES btce ## _balances
#define PARSEBALANCE btce ## _parsebalance
#define WITHDRAW btce ## _withdraw
#define EXCHANGE_AUTHURL "https://btc-e.com/tapi"
#define CHECKBALANCE btce ## _checkbalance
#define ALLPAIRS btce ## _allpairs
#define FUNCS btce ## _funcs
#define BASERELS btce ## _baserels
static char *BASERELS[][2] = { {"btc","usd"}, {"btc","rur"}, {"btc","eur"}, {"ltc","btc"}, {"ltc","usd"}, {"ltc","rur"}, {"ltc","eur"}, {"nmc","btc"}, {"nmc","usd"}, {"nvc","btc"}, {"nvc","usd"}, {"eur","usd"}, {"eur","rur"}, {"ppc","btc"}, {"ppc","usd"} };
#include "exchange_supports.h"
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert)
{
char field[64],url[1024],lbase[16],lrel[16];
strcpy(lrel,rel), strcpy(lbase,base);
tolowercase(lrel), tolowercase(lbase);
sprintf(field,"%s_%s",lbase,lrel);
sprintf(url,"https://btc-e.com/api/3/depth/%s",field);
return(exchanges777_standardprices(exchange,commission,base,rel,url,quotes,0,0,maxdepth,field,invert));
}
cJSON *SIGNPOST(void **cHandlep,int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *url,char *payload)
{
char dest[(512>>3)*2+1],hdr1[512],hdr2[512],hdr3[512],hdr4[512],*data,*sig; cJSON *json;
hdr1[0] = hdr2[0] = hdr3[0] = hdr4[0] = 0;
json = 0;
if ( (sig= hmac_sha512_str(dest,exchange->apisecret,(int32_t)strlen(exchange->apisecret),payload)) != 0 )
sprintf(hdr1,"Sign:%s",sig);
else hdr1[0] = 0;
sprintf(hdr2,"Key:%s",exchange->apikey);
if ( dotrade == 0 )
data = exchange_would_submit(payload,hdr1,hdr2,hdr3,hdr4);
else if ( (data= curl_post(&exchange->cHandle,url,0,payload,hdr1,hdr2,hdr3,hdr4)) != 0 )
json = cJSON_Parse(data);
if ( retstrp != 0 )
*retstrp = data;
else if ( data != 0 )
free(data);
return(json);
}
cJSON *BALANCES(struct exchange_info *exchange,cJSON *argjson)
{
char payload[1024];
sprintf(payload,"method=getInfo&nonce=%llu",(long long)exchange_nonce(exchange));
return(SIGNPOST(&exchange->cHandle,1,0,exchange,EXCHANGE_AUTHURL,payload));
}
char *PARSEBALANCE(struct exchange_info *exchange,double *balancep,char *coinstr,cJSON *argjson)
{
//btce.({"success":1,"return":{"funds":{"usd":73.02571846,"btc":0,"ltc":0,"nmc":0,"rur":0,"eur":0,"nvc":0.0000322,"trc":0,"ppc":0.00000002,"ftc":0,"xpm":2.28605349,"cnh":0,"gbp":0},"rights":{"info":1,"trade":1,"withdraw":0},"transaction_count":0,"open_orders":3,"server_time":1441918649}})
char field[128],*itemstr = 0; cJSON *obj,*item;
*balancep = 0.;
strcpy(field,coinstr);
tolowercase(field);
if ( argjson != 0 && (obj= jobj(argjson,"return")) != 0 && (item= jobj(obj,"funds")) != 0 )
{
*balancep = jdouble(item,field);
obj = cJSON_CreateObject();
touppercase(field);
jaddstr(obj,"base",field);
jaddnum(obj,"balance",*balancep);
itemstr = jprint(obj,1);
}
if ( itemstr == 0 )
return(clonestr("{\"error\":\"cant find coin balance\"}"));
return(itemstr);
}
#include "checkbalance.c"
uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *base,char *rel,int32_t dir,double price,double volume,cJSON *argjson)
{
char payload[1024],pairstr[512],*extra; cJSON *json,*resultobj; uint64_t txid = 0;
if ( (extra= *retstrp) != 0 )
*retstrp = 0;
if ( (dir= flipstr_for_exchange(exchange,pairstr,"%s_%s",dir,&price,&volume,base,rel,argjson)) == 0 )
{
printf("cant find baserel (%s/%s)\n",base,rel);
return(0);
}
sprintf(payload,"method=Trade&nonce=%llu&pair=%s&type=%s&rate=%.3f&amount=%.6f",(long long)exchange_nonce(exchange),pairstr,dir>0?"buy":"sell",price,volume);
if ( CHECKBALANCE(retstrp,dotrade,exchange,dir,base,rel,price,volume,argjson) == 0 && (json= SIGNPOST(&exchange->cHandle,dotrade,retstrp,exchange,EXCHANGE_AUTHURL,payload)) != 0 )
{
//{ "success":1, "return":{ "received":0.1, "remains":0, "order_id":0, "funds":{ "usd":325, "btc":2.498, } } }
if ( juint(json,"success") > 0 && (resultobj= jobj(json,"return")) != 0 )
{
if ( (txid= j64bits(resultobj,"order_id")) == 0 )
{
if ( j64bits(resultobj,"remains") == 0 )
txid = calc_crc32(0,payload,strlen(payload));
}
}
free_json(json);
}
return(txid);
}
char *ORDERSTATUS(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson)
{
char payload[1024],*retstr = 0; cJSON *json;
sprintf(payload,"method=OrderInfo&nonce=%llu&order_id=%llu",(long long)exchange_nonce(exchange),(long long)quoteid);
if ( (json= SIGNPOST(&exchange->cHandle,1,&retstr,exchange,EXCHANGE_AUTHURL,payload)) != 0 )
{
free_json(json);
}
return(retstr); // return standardized orderstatus
}
char *CANCELORDER(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson)
{
char payload[1024],*retstr = 0; cJSON *json;
sprintf(payload,"method=CancelOrder&nonce=%llu&order_id=%llu",(long long)exchange_nonce(exchange),(long long)quoteid);
if ( (json= SIGNPOST(&exchange->cHandle,1,&retstr,exchange,EXCHANGE_AUTHURL,payload)) != 0 )
{
free_json(json);
}
return(retstr); // return standardized cancelorder
}
char *OPENORDERS(struct exchange_info *exchange,cJSON *argjson)
{
char payload[1024],market[64],*base,*rel,*retstr = 0; cJSON *json;
sprintf(payload,"method=ActiveOrders&nonce=%llu",(long long)exchange_nonce(exchange));
if ( (base= jstr(argjson,"base")) != 0 && (rel= jstr(argjson,"rel")) != 0 )
{
sprintf(market,"%s_%s",base,rel);
tolowercase(market);
sprintf(payload + strlen(payload),"&pair=%s",market);
}
if ( (json= SIGNPOST(&exchange->cHandle,1,&retstr,exchange,EXCHANGE_AUTHURL,payload)) != 0 )
{
free_json(json);
}
return(retstr); // return standardized open orders
}
char *TRADEHISTORY(struct exchange_info *exchange,cJSON *argjson)
{
char payload[1024],market[64],*base,*rel,*retstr = 0; cJSON *json; uint32_t starttime,endtime;
sprintf(payload,"method=TradeHistory&nonce=%llu",(long long)exchange_nonce(exchange));
if ( (starttime= juint(argjson,"start")) != 0 )
sprintf(payload + strlen(payload),"&since=%u",starttime);
if ( (endtime= juint(argjson,"end")) != 0 )
sprintf(payload + strlen(payload),"&end=%u",endtime);
if ( (base= jstr(argjson,"base")) != 0 && (rel= jstr(argjson,"rel")) != 0 )
{
sprintf(market,"%s_%s",base,rel);
tolowercase(market);
sprintf(payload + strlen(payload),"&pair=%s",market);
}
if ( (json= SIGNPOST(&exchange->cHandle,1,&retstr,exchange,EXCHANGE_AUTHURL,payload)) != 0 )
{
free_json(json);
}
return(retstr); // return standardized tradehistory
}
char *WITHDRAW(struct exchange_info *exchange,char *base,double amount,char *destaddr,cJSON *argjson)
{
char payload[1024],*retstr = 0; cJSON *json;
if ( base == 0 || base[0] == 0 )
return(clonestr("{\"error\":\"base not specified\"}"));
if ( destaddr == 0 || destaddr[0] == 0 )
return(clonestr("{\"error\":\"destaddr not specified\"}"));
if ( amount < SMALLVAL )
return(clonestr("{\"error\":\"amount not specified\"}"));
sprintf(payload,"method=WithdrawCoin&nonce=%llu&coinName=%s&amount=%.6f&address=%s",(long long)exchange_nonce(exchange),base,amount,destaddr);
if ( (json= SIGNPOST(&exchange->cHandle,1,&retstr,exchange,EXCHANGE_AUTHURL,payload)) != 0 )
{
free_json(json);
}
return(retstr); // return standardized withdraw
}
struct exchange_funcs btce_funcs = EXCHANGE_FUNCS(btce,EXCHANGE_NAME);
#include "exchange_undefs.h"

53
iguana/exchanges/checkbalance.c

@ -0,0 +1,53 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
int32_t CHECKBALANCE(char **retstrp,int32_t skipflag,struct exchange_info *exchange,int32_t dir,char *base,char *rel,double price,double volume,cJSON *argjson)
{
cJSON *json; char *coinstr,*balancestr,*resultstr,*resultval; double balance; int32_t retval = -1;
if ( skipflag == 0 )
{
coinstr = (dir > 0) ? rel : base;
if ( (balancestr= PARSEBALANCE(exchange,&balance,coinstr,argjson)) != 0 )
{
json = cJSON_Parse(balancestr);
free(balancestr);
printf("%s balance.%s %f vs %f\n",exchange->name,coinstr,balance,dir > 0 ? volume : volume * price);
if ( (dir > 0 && balance < volume) || (dir < 0 && balance < (volume * price)) )
{
resultstr = "error";
resultval = "not enough balance";
}
else
{
resultval = "balance";
resultstr = "success";
retval = 0;
}
if ( retstrp != 0 )
{
if ( json == 0 )
json = cJSON_CreateObject();
jaddstr(json,"coin",coinstr);
jaddnum(json,"balance",balance);
jaddnum(json,"required",volume * (dir < 0 ? price : 1.));
jaddstr(json,resultstr,resultval);
*retstrp = jprint(json,1);
}
else if ( json != 0 )
free_json(json);
}
} else retval = 0;
return(retval);
}

216
iguana/exchanges/coinbase.c

@ -0,0 +1,216 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#define EXCHANGE_NAME "coinbase"
#define UPDATE coinbase ## _price
#define SUPPORTS coinbase ## _supports
#define SIGNPOST coinbase ## _signpost
#define TRADE coinbase ## _trade
#define ORDERSTATUS coinbase ## _orderstatus
#define CANCELORDER coinbase ## _cancelorder
#define OPENORDERS coinbase ## _openorders
#define TRADEHISTORY coinbase ## _tradehistory
#define BALANCES coinbase ## _balances
#define PARSEBALANCE coinbase ## _parsebalance
#define WITHDRAW coinbase ## _withdraw
#define EXCHANGE_AUTHURL "https://api.exchange.coinbase.com"
#define CHECKBALANCE coinbase ## _checkbalance
#define ALLPAIRS coinbase ## _allpairs
#define FUNCS coinbase ## _funcs
#define BASERELS coinbase ## _baserels
static char *BASERELS[][2] = { {"btc","usd"} };
#include "exchange_supports.h"
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert)
{
char url[1024];
sprintf(url,"https://api.exchange.coinbase.com/products/%s-%s/book?level=2",base,rel);
return(exchanges777_standardprices(exchange,commission,base,rel,url,quotes,0,0,maxdepth,0,invert));
}
cJSON *SIGNPOST(void **cHandlep,int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *payload,uint64_t nonce,char *path,char *method)
{
/*All REST requests must contain the following headers:
CB-ACCESS-KEY The api key as a string.
CB-ACCESS-SIGN The base64-encoded signature (see Signing a Message).
CB-ACCESS-TIMESTAMP A timestamp for your request.
CB-ACCESS-PASSPHRASE The passphrase you specified when creating the API key.
All request bodies should have content type application/json and be valid JSON.
Signing a Message
The CB-ACCESS-SIGN header is generated by creating a sha256 HMAC using the base64-decoded
secret key on the prehash string timestamp + method + requestPath + body (where + represents string concatenation)
and base64-encode the output. The timestamp value is the same as the CB-ACCESS-TIMESTAMP header.
The body is the request body string or omitted if there is no request body (typically for GET requests).
The method should be UPPER CASE
Remember to first base64-decode the alphanumeric secret string (resulting in 64 bytes) before using it as the key for HMAC. Also, base64-encode the digest output before sending in the header.
*/
/* def __call__(self, request):
timestamp = str(time.time())
message = timestamp + request.method + request.path_url + (request.body or '')
hmac_key = base64.b64decode(self.secret_key)
signature = hmac.new(hmac_key, message, hashlib.sha256)
signature_b64 = signature.digest().encode('base64').rstrip('\n')
request.headers.update({
'CB-ACCESS-SIGN': signature_b64,
'CB-ACCESS-TIMESTAMP': timestamp,
'CB-ACCESS-KEY': self.api_key,
'CB-ACCESS-PASSPHRASE': self.passphrase,
'Content-Type': 'application/json'
})*/
char url[1024],hdr1[512],hdr2[512],hdr3[512],hdr4[512],dest[1024]; cJSON *json; int32_t n;
char prehash64[512],prehash[512],decodedsecret[512],sig64[512],*sig,*data = 0;
hdr1[0] = hdr2[0] = hdr3[0] = hdr4[0] = 0;
json = 0;
n = nn_base64_decode((void *)exchange->apisecret,strlen(exchange->apisecret),(void *)decodedsecret,sizeof(decodedsecret));
sprintf(prehash,"%llu%s/%s%s",(long long)nonce,method,path,payload);
nn_base64_encode((void *)prehash,strlen(prehash),prehash64,sizeof(prehash64));
if ( (sig= hmac_sha256_str(dest,decodedsecret,n,prehash64)) != 0 )
{
nn_base64_encode((void *)sig,strlen(sig),sig64,sizeof(sig64));
//CB-ACCESS-KEY The api key as a string.
//CB-ACCESS-SIGN The base64-encoded signature (see Signing a Message).
//CB-ACCESS-TIMESTAMP A timestamp for your request.
//CB-ACCESS-PASSPHRASE The passphrase you specified when creating the API key.
sprintf(hdr1,"CB-ACCESS-KEY:%s",exchange->apikey);
sprintf(hdr2,"CB-ACCESS-SIGN:%s",sig64);
sprintf(hdr3,"CB-ACCESS-TIMESTAMP:%llu",(long long)nonce);
//sprintf(hdr4,"CB-ACCESS-PASSPHRASE:%s; content-type:application/json; charset=utf-8",exchange->userid);
sprintf(hdr4,"CB-ACCESS-PASSPHRASE:%s",exchange->userid);
sprintf(url,"%s/%s",EXCHANGE_AUTHURL,path);
if ( dotrade == 0 )
data = exchange_would_submit(payload,hdr1,hdr2,hdr3,hdr4);
else if ( (data= curl_post(&exchange->cHandle,url,0,payload,hdr1,hdr2,hdr3,hdr4)) != 0 )
json = cJSON_Parse(data);
}
if ( retstrp != 0 )
*retstrp = data;
else if ( data != 0 )
free(data);
return(json);
}
cJSON *BALANCES(struct exchange_info *exchange,cJSON *argjson)
{
return(SIGNPOST(&exchange->cHandle,1,0,exchange,"",exchange_nonce(exchange),"accounts","GET"));
}
char *PARSEBALANCE(struct exchange_info *exchange,double *balancep,char *coinstr,cJSON *argjson)
{
char field[128],*itemstr = 0; cJSON *obj,*item;
*balancep = 0.;
strcpy(field,coinstr);
tolowercase(field);
if ( argjson != 0 && (obj= jobj(argjson,"return")) != 0 && (item= jobj(obj,"funds")) != 0 )
{
*balancep = jdouble(item,field);
obj = cJSON_CreateObject();
touppercase(field);
jaddstr(obj,"base",field);
jaddnum(obj,"balance",*balancep);
itemstr = jprint(obj,1);
}
if ( itemstr == 0 )
return(clonestr("{\"error\":\"cant find coin balance\"}"));
return(itemstr);
}
#include "checkbalance.c"
uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *base,char *rel,int32_t dir,double price,double volume,cJSON *argjson)
{
char payload[1024],pairstr[512],method[32],*path,*extra;
cJSON *json; uint64_t nonce,txid = 0;
if ( (extra= *retstrp) != 0 )
*retstrp = 0;
path = "trade", strcpy(method,"POST");
if ( (dir= flip_for_exchange(pairstr,"%s_%s","BTC",dir,&price,&volume,base,rel)) == 0 )
{
printf("cant find baserel (%s/%s)\n",base,rel);
return(0);
}
nonce = exchange_nonce(exchange);
sprintf(payload,"method=Trade&nonce=%llu&pair=%s&type=%s&rate=%.6f&amount=%.6f",(long long)nonce,pairstr,dir>0?"buy":"sell",price,volume);
if ( CHECKBALANCE(retstrp,dotrade,exchange,dir,base,rel,price,volume,argjson) == 0 && (json= SIGNPOST(&exchange->cHandle,dotrade,retstrp,exchange,payload,nonce,path,method)) != 0 )
{
// parse json and set txid
free_json(json);
}
return(txid);
}
char *ORDERSTATUS(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson)
{
char payload[1024],*retstr = 0; cJSON *json;
// generate payload
if ( (json= SIGNPOST(&exchange->cHandle,1,0,exchange,payload,exchange_nonce(exchange),"accounts","GET")) != 0 )
{
free_json(json);
}
return(retstr); // return standardized orderstatus
}
char *CANCELORDER(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson)
{
char payload[1024],*retstr = 0; cJSON *json;
// generate payload
if ( (json= SIGNPOST(&exchange->cHandle,1,0,exchange,payload,exchange_nonce(exchange),"accounts","GET")) != 0 )
{
free_json(json);
}
return(retstr); // return standardized cancelorder
}
char *OPENORDERS(struct exchange_info *exchange,cJSON *argjson)
{
char payload[1024],*retstr = 0; cJSON *json;
// generate payload
if ( (json= SIGNPOST(&exchange->cHandle,1,0,exchange,payload,exchange_nonce(exchange),"accounts","GET")) != 0 )
{
free_json(json);
}
return(retstr); // return standardized open orders
}
char *TRADEHISTORY(struct exchange_info *exchange,cJSON *argjson)
{
char payload[1024],*retstr = 0; cJSON *json;
// generate payload
if ( (json= SIGNPOST(&exchange->cHandle,1,0,exchange,payload,exchange_nonce(exchange),"accounts","GET")) != 0 )
{
free_json(json);
}
return(retstr); // return standardized tradehistory
}
char *WITHDRAW(struct exchange_info *exchange,char *base,double amount,char *destaddr,cJSON *argjson)
{
char payload[1024],*retstr = 0; cJSON *json;
// generate payload
if ( (json= SIGNPOST(&exchange->cHandle,1,0,exchange,payload,exchange_nonce(exchange),"accounts","GET")) != 0 )
{
free_json(json);
}
return(retstr); // return standardized withdraw
}
struct exchange_funcs coinbase_funcs = EXCHANGE_FUNCS(coinbase,EXCHANGE_NAME);
#include "exchange_undefs.h"

25
iguana/exchanges/exchange_supports.h

@ -0,0 +1,25 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
char *ALLPAIRS(struct exchange_info *exchange,cJSON *argjson)
{
return(jprint(exchanges777_allpairs(BASERELS,(int32_t)(sizeof(BASERELS)/sizeof(*BASERELS))),1));
}
int32_t SUPPORTS(struct exchange_info *exchange,char *base,char *rel,cJSON *argjson)
{
return(baserel_polarity(BASERELS,(int32_t)(sizeof(BASERELS)/sizeof(*BASERELS)),base,rel));
}

32
iguana/exchanges/exchange_undefs.h

@ -0,0 +1,32 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#undef UPDATE
#undef SUPPORTS
#undef SIGNPOST
#undef TRADE
#undef ORDERSTATUS
#undef CANCELORDER
#undef OPENORDERS
#undef TRADEHISTORY
#undef BALANCES
#undef PARSEBALANCE
#undef WITHDRAW
#undef EXCHANGE_NAME
#undef CHECKBALANCE
#undef ALLPAIRS
#undef FUNCS
#undef BASERELS
#undef EXCHANGE_AUTHURL

319
iguana/exchanges/fxcm.c

@ -0,0 +1,319 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#define EXCHANGE_NAME "fxcm"
#define UPDATE fxcm ## _price
#define SUPPORTS fxcm ## _supports
#define SIGNPOST fxcm ## _signpost
#define TRADE fxcm ## _trade
#define ORDERSTATUS fxcm ## _orderstatus
#define CANCELORDER fxcm ## _cancelorder
#define OPENORDERS fxcm ## _openorders
#define TRADEHISTORY fxcm ## _tradehistory
#define BALANCES fxcm ## _balances
#define PARSEBALANCE fxcm ## _parsebalance
#define WITHDRAW fxcm ## _withdraw
#define CHECKBALANCE fxcm ## _checkbalance
#define ALLPAIRS fxcm ## _allpairs
#define FUNCS fxcm ## _funcs
#define BASERELS fxcm ## _baserels
static char **FXCM_contracts; static int num_FXCM;
char *fxcm_xmlstr()
{
char *xmlstr; int32_t i,j,k;
if ( (xmlstr= issue_curl("http://rates.fxcm.com/RatesXML")) != 0 )
{
_stripwhite(xmlstr,0);
//printf("(%s)\n",xmlstr);
i = 0;
if ( strncmp("<?xml",xmlstr,5) == 0 )
for (; xmlstr[i]!='>'&&xmlstr[i]!=0; i++)
;
if ( xmlstr[i] == '>' )
i++;
for (j=0; xmlstr[i]!=0; i++)
{
if ( strncmp("<Rates>",&xmlstr[i],strlen("<Rates>")) == 0 )
xmlstr[j++] = '[', i += strlen("<Rates>")-1;
else if ( strncmp("<RateSymbol=",&xmlstr[i],strlen("<RateSymbol=")) == 0 )
{
if ( j > 1 )
xmlstr[j++] = ',';
memcpy(&xmlstr[j],"{\"Symbol\":",strlen("{\"Symbol\":")), i += strlen("<RateSymbol=")-1, j += strlen("{\"Symbol\":");
}
else
{
char *strpairs[][2] = { { "<Bid>", "\"Bid\":" }, { "<Ask>", "\"Ask\":" }, { "<High>", "\"High\":" }, { "<Low>", "\"Low\":" }, { "<Direction>", "\"Direction\":" }, { "<Last>", "\"Last\":\"" } };
for (k=0; k<sizeof(strpairs)/sizeof(*strpairs); k++)
if ( strncmp(strpairs[k][0],&xmlstr[i],strlen(strpairs[k][0])) == 0 )
{
memcpy(&xmlstr[j],strpairs[k][1],strlen(strpairs[k][1]));
i += strlen(strpairs[k][0])-1;
j += strlen(strpairs[k][1]);
break;
}
if ( k == sizeof(strpairs)/sizeof(*strpairs) )
{
char *ends[] = { "</Bid>", "</Ask>", "</High>", "</Low>", "</Direction>", "</Last>", "</Rate>", "</Rates>", ">" };
for (k=0; k<sizeof(ends)/sizeof(*ends); k++)
if ( strncmp(ends[k],&xmlstr[i],strlen(ends[k])) == 0 )
{
i += strlen(ends[k])-1;
if ( strcmp("</Rate>",ends[k]) == 0 )
xmlstr[j++] = '}';
else if ( strcmp("</Rates>",ends[k]) == 0 )
xmlstr[j++] = ']';
else if ( strcmp("</Last>",ends[k]) == 0 )
xmlstr[j++] = '\"';
else xmlstr[j++] = ',';
break;
}
if ( k == sizeof(ends)/sizeof(*ends) )
xmlstr[j++] = xmlstr[i];
}
}
}
xmlstr[j] = 0;
}
return(xmlstr);
}
int32_t fxcm_setcontracts()
{
int32_t i,n,flag,num = 0; cJSON *json,*obj; char name[32],*str,*xmlstr = fxcm_xmlstr();
if ( xmlstr != 0 )
{
if ( (json= cJSON_Parse(xmlstr)) != 0 )
{
/*<Rate Symbol="USDJPY">
<Bid>123.763</Bid>
<Ask>123.786</Ask>
<High>123.956</High>
<Low>123.562</Low>
<Direction>-1</Direction>
<Last>08:49:15</Last>*/
//printf("Parsed stupid XML! (%s)\n",xmlstr);
if ( is_cJSON_Array(json) != 0 && (n= cJSON_GetArraySize(json)) != 0 )
{
if ( FXCM_contracts != 0 )
{
for (i=0; i<num_FXCM; i++)
{
if ( FXCM_contracts[i] == 0 )
break;
free(FXCM_contracts[i]);
}
free(FXCM_contracts);
}
FXCM_contracts = calloc(n+1,sizeof(*FXCM_contracts));
for (i=0; i<n; i++)
{
obj = jitem(json,i);
flag = 0;
if ( (str= jstr(obj,"Symbol")) != 0 && strlen(str) < 15 )
{
strcpy(name,str);
touppercase(name);
if ( strcmp(name,"USDCNH") == 0 )
strcpy(name,"USDCNY");
FXCM_contracts[num++] = clonestr(name);
}
}
}
}
free(xmlstr);
}
return(num);
}
int32_t fxcm_ensure()
{
if ( num_FXCM == 0 || FXCM_contracts == 0 )
num_FXCM = fxcm_setcontracts();
if ( FXCM_contracts == 0 )
return(-1);
else return(0);
}
char *ALLPAIRS(struct exchange_info *exchange,cJSON *argjson)
{
int32_t i,c,n; char base[32],rel[32]; cJSON *json,*item,*array = cJSON_CreateArray();
if ( fxcm_ensure() == 0 )
{
for (i=0; i<num_FXCM; i++)
{
if ( strcmp("COPPER",FXCM_contracts[i]) != 0 && (n= (int32_t)strlen(FXCM_contracts[i])) == 6 && ((c= FXCM_contracts[i][n-1]) < '0' || c > '9') )
{
strcpy(base,FXCM_contracts[i]);
strcpy(rel,FXCM_contracts[i] + 3);
base[3] = rel[3] = 0;
touppercase(base), touppercase(rel);
}
else if ( strcmp(FXCM_contracts[i],"USDOLLAR") == 0 || strcmp(FXCM_contracts[i],"BUND") == 0 || ((c= FXCM_contracts[i][n-1]) >= '0' && c <= '9') )
{
strcpy(base,FXCM_contracts[i]), touppercase(base);
rel[0] = 0;
}
else
{
strcpy(base,FXCM_contracts[i]), touppercase(base);
strcpy(rel,"USD");
}
item = cJSON_CreateArray();
jaddistr(item,base);
jaddistr(item,rel);
jaddi(array,item);
}
json = cJSON_CreateObject();
jadd(json,"result",array);
return(jprint(json,1));
} else return(clonestr("{\"error\":\"cant find FXCM contracts\"}"));
}
int32_t SUPPORTS(struct exchange_info *exchange,char *_base,char *_rel,cJSON *argjson)
{
int32_t i; char contract[32],revcontract[32],base[32],rel[32];
if ( fxcm_ensure() == 0 && num_FXCM > 0 && FXCM_contracts != 0 )
{
strcpy(base,_base), strcpy(rel,_rel);
touppercase(base), touppercase(rel);
sprintf(contract,"%s%s",base,rel), touppercase(contract);
sprintf(revcontract,"%s%s",rel,base), touppercase(revcontract);
for (i=0; i<num_FXCM; i++)
{
if ( strcmp(contract,FXCM_contracts[i]) == 0 )
return(1);
else if ( strcmp(revcontract,FXCM_contracts[i]) == 0 )
return(-1);
}
}
return(0);
}
void prices777_fxcm(double bids[64],double asks[64],double highs[64],double lows[64])
{
char name[64],*str,*xmlstr; cJSON *json,*obj; int32_t i,c,flag,n = 0; double bid,ask,high,low; struct destbuf numstr;
memset(bids,0,sizeof(*bids) * 64), memset(asks,0,sizeof(*asks) * 64);
memset(highs,0,sizeof(*highs) * 64), memset(lows,0,sizeof(*lows) * 64);
if ( fxcm_ensure() < 0 )
return;
if ( (xmlstr= fxcm_xmlstr()) != 0 )
{
if ( (json= cJSON_Parse(xmlstr)) != 0 )
{
if ( is_cJSON_Array(json) != 0 && (n= cJSON_GetArraySize(json)) != 0 )
{
for (i=0; i<n; i++)
{
obj = jitem(json,i);
flag = 0;
c = -1;
if ( (str= jstr(obj,"Symbol")) != 0 && strlen(str) < 15 )
{
strcpy(name,str);
if ( strcmp(name,"USDCNH") == 0 )
strcpy(name,"USDCNY");
copy_cJSON(&numstr,jobj(obj,"Bid")), bid = atof(numstr.buf);
copy_cJSON(&numstr,jobj(obj,"Ask")), ask = atof(numstr.buf);
copy_cJSON(&numstr,jobj(obj,"High")), high = atof(numstr.buf);
copy_cJSON(&numstr,jobj(obj,"Low")), low = atof(numstr.buf);
if ( (c= strsearch(FXCM_contracts,num_FXCM,name)) >= 0 )
{
bids[c] = bid, asks[c] = ask, highs[c] = high, lows[c] = low;
//printf("c.%d (%s) %f %f\n",c,name,bid,ask);
flag = 1;
} else printf("cant find.%s\n",name);//, getchar();
}
if ( flag == 0 )
printf("FXCM: Error finding.(%s) c.%d (%s)\n",name,c,cJSON_Print(obj));
}
}
free_json(json);
} else printf("couldnt parse.(%s)\n",xmlstr);
free(xmlstr);
}
}
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *bidasks,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert)
{
double bid,ask,bids[64],asks[64],highs[64],lows[64]; int32_t numbids,numasks,c; char name[32];
if ( fxcm_ensure() == 0 )
{
strcpy(name,base), strcat(name,rel), touppercase(name);
if ( (c= strsearch(FXCM_contracts,num_FXCM,name)) >= 0 )
{
prices777_fxcm(bids,asks,highs,lows);
numbids = numasks = 0;
bid = exchange_setquote(bidasks,&numbids,&numasks,0,invert,bids[c],1,commission,0,(uint32_t)time(NULL),0);
ask = exchange_setquote(bidasks,&numbids,&numasks,1,invert,asks[c],1,commission,0,(uint32_t)time(NULL),0);
if ( bid > SMALLVAL && ask > SMALLVAL )
return((bid + ask) * .5);
}
}
return(0);
}
cJSON *SIGNPOST(void **cHandlep,int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *payload,char *path)
{
if ( retstrp != 0 )
*retstrp = clonestr("{\"error\":\"fxcm is readonly data source\"}");
return(cJSON_Parse("{}"));
}
char *PARSEBALANCE(struct exchange_info *exchange,double *balancep,char *coinstr,cJSON *argjson)
{
return(clonestr("{\"error\":\"fxcm is readonly data source\"}"));
}
cJSON *BALANCES(struct exchange_info *exchange,cJSON *argjson)
{
return(cJSON_Parse("{\"error\":\"fxcm is readonly data source\"}"));
}
uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *base,char *rel,int32_t dir,double price,double volume,cJSON *argjson)
{
return(0);
}
char *ORDERSTATUS(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson)
{
return(clonestr("{\"error\":\"fxcm is readonly data source\"}"));
}
char *CANCELORDER(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson)
{
return(clonestr("{\"error\":\"fxcm is readonly data source\"}"));
}
char *OPENORDERS(struct exchange_info *exchange,cJSON *argjson)
{
return(clonestr("{\"error\":\"fxcm is readonly data source\"}"));
}
char *TRADEHISTORY(struct exchange_info *exchange,cJSON *argjson)
{
return(clonestr("{\"error\":\"fxcm is readonly data source\"}"));
}
char *WITHDRAW(struct exchange_info *exchange,char *base,double amount,char *destaddr,cJSON *argjson)
{
return(clonestr("{\"error\":\"fxcm is readonly data source\"}"));
}
struct exchange_funcs fxcm_funcs = EXCHANGE_FUNCS(fxcm,EXCHANGE_NAME);
#include "exchange_undefs.h"

171
iguana/exchanges/huobi.c

@ -0,0 +1,171 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#define EXCHANGE_NAME "huobi"
#define UPDATE huobi ## _price
#define SUPPORTS huobi ## _supports
#define SIGNPOST huobi ## _signpost
#define TRADE huobi ## _trade
#define ORDERSTATUS huobi ## _orderstatus
#define CANCELORDER huobi ## _cancelorder
#define OPENORDERS huobi ## _openorders
#define TRADEHISTORY huobi ## _tradehistory
#define BALANCES huobi ## _balances
#define PARSEBALANCE huobi ## _parsebalance
#define WITHDRAW huobi ## _withdraw
#define CHECKBALANCE huobi ## _checkbalance
#define ALLPAIRS huobi ## _allpairs
#define FUNCS huobi ## _funcs
#define BASERELS huobi ## _baserels
static char *BASERELS[][2] = { {"btc","cny"}, {"ltc","cny"} };
#include "exchange_supports.h"
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert)
{
char url[1024],lbase[16];
strcpy(lbase,base), tolowercase(lbase);
sprintf(url,"http://api.huobi.com/staticmarket/depth_%s_json.js ",lbase);
return(exchanges777_standardprices(exchange,commission,base,rel,url,quotes,0,0,maxdepth,0,invert));
}
cJSON *SIGNPOST(void **cHandlep,int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *payload)
{
char *data; cJSON *json;
json = 0;
//if ( (data= curl_post(&cHandle,"https://api.huobi.com/apiv3",0,payload,"Content-Type:application/x-www-form-urlencoded",0,0,0)) != 0 )
if ( dotrade == 0 )
data = exchange_would_submit(payload,"","","","");
else if ( (data= curl_post(&exchange->cHandle,"https://api.huobi.com/apiv3",0,payload,"",0,0,0)) != 0 )
json = cJSON_Parse(data);
if ( retstrp != 0 )
*retstrp = data;
else if ( data != 0 )
free(data);
return(json);
}
cJSON *huobi_issue_auth(void **cHandlep,struct exchange_info *exchange,char *method,char *buf)
{
char payload[1024],digest[33],tmp[1024]; uint64_t nonce;
nonce = exchange_nonce(exchange);
sprintf(tmp,"access_key=%s&created=%llu&method=%s%s",exchange->apikey,(long long)nonce,method,buf);
sprintf(payload,"%s&secret_key=%s",tmp,exchange->apisecret);
//printf("tmp.(%s) payload.(%s)\n",tmp,payload);
calc_md5(digest,payload,(int32_t)strlen(payload));
sprintf(payload,"%s&sign=%s",tmp,digest);
//printf("-> (%s)\n",payload);
return(SIGNPOST(&exchange->cHandle,1,0,exchange,payload));
}
char *PARSEBALANCE(struct exchange_info *exchange,double *balancep,char *coinstr,cJSON *argjson)
{
char field[128],*itemstr = 0; cJSON *obj,*item;
*balancep = 0.;
strcpy(field,coinstr);
tolowercase(field);
if ( argjson != 0 && (obj= jobj(argjson,"return")) != 0 && (item= jobj(obj,"funds")) != 0 )
{
*balancep = jdouble(item,field);
obj = cJSON_CreateObject();
touppercase(field);
jaddstr(obj,"base",field);
jaddnum(obj,"balance",*balancep);
itemstr = jprint(obj,1);
}
if ( itemstr == 0 )
return(clonestr("{\"error\":\"cant find coin balance\"}"));
return(itemstr);
}
cJSON *BALANCES(struct exchange_info *exchange,cJSON *argjson)
{
return(huobi_issue_auth(&exchange->cHandle,exchange,"get_account_info",""));
}
#include "checkbalance.c"
uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *base,char *rel,int32_t dir,double price,double volume,cJSON *argjson)
{
char payload[1024],pairstr[64],pricestr[64],*extra,*method; cJSON *json; int32_t type; uint64_t txid = 0;
if ( (extra= *retstrp) != 0 )
*retstrp = 0;
if ( (dir= flipstr_for_exchange(exchange,pairstr,"%s%s",dir,&price,&volume,base,rel,argjson)) == 0 )
{
printf("cant find baserel (%s/%s)\n",base,rel);
return(0);
}
if ( extra != 0 && strcmp(extra,"market") == 0 )
method = (dir > 0) ? "buy_market" : "sell_market";
else method = (dir > 0) ? "buy" : "sell", sprintf(pricestr,"&price=%.2f",price);
if ( strcmp(pairstr,"btccny") == 0 )
type = 1;
else if ( strcmp(pairstr,"ltccny") == 0 )
type = 2;
else
{
printf("cant find baserel (%s/%s)\n",base,rel);
return(0);
}
sprintf(payload,"&amount=%.4f&coin_type=%d%s",volume,type,pricestr);
if ( CHECKBALANCE(retstrp,dotrade,exchange,dir,base,rel,price,volume,argjson) == 0 && (json= huobi_issue_auth(&exchange->cHandle,exchange,method,payload)) != 0 )
{
txid = j64bits(json,"order_id");
free_json(json);
}
return(txid);
}
char *ORDERSTATUS(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson)
{
char payload[1024];
sprintf(payload,"&id=%llu&coin_type=1",(long long)quoteid);
return(jprint(huobi_issue_auth(&exchange->cHandle,exchange,"order_info",payload),1));
}
char *CANCELORDER(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson)
{
char payload[1024];
sprintf(payload,"&id=%llu&coin_type=1",(long long)quoteid);
return(jprint(huobi_issue_auth(&exchange->cHandle,exchange,"cancel_order",payload),1));
}
char *OPENORDERS(struct exchange_info *exchange,cJSON *argjson)
{
return(jprint(huobi_issue_auth(&exchange->cHandle,exchange,"get_orders","&coin_type=1"),1));
}
char *TRADEHISTORY(struct exchange_info *exchange,cJSON *argjson)
{
return(clonestr("{\"error\":\"huobi doesnt seem to have trade history api!\"}"));
}
char *WITHDRAW(struct exchange_info *exchange,char *base,double amount,char *destaddr,cJSON *argjson)
{
char payload[1024],*method;
if ( base == 0 || base[0] == 0 )
return(clonestr("{\"error\":\"base not specified\"}"));
if ( destaddr == 0 || destaddr[0] == 0 )
return(clonestr("{\"error\":\"destaddr not specified\"}"));
if ( amount < SMALLVAL )
return(clonestr("{\"error\":\"amount not specified\"}"));
method = "withdraw_coin";
sprintf(payload,"&coin_type=1&withdraw_address=%s&withdraw_amount=%.4f",destaddr,amount);
return(jprint(huobi_issue_auth(&exchange->cHandle,exchange,method,payload),1));
}
struct exchange_funcs huobi_funcs = EXCHANGE_FUNCS(huobi,EXCHANGE_NAME);
#include "exchange_undefs.h"

137
iguana/exchanges/instaforex.c

@ -0,0 +1,137 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#define EXCHANGE_NAME "instaforex"
#define UPDATE instaforex ## _price
#define SUPPORTS instaforex ## _supports
#define SIGNPOST instaforex ## _signpost
#define TRADE instaforex ## _trade
#define ORDERSTATUS instaforex ## _orderstatus
#define CANCELORDER instaforex ## _cancelorder
#define OPENORDERS instaforex ## _openorders
#define TRADEHISTORY instaforex ## _tradehistory
#define BALANCES instaforex ## _balances
#define PARSEBALANCE instaforex ## _parsebalance
#define WITHDRAW instaforex ## _withdraw
#define CHECKBALANCE instaforex ## _checkbalance
#define ALLPAIRS instaforex ## _allpairs
#define FUNCS instaforex ## _funcs
#define BASERELS instaforex ## _baserels
static char *BASERELS[][2] = { {"NZD","USD"},{"NZD","CHF"},{"NZD","CAD"},{"NZD","JPY"},{"GBP","NZD"},{"EUR","NZD"},{"AUD","NZD"},{"CAD","JPY"},{"CAD","CHF"},{"USD","CAD"},{"EUR","CAD"},{"GBP","CAD"},{"AUD","CAD"},{"USD","CHF"},{"CHF","JPY"},{"EUR","CHF"},{"GBP","CHF"},{"AUD","CHF"},{"EUR","USD"},{"EUR","AUD"},{"EUR","JPY"},{"EUR","GBP"},{"GBP","USD"},{"GBP","JPY"},{"GBP","AUD"},{"USD","JPY"},{"AUD","JPY"},{"AUD","USD"},{"XAU","USD"} };
#include "exchange_supports.h"
#define NUM_INSTAFOREX ((int32_t)(sizeof(BASERELS)/sizeof(*BASERELS)))
void prices777_instaforex(uint32_t timestamps[NUM_INSTAFOREX],double bids[NUM_INSTAFOREX],double asks[NUM_INSTAFOREX])
{
//{"NZDUSD":{"symbol":"NZDUSD","lasttime":1437580206,"digits":4,"change":"-0.0001","bid":"0.6590","ask":"0.6593"},
char contract[32],*jsonstr; cJSON *json,*item; int32_t i;
memset(timestamps,0,sizeof(*timestamps) * NUM_INSTAFOREX);
memset(bids,0,sizeof(*bids) * NUM_INSTAFOREX);
memset(asks,0,sizeof(*asks) * NUM_INSTAFOREX);
jsonstr = issue_curl("https://quotes.instaforex.com/get_quotes.php?q=NZDUSD,NZDCHF,NZDCAD,NZDJPY,GBPNZD,EURNZD,AUDNZD,CADJPY,CADCHF,USDCAD,EURCAD,GBPCAD,AUDCAD,USDCHF,CHFJPY,EURCHF,GBPCHF,AUDCHF,EURUSD,EURAUD,EURJPY,EURGBP,GBPUSD,GBPJPY,GBPAUD,USDJPY,AUDJPY,AUDUSD,XAUUSD&m=json");
if ( jsonstr != 0 )
{
// printf("(%s)\n",jsonstr);
if ( (json= cJSON_Parse(jsonstr)) != 0 )
{
for (i=0; i<NUM_INSTAFOREX; i++)
{
sprintf(contract,"%s%s",BASERELS[i][0],BASERELS[i][1]);
if ( (item= jobj(json,contract)) != 0 )
{
timestamps[i] = juint(item,"lasttime");
bids[i] = jdouble(item,"bid");
asks[i] = jdouble(item,"ask");
}
}
free_json(json);
}
free(jsonstr);
}
}
double UPDATE(struct exchange_info *exchange,char *_base,char *_rel,struct exchange_quote *bidasks,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert)
{
uint32_t timestamps[NUM_INSTAFOREX]; double bids[NUM_INSTAFOREX],asks[NUM_INSTAFOREX];
char base[32],rel[32]; int32_t numbids,numasks,i; double bid,ask;
strcpy(base,_base), touppercase(base);
strcpy(rel,_rel), touppercase(rel);
for (i=0; i<NUM_INSTAFOREX; i++)
{
if ( strcmp(base,BASERELS[i][0]) == 0 && strcmp(rel,BASERELS[i][1]) == 0 )
{
prices777_instaforex(timestamps,bids,asks);
numbids = numasks = 0;
bid = exchange_setquote(bidasks,&numbids,&numasks,0,invert,bids[i],1,commission,0,timestamps[i],0);
ask = exchange_setquote(bidasks,&numbids,&numasks,1,invert,asks[i],1,commission,0,timestamps[i],0);
if ( bid > SMALLVAL && ask > SMALLVAL )
return((bid + ask) * .5);
else return(0.);
}
}
return(0);
}
cJSON *SIGNPOST(void **cHandlep,int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *payload,char *path)
{
if ( retstrp != 0 )
*retstrp = clonestr("{\"error\":\"instaforex is readonly data source\"}");
return(cJSON_Parse("{}"));
}
char *PARSEBALANCE(struct exchange_info *exchange,double *balancep,char *coinstr,cJSON *argjson)
{
return(clonestr("{\"error\":\"instaforex is readonly data source\"}"));
}
cJSON *BALANCES(struct exchange_info *exchange,cJSON *argjson)
{
return(cJSON_Parse("{\"error\":\"instaforex is readonly data source\"}"));
}
uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *base,char *rel,int32_t dir,double price,double volume,cJSON *argjson)
{
return(0);
}
char *ORDERSTATUS(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson)
{
return(clonestr("{\"error\":\"instaforex is readonly data source\"}"));
}
char *CANCELORDER(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson)
{
return(clonestr("{\"error\":\"instaforex is readonly data source\"}"));
}
char *OPENORDERS(struct exchange_info *exchange,cJSON *argjson)
{
return(clonestr("{\"error\":\"instaforex is readonly data source\"}"));
}
char *TRADEHISTORY(struct exchange_info *exchange,cJSON *argjson)
{
return(clonestr("{\"error\":\"instaforex is readonly data source\"}"));
}
char *WITHDRAW(struct exchange_info *exchange,char *base,double amount,char *destaddr,cJSON *argjson)
{
return(clonestr("{\"error\":\"instaforex is readonly data source\"}"));
}
struct exchange_funcs instaforex_funcs = EXCHANGE_FUNCS(instaforex,EXCHANGE_NAME);
#include "exchange_undefs.h"

94
iguana/exchanges/jumblr.c

@ -0,0 +1,94 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#define EXCHANGE_NAME "jumblr"
#define UPDATE jumblr ## _price
#define SUPPORTS jumblr ## _supports
#define SIGNPOST jumblr ## _signpost
#define TRADE jumblr ## _trade
#define ORDERSTATUS jumblr ## _orderstatus
#define CANCELORDER jumblr ## _cancelorder
#define OPENORDERS jumblr ## _openorders
#define TRADEHISTORY jumblr ## _tradehistory
#define BALANCES jumblr ## _balances
#define PARSEBALANCE jumblr ## _parsebalance
#define WITHDRAW jumblr ## _withdraw
#define CHECKBALANCE jumblr ## _checkbalance
#define ALLPAIRS jumblr ## _allpairs
#define FUNCS jumblr ## _funcs
#define BASERELS jumblr ## _baserels
static char *BASERELS[][2] = { {"btc","nxt"}, {"btc","btcd"}, {"btc","ltc"}, {"btc","vrc"}, {"btc","doge"} };
#include "exchange_supports.h"
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert)
{
char url[1024],lrel[16],lbase[16];
strcpy(lrel,rel), strcpy(lbase,base);
tolowercase(lrel), tolowercase(lbase);
sprintf(url,"http://api.quadrigacx.com/v2/order_book?book=%s_%s",lbase,lrel);
return(exchanges777_standardprices(exchange,commission,base,rel,url,quotes,0,0,maxdepth,0,invert));
}
cJSON *SIGNPOST(void **cHandlep,int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *payload,char *path)
{
if ( retstrp != 0 )
*retstrp = clonestr("{\"error\":\"jumblr is not yet\"}");
return(cJSON_Parse("{}"));
}
char *PARSEBALANCE(struct exchange_info *exchange,double *balancep,char *coinstr,cJSON *argjson)
{
return(clonestr("{\"error\":\"jumblr is not yet\"}"));
}
cJSON *BALANCES(struct exchange_info *exchange,cJSON *argjson)
{
return(cJSON_Parse("{\"error\":\"jumblr is not yet\"}"));
}
uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *base,char *rel,int32_t dir,double price,double volume,cJSON *argjson)
{
return(0);
}
char *ORDERSTATUS(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson)
{
return(clonestr("{\"error\":\"jumblr is not yet\"}"));
}
char *CANCELORDER(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson)
{
return(clonestr("{\"error\":\"jumblr is not yet\"}"));
}
char *OPENORDERS(struct exchange_info *exchange,cJSON *argjson)
{
return(clonestr("{\"error\":\"jumblr is not yet\"}"));
}
char *TRADEHISTORY(struct exchange_info *exchange,cJSON *argjson)
{
return(clonestr("{\"error\":\"jumblr is not yet\"}"));
}
char *WITHDRAW(struct exchange_info *exchange,char *base,double amount,char *destaddr,cJSON *argjson)
{
return(clonestr("{\"error\":\"jumblr is not yet\"}"));
}
struct exchange_funcs jumblr_funcs = EXCHANGE_FUNCS(jumblr,EXCHANGE_NAME);
#include "exchange_undefs.h"

266
iguana/exchanges/lakebtc.c

@ -0,0 +1,266 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#define EXCHANGE_NAME "lakebtc"
#define UPDATE lakebtc ## _price
#define SUPPORTS lakebtc ## _supports
#define SIGNPOST lakebtc ## _signpost
#define TRADE lakebtc ## _trade
#define ORDERSTATUS lakebtc ## _orderstatus
#define CANCELORDER lakebtc ## _cancelorder
#define OPENORDERS lakebtc ## _openorders
#define TRADEHISTORY lakebtc ## _tradehistory
#define BALANCES lakebtc ## _balances
#define PARSEBALANCE lakebtc ## _parsebalance
#define WITHDRAW lakebtc ## _withdraw
#define CHECKBALANCE lakebtc ## _checkbalance
#define ALLPAIRS lakebtc ## _allpairs
#define FUNCS lakebtc ## _funcs
#define BASERELS lakebtc ## _baserels
static char *BASERELS[][2] = { {"btc","usd"}, {"btc","cny"} };
#include "exchange_supports.h"
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert)
{
char url[1024];
if ( strcmp(rel,"USD") == 0 )
sprintf(url,"https://www.LakeBTC.com/api_v1/bcorderbook");
else if ( strcmp(rel,"CNY") == 0 )
sprintf(url,"https://www.LakeBTC.com/api_v1/bcorderbook_cny");
else printf("illegal lakebtc pair.(%s/%s)\n",base,rel);
return(exchanges777_standardprices(exchange,commission,base,rel,url,quotes,0,0,maxdepth,0,invert));
}
cJSON *SIGNPOST(void **cHandlep,int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *payload,char *hdr1,uint64_t tonce)
{
char hdr2[512],cmdbuf[1024],buf64[1024],hdr3[512],dest[1025],hdr4[512],*sig,*data = 0; cJSON *json;
hdr2[0] = hdr3[0] = hdr4[0] = 0;
json = 0;
if ( (sig= hmac_sha1_str(dest,exchange->apisecret,(int32_t)strlen(exchange->apisecret),hdr1)) != 0 )
{
sprintf(cmdbuf,"%s:%s",exchange->userid,sig);
nn_base64_encode((void *)cmdbuf,strlen(cmdbuf),buf64,sizeof(buf64));
sprintf(hdr1,"Authorization:Basic %s",buf64);
sprintf(hdr2,"Json-Rpc-Tonce: %llu",(long long)tonce);
if ( dotrade == 0 )
data = exchange_would_submit(payload,hdr1,hdr2,hdr3,hdr4);
else if ( (data= curl_post(&exchange->cHandle,"https://www.LakeBTC.com/api_v1",0,payload,hdr1,hdr2,hdr3,hdr4)) != 0 )
json = cJSON_Parse(data);
}
if ( retstrp != 0 )
*retstrp = data;
else if ( data != 0 )
free(data);
return(json);
}
/* LakeBTC provides trading JSON-RPC API interface. HMAC (Hash-based Message Authentication Code) is employed as our authentication mechanisms. You need at 0.1 BTC in your account to retrieve your private key.
Besides your private key, the client needs to prepare the following attributes
tonce (timestamp in microseconds, i.e., unixtime × 1000000, make sure your clock is correctly adjusted)
accesskey (your registered email address at LakeBTC)
requestmethod (post)
id (JSON-RPC request id, an integer)
method (JSON-RPC method)
params (JSON-RPC parameters)
Concatenate the above parameters with &, in that order. Parameters can be blank. For example, $signature =
tonce=1389067414466757&accesskey=foo@bar.com&requestmethod=post&id=123&method=ticker&params=
Create HMAC signature with your private key by using SHA1. $hash =
hash_hmac('sha1', $signature, $privatetkey) #php
Join your email and the hash signature with colon (:), and sign with Base64. $b64 =
base64_encode("foo@bar.com:<hash>") #php YXRjQHF3amlhbi5jb206ZmEzM2UzYzg5MDZjg5MzdiYzFiYw==
Set HTTP Header. Note tonce is the same as that in Step 2.
Json-Rpc-Tonce: 1389067414466757 #HTTP HEADER
Authorization: Basic YXRjQHF3amlhbi5jb206ZmEzM2UzYzg5MDZjg5MzdiYzFiYw== #HTTP HEADER
POST params data in JSON format to this url:
https://www.LakeBTC.com/api_v1
API Methods
getAccountInfo
method=getAccountInfo
params= (i.e., blank)
static CURL *cHandle;
char *data,*method,buf64[4096],paramstr[128],jsonbuf[1024],base[64],rel[64],pairstr[64],params[1024],dest[512],url[1024],cmdbuf[8192],*sig,hdr1[4096],hdr2[4096],buf[4096]; cJSON *json; uint64_t tonce,nonce,txid = 0;
*retstrp = 0;
params[0] = 0;
nonce = exchange_nonce(exchange);
tonce = (nonce * 1000000 + ((uint64_t)milliseconds() % 1000) * 1000);
if ( dir == 0 )
{
method = "getAccountInfo";
sprintf(buf,"tonce=%llu&accesskey=%s&requestmethod=post&id=1&method=%s&params=",(long long)tonce,exchange->userid,method);
sprintf(jsonbuf,"{\"method\":\"%s\",\"params\":[\"%s\"],\"id\":1}",method,params);
}
else
{
if ( (dir= flipstr_for_exchange(exchange,pairstr,"%s_%s",dir,&price,&volume,base,rel)) == 0 )
{
printf("cant find baserel (%s/%s)\n",base,rel);
return(0);
}
method = (dir > 0) ? "buyOrder" : "sellOrder";
touppercase(rel);
sprintf(paramstr,"%.2f,%.4f,%s",price,volume,rel);
sprintf(buf,"tonce=%llu&accesskey=%s&requestmethod=post&id=1&method=%s&params=%s",(long long)tonce,exchange->userid,method,paramstr);
sprintf(jsonbuf,"{\"method\":\"%s\",\"params\":[\"%s\"],\"id\":1}",method,paramstr);
}
if ( (sig= hmac_sha1_str(dest,exchange->apisecret,(int32_t)strlen(exchange->apisecret),buf)) != 0 )
{
sprintf(cmdbuf,"%s:%s",exchange->userid,sig);
nn_base64_encode((void *)cmdbuf,strlen(cmdbuf),buf64,sizeof(buf64));
sprintf(url,"https://www.lakebtc.com/api_v1");
sprintf(hdr1,"Authorization:Basic %s",buf64);
sprintf(hdr2,"Json-Rpc-Tonce: %llu",(long long)tonce);
if ( (data= curl_post(&cHandle,url,0,jsonbuf,hdr1,hdr2,0,0)) != 0 )
{
//printf("submit cmd.(%s) [%s]\n",jsonbuf,data);
if ( (json= cJSON_Parse(data)) != 0 )
{
txid = j64bits(json,"order_id");
free_json(json);
}
} else fprintf(stderr,"submit err cmd.(%s)\n",cmdbuf);
if ( retstrp != 0 )
*retstrp = data;
else if ( data != 0 )
free(data);
}
*/
char *PARSEBALANCE(struct exchange_info *exchange,double *balancep,char *coinstr,cJSON *argjson)
{
char field[128],*str,*itemstr = 0; cJSON *obj=0,*item=0,*prof=0; double locked = 0;
*balancep = 0.;
strcpy(field,coinstr);
touppercase(field);
if ( argjson != 0 && (obj= jobj(argjson,"balance")) != 0 && (item= jobj(argjson,"locked")) != 0 && (prof= jobj(argjson,"profile")) != 0 )
{
*balancep = jdouble(obj,field);
locked = jdouble(item,field);
obj = cJSON_CreateObject();
jaddstr(obj,"base",field);
jaddnum(obj,"balance",*balancep);
jaddnum(obj,"locked",locked);
if ( (str= jstr(prof,"btc_deposit_addres")) != 0 )
jaddstr(obj,"deposit_address",str);
itemstr = jprint(obj,1);
}
if ( itemstr == 0 )
return(clonestr("{\"error\":\"cant find coin balance\"}"));
return(itemstr);
}
cJSON *BALANCES(struct exchange_info *exchange,cJSON *argjson)
{
char payload[1024],jsonbuf[1024],*method; uint64_t tonce;
method = "getAccountInfo";
tonce = (exchange_nonce(exchange) * 1000000 + ((uint64_t)OS_milliseconds() % 1000) * 1000);
sprintf(payload,"tonce=%llu&accesskey=%s&requestmethod=post&id=1&method=%s&params=",(long long)tonce,exchange->userid,method);
sprintf(jsonbuf,"{\"method\":\"%s\",\"params\":[\"%s\"],\"id\":1}",method,"");
return(SIGNPOST(&exchange->cHandle,1,0,exchange,jsonbuf,payload,tonce));
}
#include "checkbalance.c"
uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *base,char *rel,int32_t dir,double price,double volume,cJSON *argjson)
{
char payload[1024],jsonbuf[1024],pairstr[64],paramstr[512],*extra,*method;
cJSON *json; uint64_t tonce,txid = 0;
if ( (extra= *retstrp) != 0 )
*retstrp = 0;
tonce = (exchange_nonce(exchange) * 1000000 + ((uint64_t)OS_milliseconds() % 1000) * 1000);
if ( (dir= flipstr_for_exchange(exchange,pairstr,"%s_%s",dir,&price,&volume,base,rel,argjson)) == 0 )
{
printf("cant find baserel (%s/%s)\n",base,rel);
return(0);
}
method = (dir > 0) ? "buyOrder" : "sellOrder";
touppercase(rel);
sprintf(paramstr,"%.2f,%.4f,%s",price,volume,rel);
sprintf(payload,"tonce=%llu&accesskey=%s&requestmethod=post&id=1&method=%s&params=%s",(long long)tonce,exchange->userid,method,paramstr);
sprintf(jsonbuf,"{\"method\":\"%s\",\"params\":[\"%s\"],\"id\":1}",method,paramstr);
if ( CHECKBALANCE(retstrp,dotrade,exchange,dir,base,rel,price,volume,argjson) == 0 && (json= SIGNPOST(&exchange->cHandle,dotrade,retstrp,exchange,jsonbuf,payload,tonce)) != 0 )
{
txid = j64bits(json,"order_id");
free_json(json);
}
return(txid);
}
char *CANCELORDER(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson)
{
char payload[1024],jsonbuf[1024],*method,*retstr = 0; cJSON *json; uint64_t tonce;
method = "cancelOrder";
tonce = (exchange_nonce(exchange) * 1000000 + ((uint64_t)OS_milliseconds() % 1000) * 1000);
sprintf(jsonbuf,"{\"method\":\"%s\",\"params\":[\"%llu\"],\"id\":1}",method,(long long)quoteid);
if ( (json= SIGNPOST(&exchange->cHandle,1,&retstr,exchange,payload,jsonbuf,tonce)) != 0 )
{
free_json(json);
}
return(retstr); // return standardized cancelorder
}
char *OPENORDERS(struct exchange_info *exchange,cJSON *argjson)
{
char payload[1024],jsonbuf[1024],*method,*retstr = 0; cJSON *json; uint64_t tonce;
method = "getOrders";
tonce = (exchange_nonce(exchange) * 1000000 + ((uint64_t)OS_milliseconds() % 1000) * 1000);
sprintf(jsonbuf,"{\"method\":\"%s\",\"params\":[\"%s\"],\"id\":1}",method,"");
if ( (json= SIGNPOST(&exchange->cHandle,1,&retstr,exchange,payload,jsonbuf,tonce)) != 0 )
{
free_json(json);
}
return(retstr); // return standardized open orders
}
char *TRADEHISTORY(struct exchange_info *exchange,cJSON *argjson)
{
char payload[1024],jsonbuf[1024],timestr[64],*method,*retstr = 0;
cJSON *json; uint64_t tonce; uint32_t starttime;
method = "getTrades";
if ( (starttime= juint(argjson,"start")) != 0 )
sprintf(timestr,"%u",starttime);
else timestr[0] = 0;
tonce = (exchange_nonce(exchange) * 1000000 + ((uint64_t)OS_milliseconds() % 1000) * 1000);
sprintf(jsonbuf,"{\"method\":\"%s\",\"params\":[%s],\"id\":1}",method,timestr);
if ( (json= SIGNPOST(&exchange->cHandle,1,&retstr,exchange,payload,jsonbuf,tonce)) != 0 )
{
free_json(json);
}
return(retstr); // return standardized tradehistory
}
char *ORDERSTATUS(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson)
{
char *status,*retstr;
status = OPENORDERS(exchange,argjson);
if ( (retstr= exchange_extractorderid(0,status,quoteid,"id")) != 0 )
{
free(status);
return(retstr);
}
free(status);
return(clonestr("{\"error\":\"cant find quoteid\"}"));
}
char *WITHDRAW(struct exchange_info *exchange,char *base,double amount,char *destaddr,cJSON *argjson)
{
return(clonestr("{\"error\":\"lakebtc doesnt seem to have withdraw api!\"}"));
}
struct exchange_funcs lakebtc_funcs = EXCHANGE_FUNCS(lakebtc,EXCHANGE_NAME);
#include "exchange_undefs.h"

749
iguana/exchanges/nxtae.c

@ -0,0 +1,749 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#define NXT_ASSETID ('N' + ((uint64_t)'X'<<8) + ((uint64_t)'T'<<16)) // 5527630
#define DEFAULT_NXT_DEADLINE 720
#define issue_NXTPOST(cmdstr) bitcoind_RPC(0,"curl",myinfo->NXTAPIURL,0,0,cmdstr)
#define NXT_MSTYPE 5
#define NXT_ASSETTYPE 2
#define NXT_GENESISTIME 1385294400
cJSON *_issue_NXTjson(struct supernet_info *myinfo,char *extra)
{
char cmd[4096],*jsonstr; cJSON *json = 0;
//sprintf(cmd,"requestType=getAsset&asset=%s",assetidstr);
sprintf(cmd,"requestType=%s",extra);
//printf("_cmd.(%s)\n",cmd);
if ( (jsonstr= issue_NXTPOST(cmd)) != 0 )
{
json = cJSON_Parse(jsonstr);
free(jsonstr);
}
return(json);
}
char *_issue_getAsset(struct supernet_info *myinfo,char *assetidstr)
{
char cmd[4096],*jsonstr;
//sprintf(cmd,"requestType=getAsset&asset=%s",assetidstr);
sprintf(cmd,"requestType=getAsset&asset=%s",assetidstr);
//printf("_cmd.(%s)\n",cmd);
jsonstr = issue_NXTPOST(cmd);
//printf("(%s) -> (%s)\n",cmd,jsonstr);
return(jsonstr);
}
char *_issue_getCurrency(struct supernet_info *myinfo,char *assetidstr)
{
char cmd[4096];
//sprintf(cmd,"requestType=getAsset&asset=%s",assetidstr);
sprintf(cmd,"requestType=getCurrency&currency=%s",assetidstr);
//printf("_cmd.(%s)\n",cmd);
return(issue_NXTPOST(cmd));
}
char *_get_AEquotestr(struct supernet_info *myinfo,char *str,uint64_t orderid)
{
char cmd[256];
sprintf(cmd,"requestType=get%sOrder&order=%llu",str,(long long)orderid);
return(issue_NXTPOST(cmd));
}
uint64_t _get_AEquote(struct supernet_info *myinfo,char *str,uint64_t orderid)
{
char *jsonstr; cJSON *json; uint64_t nxt64bits = 0;
if ( (jsonstr= _get_AEquotestr(myinfo,str,orderid)) != 0 )
{
if ( (json= cJSON_Parse(jsonstr)) != 0 )
{
nxt64bits = j64bits(json,"account");
free_json(json);
}
free(jsonstr);
}
return(nxt64bits);
}
char *_get_MSoffers(struct supernet_info *myinfo,char *str)
{
char cmd[512];
sprintf(cmd,"requestType=get%sOffers&account=%s",str,myinfo->myaddr.NXTADDR);
return(issue_NXTPOST(cmd));
}
uint32_t get_blockutime(struct supernet_info *myinfo,uint32_t blocknum)
{
cJSON *json; uint32_t timestamp = 0; char cmd[4096],*jsonstr;
sprintf(cmd,"requestType=getBlock&height=%u",blocknum);
if ( (jsonstr= issue_NXTPOST(cmd)) != 0 )
{
//printf("(%s) -> (%s)\n",cmd,jsonstr);
if ( (json= cJSON_Parse(jsonstr)) != 0 )
{
if ( (timestamp= juint(json,"timestamp")) != 0 )
timestamp += NXT_GENESISTIME;
free_json(json);
}
free(jsonstr);
}
return(timestamp);
}
char *MGWassets[][3] =
{
{ "12659653638116877017", "BTC", "8" },
{ "17554243582654188572", "BTC", "8" }, // assetid, name, decimals
{ "4551058913252105307", "BTC", "8" },
{ "6918149200730574743", "BTCD", "4" },
{ "11060861818140490423", "BTCD", "4" },
{ "16344939950195952527", "DOGE", "4" },
{ "2303962892272487643", "DOGE", "4" },
{ "6775076774325697454", "OPAL", "8" },
{ "7734432159113182240", "VPN", "4" },
{ "9037144112883608562", "VRC", "8" },
{ "2881764795164526882", "LTC", "4" },
};
uint64_t is_MGWcoin(char *name)
{
int32_t i;
for (i=0; i<(int32_t)(sizeof(MGWassets)/sizeof(*MGWassets)); i++)
if ( strcmp(MGWassets[i][1],name) == 0 )
return(calc_nxt64bits(MGWassets[i][0]));
return(0);
}
char *is_MGWasset(uint64_t assetid)
{
int32_t i; char assetidstr[64];
expand_nxt64bits(assetidstr,assetid);
for (i=0; i<(int32_t)(sizeof(MGWassets)/sizeof(*MGWassets)); i++)
if ( strcmp(MGWassets[i][0],assetidstr) == 0 )
return(MGWassets[i][1]);
return(0);
}
uint64_t NXT_assetid(char *name)
{
uint64_t assetid;
if ( (assetid= is_MGWcoin(name)) != 0 )
return(assetid);
else if ( is_decimalstr(name) > 0 )
return(calc_nxt64bits(name));
else return(0);
}
double NXT_price_volume(double *volumep,uint64_t baseamount,uint64_t relamount)
{
*volumep = (((double)baseamount + 0.000000009999999) / SATOSHIDEN);
if ( baseamount > 0. )
return((double)relamount / (double)baseamount);
else return(0.);
}
int32_t is_native_crypto(char *name)
{
int32_t i,n;
if ( (n= (int32_t)strlen(name)) > 0 && n < 6 )
{
for (i=0; i<n; i++)
{
if ( (name[i] >= '0' && name[i] <= '9') || (name[i] >= 'A' && name[i] <= 'Z') ) continue;
printf("(%s) is not native crypto\n",name);
return(0);
}
printf("(%s) is native crypto\n",name);
return(1);
}
return(0);
}
int32_t get_assettype(struct supernet_info *myinfo,int32_t *numdecimalsp,char *assetidstr)
{
cJSON *json; char name[64],*jsonstr; uint64_t assetid; int32_t ap_type = -1; //struct assethash *ap,A;
*numdecimalsp = -1;
name[0] = 0;
if ( is_native_crypto(assetidstr) > 0 )
{
//printf("found native crypto.(%s) name.(%s)\n",assetidstr,name);
ap_type = 0;
*numdecimalsp = 8;
return(0);
}
if ( is_decimalstr(assetidstr) > 0 && (assetid= calc_nxt64bits(assetidstr)) == NXT_ASSETID )
{
//printf("found NXT_ASSETID.(%s)\n",assetidstr);
ap_type = 0;
*numdecimalsp = 8;
return(0);
}
/*if ( (ap= find_asset(assetid)) != 0 )
{
*numdecimalsp = ap->decimals;
return(ap->type);
}*/
memset(name,0,sizeof(name));
if ( (jsonstr= _issue_getAsset(myinfo,assetidstr)) != 0 )
{
if ( (json= cJSON_Parse(jsonstr)) != 0 )
{
if ( get_cJSON_int(json,"errorCode") == 0 )
{
//printf("assetstr.(%s)\n",jsonstr);
if ( extract_cJSON_str(name,16,json,"name") <= 0 )
*numdecimalsp = -1;
else *numdecimalsp = (int32_t)get_cJSON_int(json,"decimals");
ap_type = NXT_ASSETTYPE;
} //else printf("errorcode.%lld (%s)\n",(long long)get_cJSON_int(json,"errorCode"),jsonstr);
free_json(json);
} else printf("cant parse.(%s)\n",jsonstr);
free(jsonstr);
} else printf("couldnt getAsset.(%s)\n",assetidstr);
if ( ap_type < 0 )
{
if ( (jsonstr= _issue_getCurrency(myinfo,assetidstr)) != 0 )
{
if ( (json= cJSON_Parse(jsonstr)) != 0 )
{
if ( get_cJSON_int(json,"errorCode") == 0 )
{
if ( extract_cJSON_str(name,16,json,"name") <= 0 )
*numdecimalsp = -1;
else *numdecimalsp = (int32_t)get_cJSON_int(json,"decimals");
ap_type = NXT_MSTYPE;
}
free_json(json);
}
free(jsonstr);
}
}
/*memset(&A,0,sizeof(A));
A.assetid = assetid;
A.minvol = A.mult = calc_decimals_mult(*numdecimalsp);
A.decimals = *numdecimalsp;
A.type = ap_type;
strcpy(A.name,name);
create_asset(assetid,&A);*/
return(ap_type);
}
uint64_t calc_decimals_mult(int32_t decimals)
{
int32_t i; uint64_t mult = 1;
for (i=7-decimals; i>=0; i--)
mult *= 10;
return(mult);
}
uint64_t assetmult(struct supernet_info *myinfo,int32_t *is_MSp,char *assetidstr)
{
int32_t ap_type,decimals; uint64_t mult = 0;
ap_type = get_assettype(myinfo,&decimals,assetidstr);
if ( decimals >= 0 && decimals <= 8 )
mult = calc_decimals_mult(decimals);
*is_MSp = (ap_type == NXT_MSTYPE);
return(mult);
}
int32_t assetdecimals(struct supernet_info *myinfo,char *assetidstr)
{
int32_t ap_type,decimals = 0;
ap_type = get_assettype(myinfo,&decimals,assetidstr);
if ( ap_type == 0 )
return(8);
return(decimals);
}
uint64_t min_asset_amount(struct supernet_info *myinfo,uint64_t assetid)
{
char assetidstr[64]; int32_t tmp;
if ( assetid == NXT_ASSETID )
return(1);
expand_nxt64bits(assetidstr,assetid);
return(assetmult(myinfo,&tmp,assetidstr));
}
int32_t get_assetdecimals(struct supernet_info *myinfo,uint64_t assetid)
{
char assetidstr[64];
if ( assetid == NXT_ASSETID )
return(8);
expand_nxt64bits(assetidstr,assetid);
return(assetdecimals(myinfo,assetidstr));
}
uint64_t get_assetmult(struct supernet_info *myinfo,int32_t *is_MSp,uint64_t assetid)
{
char assetidstr[64];
expand_nxt64bits(assetidstr,assetid);
return(assetmult(myinfo,is_MSp,assetidstr));
}
double get_minvolume(struct supernet_info *myinfo,uint64_t assetid)
{
int32_t tmp;
return(dstr(get_assetmult(myinfo,&tmp,assetid)));
}
int64_t get_asset_quantity(struct supernet_info *myinfo,int64_t *unconfirmedp,char *NXTaddr,char *assetidstr)
{
char cmd[2*MAX_JSON_FIELD],*jsonstr; struct destbuf assetid; int32_t i,n,iter; cJSON *array,*item,*obj,*json; int64_t quantity,qty = 0;
uint64_t assetidbits;
quantity = *unconfirmedp = 0;
if ( is_decimalstr(assetidstr) > 0 )
assetidbits = calc_nxt64bits(assetidstr);
else return(0);
if ( assetidbits == NXT_ASSETID )
{
sprintf(cmd,"requestType=getBalance&account=%s",NXTaddr);
if ( (jsonstr= issue_NXTPOST(cmd)) != 0 )
{
//printf("(%s) -> (%s)\n",cmd,jsonstr);
if ( (json= cJSON_Parse(jsonstr)) != 0 )
{
qty = get_API_nxt64bits(cJSON_GetObjectItem(json,"balanceNQT"));
*unconfirmedp = get_API_nxt64bits(cJSON_GetObjectItem(json,"unconfirmedBalanceNQT"));
printf("(%s)\n",jsonstr);
free_json(json);
}
free(jsonstr);
}
return(qty);
}
sprintf(cmd,"requestType=getAccount&account=%s",NXTaddr);
if ( (jsonstr= issue_NXTPOST(cmd)) != 0 )
{
//printf("(%s) -> (%s)\n",cmd,jsonstr);
if ( (json= cJSON_Parse(jsonstr)) != 0 )
{
for (iter=0; iter<2; iter++)
{
qty = 0;
array = cJSON_GetObjectItem(json,iter==0?"assetBalances":"unconfirmedAssetBalances");
if ( is_cJSON_Array(array) != 0 )
{
n = cJSON_GetArraySize(array);
for (i=0; i<n; i++)
{
item = cJSON_GetArrayItem(array,i);
if ( (obj = cJSON_GetObjectItem(item,"asset")) == 0 )
printf("check for mscoin\n"), getchar();
copy_cJSON(&assetid,obj);
//printf("i.%d of %d: %s(%s)\n",i,n,assetid,cJSON_Print(item));
if ( strcmp(assetid.buf,assetidstr) == 0 )
{
qty = get_cJSON_int(item,iter==0?"balanceQNT":"unconfirmedBalanceQNT");
break;
}
}
}
if ( iter == 0 )
quantity = qty;
else *unconfirmedp = qty;
}
free_json(json);
}
free(jsonstr);
}
return(quantity);
}
uint64_t calc_asset_qty(struct supernet_info *myinfo,int32_t *is_MSp,uint64_t *availp,uint64_t *priceNQTp,int32_t checkflag,uint64_t assetid,double price,double vol)
{
char assetidstr[64];
uint64_t ap_mult,priceNQT,quantityQNT = 0;
int64_t unconfirmed,balance;
*priceNQTp = *availp = 0;
if ( assetid != NXT_ASSETID )
{
expand_nxt64bits(assetidstr,assetid);
if ( (ap_mult= get_assetmult(myinfo,is_MSp,assetid)) != 0 )
{
//price = (double)get_satoshi_obj(srcitem,"priceNQT") / ap_mult;
//vol = (double)get_satoshi_obj(srcitem,"quantityQNT") * ((double)ap_mult / SATOSHIDEN);
priceNQT = (price * ap_mult + (ap_mult/2)/SATOSHIDEN);
quantityQNT = (vol * SATOSHIDEN) / ap_mult;
balance = get_asset_quantity(myinfo,&unconfirmed,myinfo->myaddr.NXTADDR,assetidstr);
//printf("%s balance %.8f unconfirmed %.8f vs price %llu qty %llu for asset.%s | price_vol.(%f * %f) * (%lld / %llu)\n",NXTaddr,dstr(balance),dstr(unconfirmed),(long long)priceNQT,(long long)quantityQNT,assetidstr,price,vol,(long long)SATOSHIDEN,(long long)ap_mult);
//getchar();
if ( checkflag != 0 && (balance < quantityQNT || unconfirmed < quantityQNT) )
{
printf("balance %.8f < qty %.8f || unconfirmed %.8f < qty %llu\n",dstr(balance),dstr(quantityQNT),dstr(unconfirmed),(long long)quantityQNT);
return(0);
}
*priceNQTp = priceNQT;
*availp = unconfirmed;
} else printf("%llu null apmult\n",(long long)assetid);
}
else
{
*is_MSp = 0;
*priceNQTp = price * SATOSHIDEN;
quantityQNT = vol;
}
return(quantityQNT);
}
int32_t NXT_assetpolarity(struct supernet_info *myinfo,char *name)
{
int32_t ap_type,decimals;
if ( (ap_type= get_assettype(myinfo,&decimals,name)) == NXT_ASSETTYPE || ap_type == NXT_MSTYPE )
return(1);
else return(0);
}
#define EXCHANGE_NAME "nxtae"
#define UPDATE nxtae ## _price
#define SUPPORTS nxtae ## _supports
#define SIGNPOST nxtae ## _signpost
#define TRADE nxtae ## _trade
#define ORDERSTATUS nxtae ## _orderstatus
#define CANCELORDER nxtae ## _cancelorder
#define OPENORDERS nxtae ## _openorders
#define TRADEHISTORY nxtae ## _tradehistory
#define BALANCES nxtae ## _balances
#define PARSEBALANCE nxtae ## _parsebalance
#define WITHDRAW nxtae ## _withdraw
#define CHECKBALANCE nxtae ## _checkbalance
#define ALLPAIRS nxtae ## _allpairs
#define FUNCS nxtae ## _funcs
#define BASERELS nxtae ## _baserels
static char *BASERELS[][2] = { {"btc","nxt"}, {"btcd","nxt"}, {"ltc","nxt"}, {"vrc","nxt"}, {"doge","nxt"}, {"opal","nxt"} };
char *ALLPAIRS(struct exchange_info *exchange,cJSON *argjson)
{
return(jprint(exchanges777_allpairs(BASERELS,(int32_t)(sizeof(BASERELS)/sizeof(*BASERELS))),1));
}
int32_t SUPPORTS(struct exchange_info *exchange,char *base,char *rel,cJSON *argjson)
{
int32_t polarity; struct supernet_info *myinfo = SuperNET_MYINFO(0);
if ( (polarity= baserel_polarity(BASERELS,(int32_t)(sizeof(BASERELS)/sizeof(*BASERELS)),base,rel)) == 0 )
{
if ( strcmp(rel,"NXT") == 0 || strcmp(rel,"nxt") == 0 || (is_decimalstr(rel) != 0 && calc_nxt64bits(rel) == NXT_ASSETID) )
return(NXT_assetpolarity(myinfo,base));
else if ( strcmp(base,"NXT") == 0 || strcmp(base,"nxt") == 0 || (is_decimalstr(base) != 0 && calc_nxt64bits(rel) == NXT_ASSETID) )
return(-NXT_assetpolarity(myinfo,rel));
}
return(polarity);
}
cJSON *inner_json(double price,double vol,uint32_t timestamp,uint64_t quoteid,uint64_t nxt64bits,uint64_t qty,uint64_t pqt,uint64_t baseamount,uint64_t relamount)
{
cJSON *inner = cJSON_CreateArray();
jaddnum(inner,"price",price);
jaddnum(inner,"volume",vol);
jadd64bits(inner,"quoteid",quoteid);
jadd64bits(inner,"offerNXT",nxt64bits);
jaddnum(inner,"timestamp",timestamp);
jadd64bits(inner,"quantityQNT",qty);
jadd64bits(inner,"priceNQT",pqt);
jadd64bits(inner,"baseamount",baseamount);
jadd64bits(inner,"relamount",relamount);
return(inner);
}
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *bidasks,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert)
{
int32_t flip,i,n,is_MS; uint64_t baseamount,relamount,qty,pqt,ap_mult,baseid;
char url[1024],*str,*cmd,*field; struct supernet_info *myinfo = SuperNET_MYINFO(0);
uint32_t timestamp; cJSON *json,*bids,*asks,*srcobj,*item,*array; double price,vol,hbla = 0.;
if ( NXT_ASSETID != stringbits("NXT") || (strcmp(rel,"nxt") != 0 && strcmp(rel,"NXT") != 0 && strcmp(rel,"5527630") != 0) )
{
printf("NXT_ASSETID.%llu != %llu stringbits rel.%s\n",(long long)NXT_ASSETID,(long long)stringbits("NXT"),rel);//, getchar();
return(0);
}
baseid = NXT_assetid(base);
ap_mult = get_assetmult(myinfo,&is_MS,baseid);
bids = cJSON_CreateArray(), asks = cJSON_CreateArray();
for (flip=0; flip<2; flip++)
{
/*{
"offer": "16959774565785265980",
"expirationHeight": 1000000,
"accountRS": "NXT-QFAF-GR4F-RBSR-AXW2G",
"limit": "9000000",
"currency": "5775213290661997199",
"supply": "0",
"account": "9728792749189838093",
"height": 348856,
"rateNQT": "650"
}*/
if ( is_MS == 0 )
{
if ( flip == 0 )
cmd = "getBidOrders", field = "bidOrders", array = bids;
else cmd = "getAskOrders", field = "askOrders", array = asks;
sprintf(url,"requestType=%s&asset=%llu&limit=%d",cmd,(long long)baseid,maxdepth);
}
else
{
if ( flip == 0 )
cmd = "getBuyOffers", field = "offers", array = bids;
else cmd = "getSellOffers", field = "offers", array = asks;
sprintf(url,"requestType=%s&currency=%llu&limit=%d",cmd,(long long)baseid,maxdepth);
}
if ( (str= issue_NXTPOST(url)) != 0 )
{
//printf("{%s}\n",str);
if ( (json= cJSON_Parse(str)) != 0 )
{
if ( (srcobj= jarray(&n,json,field)) != 0 )
{
for (i=0; i<n && i<maxdepth; i++)
{
/*
"quantityQNT": "79",
"priceNQT": "13499000000",
"transactionHeight": 480173,
"accountRS": "NXT-FJQN-8QL2-BMY3-64VLK",
"transactionIndex": 1,
"asset": "15344649963748848799",
"type": "ask",
"account": "5245394173527769812",
"order": "17926122097022414596",
"height": 480173
*/
item = cJSON_GetArrayItem(srcobj,i);
if ( is_MS == 0 )
qty = j64bits(item,"quantityQNT"), pqt = j64bits(item,"priceNQT");
else qty = j64bits(item,"limit"), pqt = j64bits(item,"rateNQT");
baseamount = (qty * ap_mult), relamount = (qty * pqt);
price = NXT_price_volume(&vol,baseamount,relamount);
//printf("(%llu %llu) %f %f mult.%llu qty.%llu pqt.%llu baseamount.%lld relamount.%lld\n",(long long)prices->baseid,(long long)prices->relid,price,vol,(long long)prices->ap_mult,(long long)qty,(long long)pqt,(long long)baseamount,(long long)relamount);
timestamp = get_blockutime(myinfo,juint(item,"height"));
item = inner_json(price,vol,timestamp,j64bits(item,is_MS == 0 ? "order" : "offer"),j64bits(item,"account"),qty,pqt,baseamount,relamount);
cJSON_AddItemToArray(array,item);
}
}
free_json(json);
}
free(str);
} else printf("cant get.(%s)\n",url);
}
json = cJSON_CreateObject();
cJSON_AddItemToObject(json,"bids",bids);
cJSON_AddItemToObject(json,"asks",asks);
if ( Debuglevel > 2 )
printf("invert.%d NXTAE.(%s)\n",invert,jprint(json,0));
hbla = exchanges777_json_orderbook(exchange,commission,base,rel,bidasks,maxdepth,json,0,"bids","asks",0,0,invert);
free_json(json);
return(hbla);
}
uint64_t submit_triggered_nxtae(struct supernet_info *myinfo,int32_t dotrade,char **retjsonstrp,int32_t is_MS,char *bidask,uint64_t assetid,uint64_t qty,uint64_t NXTprice,char *triggerhash,char *comment,uint64_t otherNXT,uint32_t triggerheight)
{
int32_t deadline = 1 + 20; uint64_t txid = 0; struct destbuf errstr; char cmd[4096],secret[8192],*jsonstr; cJSON *json;
if ( retjsonstrp != 0 )
*retjsonstrp = 0;
if ( triggerheight != 0 )
deadline = DEFAULT_NXT_DEADLINE;
escape_code(secret,myinfo->secret);
if ( dotrade == 0 )
strcpy(secret,"<secret>");
sprintf(cmd,"requestType=%s&secretPhrase=%s&feeNQT=%u&deadline=%d",bidask,secret,0,deadline);
sprintf(cmd+strlen(cmd),"&%s=%llu&%s=%llu",is_MS!=0?"units":"quantityQNT",(long long)qty,is_MS!=0?"currency":"asset",(long long)assetid);
if ( NXTprice != 0 )
{
if ( is_MS != 0 )
sprintf(cmd+strlen(cmd),"&rateNQT=%llu",(long long)NXTprice);
else sprintf(cmd+strlen(cmd),"&priceNQT=%llu",(long long)NXTprice);
}
if ( otherNXT != 0 )
sprintf(cmd+strlen(cmd),"&recipient=%llu",(long long)otherNXT);
if ( triggerhash != 0 && triggerhash[0] != 0 )
{
if ( triggerheight == 0 )
sprintf(cmd+strlen(cmd),"&referencedTransactionFullHash=%s",triggerhash);
else sprintf(cmd+strlen(cmd),"&referencedTransactionFullHash=%s&phased=true&phasingFinishHeight=%u&phasingVotingModel=4&phasingQuorum=1&phasingLinkedFullHash=%s",triggerhash,triggerheight,triggerhash);
}
if ( comment != 0 && comment[0] != 0 )
sprintf(cmd+strlen(cmd),"&message=%s",comment);
if ( dotrade == 0 )
{
if ( retjsonstrp != 0 )
{
json = cJSON_CreateObject();
jaddstr(json,"submit",cmd);
*retjsonstrp = jprint(json,1);
}
return(0);
}
if ( (jsonstr= issue_NXTPOST(cmd)) != 0 )
{
_stripwhite(jsonstr,' ');
if ( (json= cJSON_Parse(jsonstr)) != 0 )
{
copy_cJSON(&errstr,cJSON_GetObjectItem(json,"error"));
if ( errstr.buf[0] == 0 )
copy_cJSON(&errstr,cJSON_GetObjectItem(json,"errorDescription"));
if ( errstr.buf[0] != 0 )
{
printf("submit_triggered_bidask.(%s) -> (%s)\n",cmd,jsonstr);
if ( retjsonstrp != 0 )
*retjsonstrp = clonestr(errstr.buf);
}
else txid = get_API_nxt64bits(cJSON_GetObjectItem(json,"transaction"));
}
free(jsonstr);
}
return(txid);
}
char *fill_nxtae(struct supernet_info *myinfo,int32_t dotrade,uint64_t *txidp,int32_t dir,double price,double volume,uint64_t baseid,uint64_t relid)
{
uint64_t txid,assetid,avail,qty,priceNQT,ap_mult; int32_t is_MS; char retbuf[512],*errstr,*cmdstr;
if ( baseid == NXT_ASSETID )
dir = -dir, assetid = relid;
else if ( relid == NXT_ASSETID )
assetid = baseid;
else return(clonestr("{\"error\":\"NXT AE order without NXT\"}"));
if ( (ap_mult= get_assetmult(myinfo,&is_MS,assetid)) == 0 )
return(clonestr("{\"error\":\"assetid not found\"}"));
qty = calc_asset_qty(myinfo,&is_MS,&avail,&priceNQT,0,assetid,price,volume);
if ( is_MS == 0 )
cmdstr = dir > 0 ? "placeBidOrder" : "placeAskOrder";
else cmdstr = dir > 0 ? "currencyBuy" : "currencySell";
txid = submit_triggered_nxtae(myinfo,dotrade,&errstr,is_MS,cmdstr,assetid,qty,priceNQT,0,0,0,0);
if ( errstr != 0 )
sprintf(retbuf,"{\"error\":\"%s\"}",errstr), free(errstr);
else sprintf(retbuf,"{\"result\":\"success\",\"txid\":\"%llu\"}",(long long)txid);
if ( txidp != 0 )
*txidp = txid;
return(clonestr(retbuf));
}
uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *base,char *rel,int32_t dir,double price,double volume,cJSON *argjson)
{
uint64_t baseid,relid; char *retstr; uint64_t txid = 0; struct supernet_info *myinfo = SuperNET_MYINFO(0);
if ( (baseid= NXT_assetid(base)) != 0 && (relid= NXT_assetid(rel)) != 0 )
{
retstr = fill_nxtae(myinfo,dotrade,&txid,dir,price,volume,baseid,relid);
if ( retstrp != 0 )
*retstrp = retstr;
else free(retstr);
}
return(txid);
}
char *PARSEBALANCE(struct exchange_info *exchange,double *balancep,char *coinstr,cJSON *argjson)
{
cJSON *item; char extra[256]; struct supernet_info *myinfo = SuperNET_MYINFO(0);
if ( strcmp(coinstr,"NXT") == 0 )
{
if ( (item= _issue_NXTjson(myinfo,"getAccount")) != 0 )
{
jadd(item,"NXT",item);
jaddstr(item,"result","success");
*balancep = dstr(j64bits(item,"balanceNQT"));
return(jprint(item,1));
}
}
else if ( NXT_assetpolarity(myinfo,coinstr) != 0 )
{
sprintf(extra,"getAccountAssets&asset=%s",coinstr);
if ( (item= _issue_NXTjson(myinfo,extra)) != 0 )
{
if ( jstr(item,"assetid") != 0 )
{
jaddstr(item,"result","success");
return(jprint(item,1));
}
free_json(item);
}
}
else
{
sprintf(extra,"getAccountCurrencies&currency=%s",coinstr);
if ( (item= _issue_NXTjson(myinfo,extra)) != 0 )
{
if ( jstr(item,"currency") != 0 )
{
jaddstr(item,"result","success");
return(jprint(item,1));
}
free_json(item);
}
}
return(clonestr("{\"error\":\"cant get coin balance\"}"));
}
cJSON *BALANCES(struct exchange_info *exchange,cJSON *argjson)
{
cJSON *item,*retjson = cJSON_CreateObject(); struct supernet_info *myinfo = SuperNET_MYINFO(0);
if ( (item= _issue_NXTjson(myinfo,"getAccountAssets")) != 0 )
jadd(retjson,"assets",item);
if ( (item= _issue_NXTjson(myinfo,"getAccountCurrencies")) != 0 )
jadd(retjson,"currencies",item);
if ( (item= _issue_NXTjson(myinfo,"getAccount")) != 0 )
jadd(retjson,"NXT",item);
jaddstr(retjson,"result","success");
return(retjson);
}
char *ORDERSTATUS(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson)
{
uint64_t nxt64bits; struct supernet_info *myinfo = SuperNET_MYINFO(0);
if ( (nxt64bits= _get_AEquote(myinfo,"Bid",quoteid)) == 0 )
return(_get_AEquotestr(myinfo,"Ask",quoteid));
else return(_get_AEquotestr(myinfo,"Bid",quoteid));
}
char *CANCELORDER(struct exchange_info *exchange,uint64_t orderid,cJSON *argjson)
{
uint64_t nxt64bits; char cmd[4096],secret[8192],*str = "Bid",*retstr = 0; struct supernet_info *myinfo = SuperNET_MYINFO(0);
if ( (nxt64bits= _get_AEquote(myinfo,str,orderid)) == 0 )
str = "Ask", nxt64bits = _get_AEquote(myinfo,str,orderid);
if ( nxt64bits == myinfo->myaddr.nxt64bits )
{
escape_code(secret,myinfo->secret);
sprintf(cmd,"requestType=cancel%sOrder&secretPhrase=%s&feeNQT=%d&deadline=%d&order=%llu",str,secret,0,DEFAULT_NXT_DEADLINE,(long long)orderid);
retstr = issue_NXTPOST(cmd);
//printf("(%s) -> (%s)\n",cmd,retstr);
}
else retstr = clonestr("{\"error\":\"cant cancel orderid\"}");
return(retstr);
}
char *OPENORDERS(struct exchange_info *exchange,cJSON *argjson)
{
cJSON *item,*retjson = cJSON_CreateObject(); struct supernet_info *myinfo = SuperNET_MYINFO(0);
if ( (item= _issue_NXTjson(myinfo,"getBuyOffers")) != 0 )
jadd(retjson,"buyoffers",item);
if ( (item= _issue_NXTjson(myinfo,"getSellOffers")) != 0 )
jadd(retjson,"selloffers",item);
if ( (item= _issue_NXTjson(myinfo,"getAccountCurrentBidOrders")) != 0 )
jadd(retjson,"bidorders",item);
if ( (item= _issue_NXTjson(myinfo,"getAccountCurrentAskOrders")) != 0 )
jadd(retjson,"sellorders",item);
jaddstr(retjson,"result","success");
return(jprint(retjson,1));
}
char *TRADEHISTORY(struct exchange_info *exchange,cJSON *argjson)
{
return(clonestr("{\"error\":\"nxtae tradehistory here\"}"));
}
char *WITHDRAW(struct exchange_info *exchange,char *base,double amount,char *destaddr,cJSON *argjson)
{
return(clonestr("{\"error\":\"MGW withdraw here\"}"));
}
struct exchange_funcs nxtae_funcs = EXCHANGE_FUNCS(nxtae,EXCHANGE_NAME);
#include "exchange_undefs.h"

229
iguana/exchanges/okcoin.c

@ -0,0 +1,229 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#define EXCHANGE_NAME "okcoin"
#define UPDATE okcoin ## _price
#define SUPPORTS okcoin ## _supports
#define SIGNPOST okcoin ## _signpost
#define TRADE okcoin ## _trade
#define ORDERSTATUS okcoin ## _orderstatus
#define CANCELORDER okcoin ## _cancelorder
#define OPENORDERS okcoin ## _openorders
#define TRADEHISTORY okcoin ## _tradehistory
#define BALANCES okcoin ## _balances
#define PARSEBALANCE okcoin ## _parsebalance
#define WITHDRAW okcoin ## _withdraw
#define EXCHANGE_AUTHURL "https://www.okcoin.com/api/v1"
#define CHECKBALANCE okcoin ## _checkbalance
#define ALLPAIRS okcoin ## _allpairs
#define FUNCS okcoin ## _funcs
#define BASERELS okcoin ## _baserels
static char *BASERELS[][2] = { {"btc","usd"}, {"ltc","usd"} };
#include "exchange_supports.h"
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert)
{
char url[1024],lrel[16],lbase[16];
strcpy(lrel,rel), strcpy(lbase,base);
tolowercase(lrel), tolowercase(lbase);
sprintf(url,"https://www.okcoin.com/api/v1/depth.do?symbol=%s_%s",lbase,lrel);
if ( strcmp(rel,"USD") != 0 && strcmp(rel,"BTC") != 0 )
{
fprintf(stderr,">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FATAL ERROR OKCOIN.(%s) only supports USD\n",url);
printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FATAL ERROR OKCOIN.(%s) only supports USD\n",url);
exit(-1);
return(0);
}
return(exchanges777_standardprices(exchange,commission,base,rel,url,quotes,0,0,maxdepth,0,invert));
}
cJSON *SIGNPOST(void **cHandlep,int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *url,char *payload)
{
char hdr1[512],hdr2[512],hdr3[512],hdr4[512],*data; cJSON *json;
hdr1[0] = hdr2[0] = hdr3[0] = hdr4[0] = 0;
json = 0;
if ( dotrade == 0 )
data = exchange_would_submit(payload,hdr1,hdr2,hdr3,hdr4);
else if ( (data= curl_post(&exchange->cHandle,url,0,payload,hdr1,hdr2,hdr3,hdr4)) != 0 )
json = cJSON_Parse(data);
if ( retstrp != 0 )
*retstrp = data;
else if ( data != 0 )
free(data);
return(json);
}
/*
static CURL *cHandle;
char *data,*path,*typestr,*extra,pricestr[64],base[64],rel[64],pairstr[64],url[1024],cmdbuf[8192],buf[512],digest[33]; cJSON *json; uint64_t nonce,txid = 0;
nonce = exchange_nonce(exchange);
if ( (extra= *retstrp) != 0 )
*retstrp = 0;
if ( dir == 0 )
{
path = "userinfo.do";
sprintf(buf,"api_key=%s&secret_key=%s",exchange->apikey,exchange->apisecret);
calc_md5(digest,buf,(int32_t)strlen(buf));
touppercase(digest);
sprintf(cmdbuf,"api_key=%s&sign=%s",exchange->apikey,digest);
}
else
{
path = "trade.do";
if ( (dir= flipstr_for_exchange(exchange,pairstr,"%s_%s",dir,&price,&volume,base,rel)) == 0 )
{
printf("cant find baserel (%s/%s)\n",base,rel);
return(0);
}
if ( extra != 0 && strcmp(extra,"market") == 0 )
typestr = (dir > 0) ? "buy_market" : "sell_market", sprintf(pricestr,"&price=%.2f",price); // docs say market orders put volume in price
else typestr = (dir > 0) ? "buy" : "sell", sprintf(pricestr,"&price=%.2f",price);
sprintf(buf,"amount=%.4f&api_key=%s%ssymbol=%s&type=%s&secret_key=%s",volume,exchange->apikey,pricestr,pairstr,typestr,exchange->apisecret);
calc_md5(digest,buf,(int32_t)strlen(buf));
touppercase(digest);
sprintf(cmdbuf,"amount=%.4f&api_key=%s%s&symbol=%s&type=%s&sign=%s",volume,exchange->apikey,pricestr,pairstr,typestr,digest);
}
//printf("MD5.(%s)\n",buf);
sprintf(url,"https://www.okcoin.com/api/v1/%s",path);
if ( (data= curl_post(&cHandle,url,0,cmdbuf,0,0,0,0)) != 0 ) // "{\"Content-type\":\"application/x-www-form-urlencoded\"}","{\"User-Agent\":\"OKCoin Javascript API Client\"}"
{
//printf("submit cmd.(%s) [%s]\n",cmdbuf,data);
if ( (json= cJSON_Parse(data)) != 0 )
{
txid = j64bits(json,"order_id");
free_json(json);
}
} else fprintf(stderr,"submit err cmd.(%s)\n",cmdbuf);
*/
cJSON *okcoin_issue_auth(void **cHandlep,struct exchange_info *exchange,char *method,char *buf)
{
char payload[1024],tmp[1024],digest[512],url[512];
sprintf(tmp,"api_key=%s%s",exchange->apikey,buf);
sprintf(payload,"%s&secret_key=%s",tmp,exchange->apisecret);
//printf("tmp.(%s) payload.(%s)\n",tmp,payload);
calc_md5(digest,payload,(int32_t)strlen(payload));
touppercase(digest);
sprintf(payload,"%s&sign=%s",tmp,digest);
sprintf(url,"%s/%s",EXCHANGE_AUTHURL,method);
return(SIGNPOST(&exchange->cHandle,1,0,exchange,url,payload));
}
char *PARSEBALANCE(struct exchange_info *exchange,double *balancep,char *coinstr,cJSON *argjson)
{
//okcoin.({"info":{"funds":{"asset":{"net":"0","total":"0"},"free":{"btc":"0","ltc":"0","usd":"0"},"freezed":{"btc":"0","ltc":"0","usd":"0"}}},"result":true})
char field[128],*itemstr = 0; cJSON *obj,*item,*avail,*locked; double lockval = 0;
*balancep = 0.;
strcpy(field,coinstr);
tolowercase(field);
if ( argjson != 0 && (obj= jobj(argjson,"info")) != 0 && (item= jobj(obj,"funds")) != 0 )
{
if ( (avail= jobj(item,"free")) != 0 )
*balancep = jdouble(avail,field);
if ( (locked= jobj(item,"freezed")) != 0 )
lockval = jdouble(locked,field);
obj = cJSON_CreateObject();
touppercase(field);
jaddstr(obj,"base",field);
jaddnum(obj,"balance",*balancep);
jaddnum(obj,"locked",lockval);
itemstr = jprint(obj,1);
}
if ( itemstr == 0 )
return(clonestr("{\"error\":\"cant find coin balance\"}"));
return(itemstr);
}
cJSON *BALANCES(struct exchange_info *exchange,cJSON *argjson)
{
return(okcoin_issue_auth(&exchange->cHandle,exchange,"userinfo.do",""));
}
#include "checkbalance.c"
uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *base,char *rel,int32_t dir,double price,double volume,cJSON *argjson)
{
char payload[1024],buf[1024],url[1024],digest[512],pairstr[512],pricestr[64],*extra,*typestr;
cJSON *json; uint64_t txid = 0;
if ( (extra= *retstrp) != 0 )
*retstrp = 0;
if ( (dir= flipstr_for_exchange(exchange,pairstr,"%s_%s",dir,&price,&volume,base,rel,argjson)) == 0 )
{
printf("cant find baserel (%s/%s)\n",base,rel);
return(0);
}
if ( extra != 0 && strcmp(extra,"market") == 0 )
typestr = (dir > 0) ? "buy_market" : "sell_market", sprintf(pricestr,"&price=%.2f",price); // docs say market orders put volume in price
else typestr = (dir > 0) ? "buy" : "sell";
sprintf(pricestr,"&price=%.2f",price);
sprintf(buf,"amount=%.4f&api_key=%s%ssymbol=%s&type=%s&secret_key=%s",volume,exchange->apikey,pricestr,pairstr,typestr,exchange->apisecret);
calc_md5(digest,buf,(int32_t)strlen(buf));
touppercase(digest);
sprintf(payload,"amount=%.4f&api_key=%s%s&symbol=%s&type=%s&sign=%s",volume,exchange->apikey,pricestr,pairstr,typestr,digest);
sprintf(url,"%s/%s",EXCHANGE_AUTHURL,"trade.do");
if ( CHECKBALANCE(retstrp,dotrade,exchange,dir,base,rel,price,volume,argjson) == 0 && (json= SIGNPOST(&exchange->cHandle,dotrade,retstrp,exchange,url,payload)) != 0 )
{
txid = j64bits(json,"order_id");
free_json(json);
}
return(txid);
}
char *ORDERSTATUS(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson)
{
char buf[64];
sprintf(buf,"&symbol=btc_usd&order_id=%llu",(long long)quoteid);
return(jprint(okcoin_issue_auth(&exchange->cHandle,exchange,"order_info.do",buf),1));
}
char *CANCELORDER(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson)
{
char buf[64];
sprintf(buf,"&symbol=btc_usd&order_id=%llu",(long long)quoteid);
return(jprint(okcoin_issue_auth(&exchange->cHandle,exchange,"cancel_order.do",buf),1));
}
char *OPENORDERS(struct exchange_info *exchange,cJSON *argjson)
{
return(jprint(okcoin_issue_auth(&exchange->cHandle,exchange,"orders_info.do",""),1));
}
char *TRADEHISTORY(struct exchange_info *exchange,cJSON *argjson)
{
return(jprint(okcoin_issue_auth(&exchange->cHandle,exchange,"orders_history.do","&status=1&symbol=btc_usd&current_page=0&page_length=200"),1));
}
char *WITHDRAW(struct exchange_info *exchange,char *base,double amount,char *destaddr,cJSON *argjson)
{
char payload[1024],*method,*tradepassword;
if ( base == 0 || base[0] == 0 )
return(clonestr("{\"error\":\"base not specified\"}"));
if ( destaddr == 0 || destaddr[0] == 0 )
return(clonestr("{\"error\":\"destaddr not specified\"}"));
if ( amount < SMALLVAL )
return(clonestr("{\"error\":\"amount not specified\"}"));
if ( (tradepassword= jstr(argjson,"tradepassword")) == 0 )
tradepassword = exchange->tradepassword;
if ( tradepassword == 0 || tradepassword[0] == 0 )
return(clonestr("{\"error\":\"tradepassword not specified\"}"));
method = "withdraw_coin";
sprintf(payload,"&symbol=btc_usd&chargefee=0.0001&withdraw_address=%s&withdraw_amount=%.4f&trade_pwd=%s",destaddr,amount,tradepassword);
return(jprint(okcoin_issue_auth(&exchange->cHandle,exchange,method,payload),1));
}
struct exchange_funcs okcoin_funcs = EXCHANGE_FUNCS(okcoin,EXCHANGE_NAME);
#include "exchange_undefs.h"

259
iguana/exchanges/poloniex.c

@ -0,0 +1,259 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#define EXCHANGE_NAME "poloniex"
#define UPDATE poloniex ## _price
#define SUPPORTS poloniex ## _supports
#define SIGNPOST poloniex ## _signpost
#define TRADE poloniex ## _trade
#define ORDERSTATUS poloniex ## _orderstatus
#define CANCELORDER poloniex ## _cancelorder
#define OPENORDERS poloniex ## _openorders
#define TRADEHISTORY poloniex ## _tradehistory
#define BALANCES poloniex ## _balances
#define PARSEBALANCE poloniex ## _parsebalance
#define WITHDRAW poloniex ## _withdraw
#define EXCHANGE_AUTHURL "https://poloniex.com/tradingApi"
#define CHECKBALANCE poloniex ## _checkbalance
#define ALLPAIRS poloniex ## _allpairs
#define FUNCS poloniex ## _funcs
static char *(*poloniex_baserels)[][2];
char *ALLPAIRS(struct exchange_info *exchange,cJSON *argjson)
{
static int32_t num;
char *jsonstr,*baserel; int32_t i; cJSON *json,*item;
printf("ALLPAIRS num.%d %p\n",num,*poloniex_baserels);
if ( num == 0 || (*poloniex_baserels) == 0 )
{
jsonstr = issue_curl("https://poloniex.com/public?command=returnTicker");
//jsonstr[0] = '[';
//jsonstr[strlen(jsonstr)-1] = ']';
i = 0;
if ( (json= cJSON_Parse(jsonstr)) != 0 )
{
if ( (num= cJSON_GetArraySize(json)) != 0 )
{
poloniex_baserels = calloc(num,sizeof(char *) * 2);
item = json->child;
while ( item != 0 )
{
if ( (baserel= item->string) != 0 && strncmp(baserel,"BTC_",4) == 0 && strlen(baserel) > 4 )
{
(*poloniex_baserels)[i][0] = clonestr(baserel+4);
(*poloniex_baserels)[i][1] = "BTC";
i++;
}
item = item->next;
}
}
free_json(json);
}
num = i;
printf("(%s) num.%d\n",jsonstr,num);
free(jsonstr);
}
return(jprint(exchanges777_allpairs((*poloniex_baserels),num),1));
}
int32_t SUPPORTS(struct exchange_info *exchange,char *base,char *rel,cJSON *argjson)
{
//char *baserels[][2] = { {"btc","usd"} };
//return(baserel_polarity(baserels,(int32_t)(sizeof(baserels)/sizeof(*baserels)),base,rel));
if ( strlen(base) > 5 || strlen(rel) > 5 || strcmp(rel,"CNY") == 0 || strcmp(base,"CNY") == 0 || strcmp(rel,"USD") == 0 || strcmp(base,"USD") == 0 )
return(0);
if ( strcmp(rel,"BTC") == 0 )
return(1);
else if ( strcmp(base,"BTC") == 0 )
return(-1);
else return(0);
}
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert)
{
char market[128],url[1024];
sprintf(market,"%s_%s",rel,base);
sprintf(url,"https://poloniex.com/public?command=returnOrderBook&currencyPair=%s&depth=%d",market,maxdepth);
return(exchanges777_standardprices(exchange,commission,base,rel,url,quotes,0,0,maxdepth,0,invert));
}
cJSON *SIGNPOST(void **cHandlep,int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *url,char *payload)
{
char dest[(512>>3)*2+1],hdr1[512],hdr2[512],hdr3[512],hdr4[512],*data,*sig; cJSON *json;
hdr1[0] = hdr2[0] = hdr3[0] = hdr4[0] = 0;
json = 0;
if ( (sig= hmac_sha512_str(dest,exchange->apisecret,(int32_t)strlen(exchange->apisecret),payload)) != 0 )
sprintf(hdr1,"Sign:%s",sig);
else hdr1[0] = 0;
sprintf(hdr2,"Key:%s",exchange->apikey);
if ( dotrade == 0 )
data = exchange_would_submit(payload,hdr1,hdr2,hdr3,hdr4);
else if ( (data= curl_post(&exchange->cHandle,url,0,payload,hdr1,hdr2,hdr3,hdr4)) != 0 )
{
json = cJSON_Parse(data);
//printf("GOT.(%s) %p\n",data,json);
}
if ( retstrp != 0 )
*retstrp = data;
else if ( data != 0 )
free(data);
return(json);
}
cJSON *BALANCES(struct exchange_info *exchange,cJSON *argjson)
{
char payload[1024];
sprintf(payload,"command=returnCompleteBalances&nonce=%llu",(long long)exchange_nonce(exchange));
return(SIGNPOST(&exchange->cHandle,1,0,exchange,EXCHANGE_AUTHURL,payload));
}
char *PARSEBALANCE(struct exchange_info *exchange,double *balancep,char *coinstr,cJSON *argjson)
{
char *itemstr = 0; cJSON *item,*obj; double onorders,btcvalue;
*balancep = 0.;
if ( argjson != 0 && (item= jobj(argjson,coinstr)) != 0 )
{
itemstr = jprint(item,0);
*balancep = jdouble(item,"available");
onorders = jdouble(item,"onOrders");
btcvalue = jdouble(item,"btcValue");
if ( (obj= cJSON_Parse(itemstr)) != 0 )
{
free(itemstr);
jaddstr(obj,"base",coinstr);
jaddnum(obj,"balance",*balancep);
jaddnum(obj,"onOrders",onorders);
jaddnum(obj,"btcvalue",btcvalue);
itemstr = jprint(obj,1);
}
}
if ( itemstr == 0 )
return(clonestr("{\"error\":\"cant find coin balance\"}"));
return(itemstr);
}
#include "checkbalance.c"
uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *base,char *rel,int32_t dir,double price,double volume,cJSON *argjson)
{
char payload[1024],pairstr[64],*extra,*typestr; cJSON *json; uint64_t nonce,txid = 0;
nonce = exchange_nonce(exchange);
if ( (extra= *retstrp) != 0 )
*retstrp = 0;
dir = flip_for_exchange(pairstr,"%s_%s","BTC",dir,&price,&volume,base,rel);
if ( extra != 0 && strcmp(extra,"margin") == 0 )
typestr = (dir > 0) ? "marginBuy":"marginSell";
else typestr = (dir > 0) ? "buy":"sell";
sprintf(payload,"command=%s&nonce=%lld&currencyPair=%s&rate=%.8f&amount=%.8f",typestr,(long long)nonce,pairstr,price,volume);
if ( CHECKBALANCE(retstrp,dotrade,exchange,dir,base,rel,price,volume,argjson) == 0 && (json= SIGNPOST(&exchange->cHandle,dotrade,retstrp,exchange,EXCHANGE_AUTHURL,payload)) != 0 )
{
txid = (get_API_nxt64bits(cJSON_GetObjectItem(json,"orderNumber")) << 32) | get_API_nxt64bits(cJSON_GetObjectItem(json,"tradeID"));
free_json(json);
}
return(txid);
}
void poloniex_setpair(char *pair,cJSON *argjson)
{
char *base,*rel;
base = jstr(argjson,"base");
rel = jstr(argjson,"rel");
if ( base == 0 || rel == 0 )
strcpy(pair,"all");
else sprintf(pair,"%s_%s",rel,base);
}
char *CANCELORDER(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson)
{
char payload[1024],*retstr = 0; cJSON *json;
sprintf(payload,"command=cancelOrder&nonce=%llu&orderNumber=%llu",(long long)exchange_nonce(exchange),(long long)quoteid);
if ( (json= SIGNPOST(&exchange->cHandle,1,&retstr,exchange,EXCHANGE_AUTHURL,payload)) != 0 )
{
free_json(json);
}
return(retstr); // return standardized cancelorder
}
char *OPENORDERS(struct exchange_info *exchange,cJSON *argjson)
{
char payload[1024],pair[64],*retstr = 0; cJSON *json;
poloniex_setpair(pair,argjson);
sprintf(payload,"command=returnOpenOrders&nonce=%llu&currencyPair=%s",(long long)exchange_nonce(exchange),pair);
if ( (json= SIGNPOST(&exchange->cHandle,1,&retstr,exchange,EXCHANGE_AUTHURL,payload)) != 0 )
{
free_json(json);
}
return(retstr); // return standardized open orders
}
char *TRADEHISTORY(struct exchange_info *exchange,cJSON *argjson)
{
char payload[1024],pair[64],*retstr = 0; cJSON *json; uint32_t timestamp,endstamp;
poloniex_setpair(pair,argjson);
timestamp = juint(argjson,"start");
endstamp = juint(argjson,"end");
sprintf(payload,"command=returnTradeHistory&nonce=%llu&currencyPair=%s",(long long)exchange_nonce(exchange),pair);
if ( timestamp != 0 )
sprintf(payload + strlen(payload),"&start=%u",timestamp);
if ( endstamp != 0 )
sprintf(payload + strlen(payload),"&end=%u",endstamp);
if ( (json= SIGNPOST(&exchange->cHandle,1,&retstr,exchange,EXCHANGE_AUTHURL,payload)) != 0 )
{
free_json(json);
}
return(retstr); // return standardized tradehistory
}
char *ORDERSTATUS(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson)
{
char *status,*retstr; uint32_t iter;
for (iter=0; iter<2; iter++)
{
if ( iter == 0 )
status = OPENORDERS(exchange,argjson);
else status = TRADEHISTORY(exchange,argjson);
if ( (retstr= exchange_extractorderid(iter,status,quoteid,"orderNumber")) != 0 )
{
free(status);
return(retstr);
}
free(status);
}
return(clonestr("{\"error\":\"cant find quoteid\"}"));
}
char *WITHDRAW(struct exchange_info *exchange,char *base,double amount,char *destaddr,cJSON *argjson)
{
char payload[1024],*paymentid,*retstr = 0; cJSON *json;
if ( base == 0 || base[0] == 0 )
return(clonestr("{\"error\":\"base not specified\"}"));
if ( destaddr == 0 || destaddr[0] == 0 )
return(clonestr("{\"error\":\"destaddr not specified\"}"));
if ( amount < SMALLVAL )
return(clonestr("{\"error\":\"amount not specified\"}"));
paymentid = jstr(argjson,"paymentid");
sprintf(payload,"command=withdraw&nonce=%llu&currency=%s&amount=%.6f&address=%s",(long long)exchange_nonce(exchange),base,amount,destaddr);
if ( paymentid != 0 )
sprintf(payload + strlen(payload),"&paymentId=%s",paymentid);
if ( (json= SIGNPOST(&exchange->cHandle,1,&retstr,exchange,EXCHANGE_AUTHURL,payload)) != 0 )
{
free_json(json);
}
return(retstr); // return standardized withdraw
}
struct exchange_funcs poloniex_funcs = EXCHANGE_FUNCS(poloniex,EXCHANGE_NAME);
#include "exchange_undefs.h"

172
iguana/exchanges/quadriga.c

@ -0,0 +1,172 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#define EXCHANGE_NAME "quadriga"
#define UPDATE quadriga ## _price
#define SUPPORTS quadriga ## _supports
#define SIGNPOST quadriga ## _signpost
#define TRADE quadriga ## _trade
#define ORDERSTATUS quadriga ## _orderstatus
#define CANCELORDER quadriga ## _cancelorder
#define OPENORDERS quadriga ## _openorders
#define TRADEHISTORY quadriga ## _tradehistory
#define BALANCES quadriga ## _balances
#define PARSEBALANCE quadriga ## _parsebalance
#define WITHDRAW quadriga ## _withdraw
#define CHECKBALANCE quadriga ## _checkbalance
#define ALLPAIRS quadriga ## _allpairs
#define FUNCS quadriga ## _funcs
#define BASERELS quadriga ## _baserels
static char *BASERELS[][2] = { {"btc","usd"}, {"btc","cad"} };
#include "exchange_supports.h"
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert)
{
char url[1024],lrel[16],lbase[16];
strcpy(lrel,rel), strcpy(lbase,base);
tolowercase(lrel), tolowercase(lbase);
sprintf(url,"https://api.quadrigacx.com/v2/order_book?book=%s_%s",lbase,lrel);
return(exchanges777_standardprices(exchange,commission,base,rel,url,quotes,0,0,maxdepth,0,invert));
}
cJSON *SIGNPOST(void **cHandlep,int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *payload,char *path)
{
char url[1024],req[1024],md5secret[128],tmp[1024],dest[1025],hdr1[512],hdr2[512],hdr3[512],hdr4[512],*sig,*data = 0;
cJSON *json; uint64_t nonce;
hdr1[0] = hdr2[0] = hdr3[0] = hdr4[0] = 0;
json = 0;
nonce = exchange_nonce(exchange) * 1000 + ((uint64_t)OS_milliseconds() % 1000);
sprintf(tmp,"%llu%s%s",(long long)nonce,exchange->userid,exchange->apikey);
calc_md5(md5secret,exchange->apisecret,(int32_t)strlen(exchange->apisecret));
if ( (sig= hmac_sha256_str(dest,md5secret,(int32_t)strlen(md5secret),tmp)) != 0 )
{
sprintf(req,"{\"key\":\"%s\",%s\"nonce\":%llu,\"signature\":\"%s\"}",exchange->apikey,payload,(long long)nonce,sig);
sprintf(hdr1,"Content-Type:application/json");
sprintf(hdr2,"charset=utf-8");
sprintf(hdr3,"Content-Length:%ld",(long)strlen(req));
sprintf(url,"https://api.quadrigacx.com/v2/%s",path);
if ( dotrade == 0 )
data = exchange_would_submit(req,hdr1,hdr2,hdr3,hdr4);
else if ( (data= curl_post(&exchange->cHandle,url,0,req,hdr1,hdr2,hdr3,hdr4)) != 0 )
json = cJSON_Parse(data);
}
if ( retstrp != 0 )
*retstrp = data;
else if ( data != 0 )
free(data);
return(json);
}
char *PARSEBALANCE(struct exchange_info *exchange,double *balancep,char *coinstr,cJSON *argjson)
{
//[{"btc_available":"0.00000000","btc_reserved":"0.00000000","btc_balance":"0.00000000","cad_available":"0.00","cad_reserved":"0.00","cad_balance":"0.00","usd_available":"0.00","usd_reserved":"0.00","usd_balance":"0.00","xau_available":"0.000000","xau_reserved":"0.000000","xau_balance":"0.000000","fee":"0.5000"}]
char field[128],*str,*itemstr = 0; cJSON *obj; double reserv,total;
*balancep = 0.;
strcpy(field,coinstr);
tolowercase(field);
strcat(field,"_available");
if ( argjson != 0 && (str= jstr(argjson,field)) != 0 )
{
*balancep = jdouble(argjson,field);
strcpy(field,coinstr), tolowercase(field), strcat(field,"_reserved");
reserv = jdouble(argjson,field);
strcpy(field,coinstr), tolowercase(field), strcat(field,"_balance");
total = jdouble(argjson,field);
obj = cJSON_CreateObject();
jaddnum(obj,"balance",*balancep);
jaddnum(obj,"locked_balance",reserv);
jaddnum(obj,"total",total);
itemstr = jprint(obj,1);
}
if ( itemstr == 0 )
return(clonestr("{\"error\":\"cant find coin balance\"}"));
return(itemstr);
}
cJSON *BALANCES(struct exchange_info *exchange,cJSON *argjson)
{
return(SIGNPOST(&exchange->cHandle,1,0,exchange,"","balance"));
}
#include "checkbalance.c"
uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *base,char *rel,int32_t dir,double price,double volume,cJSON *argjson)
{
char payload[1024],pairstr[64],*extra,*path; cJSON *json; uint64_t txid = 0;
if ( (extra= *retstrp) != 0 )
*retstrp = 0;
if ( (dir= flipstr_for_exchange(exchange,pairstr,"%s_%s",dir,&price,&volume,base,rel,argjson)) == 0 )
{
printf("cant find baserel (%s/%s)\n",base,rel);
return(0);
}
path = (dir > 0) ? "buy" : "sell";
//key - API key
//signature - signature
//nonce - nonce
//amount - amount of major currency
//price - price to buy at
//book - optional, if not specified, will default to btc_cad
sprintf(payload,"\"amount\":%.6f,\"price\":%.3f,\"book\":\"%s_%s\",",volume,price,base,rel);
if ( CHECKBALANCE(retstrp,dotrade,exchange,dir,base,rel,price,volume,argjson) == 0 && (json= SIGNPOST(&exchange->cHandle,dotrade,retstrp,exchange,payload,path)) != 0 )
{
// parse json and set txid
free_json(json);
}
return(txid);
}
char *ORDERSTATUS(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson)
{
char buf[64];
sprintf(buf,"\"id\":%llu,",(long long)quoteid);
return(jprint(SIGNPOST(&exchange->cHandle,1,0,exchange,buf,"lookup_order"),1));
}
char *CANCELORDER(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson)
{
char buf[64];
sprintf(buf,"\"id\":%llu,",(long long)quoteid);
return(jprint(SIGNPOST(&exchange->cHandle,1,0,exchange,buf,"cancel_order"),1));
}
char *OPENORDERS(struct exchange_info *exchange,cJSON *argjson)
{
return(jprint(SIGNPOST(&exchange->cHandle,1,0,exchange,"","open_orders"),1));
}
char *TRADEHISTORY(struct exchange_info *exchange,cJSON *argjson)
{
return(jprint(SIGNPOST(&exchange->cHandle,1,0,exchange,"","user_transactions"),1));
}
char *WITHDRAW(struct exchange_info *exchange,char *base,double amount,char *destaddr,cJSON *argjson)
{
char buf[1024];
if ( base == 0 || base[0] == 0 )
return(clonestr("{\"error\":\"base not specified\"}"));
if ( destaddr == 0 || destaddr[0] == 0 )
return(clonestr("{\"error\":\"destaddr not specified\"}"));
if ( amount < SMALLVAL )
return(clonestr("{\"error\":\"amount not specified\"}"));
sprintf(buf,"\"amount\":%.4f,\"address\":\"%s\",",amount,destaddr);
printf("submit.(%s)\n",buf);
return(jprint(SIGNPOST(&exchange->cHandle,1,0,exchange,"","bitcoin_withdrawal"),1));
}
struct exchange_funcs quadriga_funcs = EXCHANGE_FUNCS(quadriga,EXCHANGE_NAME);
#include "exchange_undefs.h"

211
iguana/exchanges/truefx.c

@ -0,0 +1,211 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#define EXCHANGE_NAME "truefx"
#define UPDATE truefx ## _price
#define SUPPORTS truefx ## _supports
#define SIGNPOST truefx ## _signpost
#define TRADE truefx ## _trade
#define ORDERSTATUS truefx ## _orderstatus
#define CANCELORDER truefx ## _cancelorder
#define OPENORDERS truefx ## _openorders
#define TRADEHISTORY truefx ## _tradehistory
#define BALANCES truefx ## _balances
#define PARSEBALANCE truefx ## _parsebalance
#define WITHDRAW truefx ## _withdraw
#define CHECKBALANCE truefx ## _checkbalance
#define ALLPAIRS truefx ## _allpairs
#define FUNCS truefx ## _funcs
#define BASERELS truefx ## _baserels
static char *BASERELS[][2] = { {"EUR","USD"},{"USD","JPY"},{"GBP","USD"},{"EUR","GBP"},{"USD","CHF"},{"AUD","NZD"},{"CAD","CHF"},{"CHF","JPY"},{"EUR","AUD"},{"EUR","CAD"},{"EUR","JPY"},{"EUR","CHF"},{"USD","CAD"},{"AUD","USD"},{"GBP","JPY"},{"AUD","CAD"},{"AUD","CHF"},{"AUD","JPY"},{"EUR","NOK"},{"EUR","NZD"},{"GBP","CAD"},{"GBP","CHF"},{"NZD","JPY"},{"NZD","USD"},{"USD","NOK"},{"USD","SEK"} };
#include "exchange_supports.h"
uint64_t prices777_truefx(char *reqbase,char *reqrel,uint64_t *millistampp,double *bidp,double *askp,double *openp,double *highp,double *lowp,double *closep,char *username,char *password,uint64_t sessionid)
{
// static uint32_t lasttime; static char *laststr;
char *truefxfmt = "http://webrates.truefx.com/rates/connect.html?f=csv&id=%s:%s:poll:%llu&c=EUR/USD,USD/JPY,GBP/USD,EUR/GBP,USD/CHF,AUD/NZD,CAD/CHF,CHF/JPY,EUR/AUD,EUR/CAD,EUR/JPY,EUR/CHF,USD/CAD,AUD/USD,GBP/JPY,AUD/CAD,AUD/CHF,AUD/JPY,EUR/NOK,EUR/NZD,GBP/CAD,GBP/CHF,NZD/JPY,NZD/USD,USD/NOK,USD/SEK";
// EUR/USD,1437569931314,1.09,034,1.09,038,1.08922,1.09673,1.09384 USD/JPY,1437569932078,123.,778,123.,781,123.569,123.903,123.860 GBP/USD,1437569929008,1.56,332,1.56,337,1.55458,1.56482,1.55538 EUR/GBP,1437569931291,0.69,742,0.69,750,0.69710,0.70383,0.70338 USD/CHF,1437569932237,0.96,142,0.96,153,0.95608,0.96234,0.95748 EUR/JPY,1437569932237,134.,960,134.,972,134.842,135.640,135.476 EUR/CHF,1437569930233,1.04,827,1.04,839,1.04698,1.04945,1.04843 USD/CAD,1437569929721,1.30,231,1.30,241,1.29367,1.30340,1.29466 AUD/USD,1437569931700,0.73,884,0.73,890,0.73721,0.74395,0.74200 GBP/JPY,1437569931924,193.,500,193.,520,192.298,193.670,192.649
char url[1024],userpass[1024],buf[128],base[64],rel[64],*str=0; cJSON *array;
int32_t jpyflag,i,n=0; double pre,pre2,bid,ask,openval,high,low; long millistamp;
millistamp = pre = pre2 = bid = ask = openval = high = low = 0;
//printf("truefx.(%s)(%s).%llu\n",username,password,(long long)idnum);
url[0] = 0;
if ( username[0] != 0 && password[0] != 0 )
{
if ( sessionid == 0 )
{
sprintf(userpass,"http://webrates.truefx.com/rates/connect.html?f=csv&s=y&u=%s&p=%s&q=poll",username,password);
if ( (str= issue_curl(userpass)) != 0 )
{
_stripwhite(str,0);
printf("(%s) -> (%s)\n",userpass,str);
sprintf(userpass,"%s:%s:poll:",username,password);
sessionid = calc_nxt64bits(str + strlen(userpass));
free(str);
//printf("idnum.%llu\n",(long long)sessionid);
}
}
if ( sessionid != 0 )
sprintf(url,truefxfmt,username,password,(long long)sessionid);
}
if ( url[0] == 0 )
sprintf(url,"http://webrates.truefx.com/rates/connect.html?f=csv&s=y");
/*if ( laststr != 0 && time(NULL) > lasttime )
{
//printf("free laststr.%p lag.%d\n",laststr,(int32_t)(time(NULL) - lasttime));
free(laststr);
laststr = 0;
} else str = laststr;
if ( str == 0 )
{
str = issue_curl(url);
lasttime = (uint32_t)time(NULL);
laststr = str;
}*/
str = issue_curl(url);
if ( str != 0 )
{
//printf("(%s) -> (%s)\n",url,str);
/*EUR/USD,1454354222037,1.08,997,1.09,000,1.08142,1.09130,1.08333
USD/JPY,1454354221120,121.,049,121.,053,120.676,121.496,121.289
GBP/USD,1454354221048,1.44,242,1.44,254,1.42280,1.44305,1.42483
EUR/GBP,1454354220966,0.75,561,0.75,567,0.75517,0.76238,0.76031
USD/CHF,1454354221288,1.01,866,1.01,876,1.01553,1.02514,1.02209
EUR/JPY,1454354221693,131.,937,131.,944,131.224,132.003,131.381
EUR/CHF,1454354221028,1.11,027,1.11,032,1.10542,1.11173,1.10705
USD/CAD,1454354221764,1.39,473,1.39,479,1.39437,1.40627,1.39729
AUD/USD,1454354221515,0.70,955,0.70,961,0.70421,0.70970,0.70817
GBP/JPY,1454354221581,174.,602,174.,621,172.408,174.730,172.805
*/
while ( str[n + 0] != 0 && str[n] != '\n' && str[n] != '\r' )
{
for (i=jpyflag=0; str[n + i]!=' '&&str[n + i]!='\n'&&str[n + i]!='\r'&&str[n + i]!=0; i++)
{
if ( i > 0 && str[n+i] == ',' && str[n+i-1] == '.' )
str[n+i-1] = ' ', jpyflag = 1;
else if ( i > 0 && str[n+i-1] == ',' && str[n+i] == '0' && str[n+i+1+2] == ',' )
{
str[n+i] = ' ';
if ( str[n+i+1] == '0' )
str[n+i+1] = ' ', i++;
}
}
memcpy(base,str+n,3), base[3] = 0;
memcpy(rel,str+n+4,3), rel[3] = 0;
str[n + i] = 0;
sprintf(buf,"[%s]",str+n+7+1);
//printf("str.(%s) (%s/%s) %d n.%d i.%d |%s|\n",str+n,base,rel,str[n],n,i,buf);
n += i + 1;
if ( (array= cJSON_Parse(buf)) != 0 )
{
if ( is_cJSON_Array(array) != 0 )
{
millistamp = j64bits(jitem(array,0),0);
pre = jdouble(jitem(array,1),0);
bid = jdouble(jitem(array,2),0);
pre2 = jdouble(jitem(array,3),0);
ask = jdouble(jitem(array,4),0);
openval = jdouble(jitem(array,5),0);
high = jdouble(jitem(array,6),0);
low = jdouble(jitem(array,7),0);
if ( jpyflag != 0 )
bid = pre + (bid / 1000.), ask = pre2 + (ask / 1000.);
else bid = pre + (bid / 100000.), ask = pre2 + (ask / 100000.);
if ( strcmp(base,reqbase) == 0 && strcmp(rel,reqrel) == 0 )
{
*bidp = bid, *askp = ask, *openp = openval, *highp = high, *lowp = low;
*closep = 0;
*millistampp = millistamp;
//printf("(%f %f)\n ",bid,ask);
break;
}
}
free_json(array);
} else printf("cant parse.(%s)\n",buf);
}
free(str);
}
return(sessionid);
}
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *bidasks,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert)
{
int32_t numbids,numasks; double bid,ask,openval,high,low,closeval,volume=1; uint64_t millistamp;
char *username = "",*password = "";
if ( exchange->apikey[0] != 0 && exchange->apisecret[0] != 0 )
username = exchange->apikey, password = exchange->apisecret;
else if ( exchange->userid[0] != 0 && exchange->tradepassword[0] != 0 )
username = exchange->userid, password = exchange->tradepassword;
exchange->lastnonce = prices777_truefx(base,rel,&millistamp,&bid,&ask,&openval,&high,&low,&closeval,username,password,exchange->lastnonce);
numbids = numasks = 0;
bid = exchange_setquote(bidasks,&numbids,&numasks,0,invert,bid,volume,commission,0,(uint32_t)(millistamp/1000),0);
ask = exchange_setquote(bidasks,&numbids,&numasks,1,invert,ask,volume,commission,0,(uint32_t)(millistamp/1000),0);
if ( bid > SMALLVAL && ask > SMALLVAL )
return((bid + ask) * .5);
else return(0);
}
cJSON *SIGNPOST(void **cHandlep,int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *payload,char *path)
{
if ( retstrp != 0 )
*retstrp = clonestr("{\"error\":\"truefx is readonly data source\"}");
return(cJSON_Parse("{}"));
}
char *PARSEBALANCE(struct exchange_info *exchange,double *balancep,char *coinstr,cJSON *argjson)
{
return(clonestr("{\"error\":\"truefx is readonly data source\"}"));
}
cJSON *BALANCES(struct exchange_info *exchange,cJSON *argjson)
{
return(cJSON_Parse("{\"error\":\"truefx is readonly data source\"}"));
}
uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *base,char *rel,int32_t dir,double price,double volume,cJSON *argjson)
{
return(0);
}
char *ORDERSTATUS(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson)
{
return(clonestr("{\"error\":\"truefx is readonly data source\"}"));
}
char *CANCELORDER(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson)
{
return(clonestr("{\"error\":\"truefx is readonly data source\"}"));
}
char *OPENORDERS(struct exchange_info *exchange,cJSON *argjson)
{
return(clonestr("{\"error\":\"truefx is readonly data source\"}"));
}
char *TRADEHISTORY(struct exchange_info *exchange,cJSON *argjson)
{
return(clonestr("{\"error\":\"truefx is readonly data source\"}"));
}
char *WITHDRAW(struct exchange_info *exchange,char *base,double amount,char *destaddr,cJSON *argjson)
{
return(clonestr("{\"error\":\"truefx is readonly data source\"}"));
}
struct exchange_funcs truefx_funcs = EXCHANGE_FUNCS(truefx,EXCHANGE_NAME);
#include "exchange_undefs.h"

94
iguana/exchanges/unconf.c

@ -0,0 +1,94 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#define EXCHANGE_NAME "unconf"
#define UPDATE unconf ## _price
#define SUPPORTS unconf ## _supports
#define SIGNPOST unconf ## _signpost
#define TRADE unconf ## _trade
#define ORDERSTATUS unconf ## _orderstatus
#define CANCELORDER unconf ## _cancelorder
#define OPENORDERS unconf ## _openorders
#define TRADEHISTORY unconf ## _tradehistory
#define BALANCES unconf ## _balances
#define PARSEBALANCE unconf ## _parsebalance
#define WITHDRAW unconf ## _withdraw
#define CHECKBALANCE unconf ## _checkbalance
#define ALLPAIRS unconf ## _allpairs
#define FUNCS unconf ## _funcs
#define BASERELS unconf ## _baserels
static char *BASERELS[][2] = { {"btc","nxt"}, {"btc","btcd"}, {"btc","ltc"}, {"btc","vrc"}, {"btc","doge"} };
#include "exchange_supports.h"
double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert)
{
char url[1024],lrel[16],lbase[16];
strcpy(lrel,rel), strcpy(lbase,base);
tolowercase(lrel), tolowercase(lbase);
sprintf(url,"http://api.quadrigacx.com/v2/order_book?book=%s_%s",lbase,lrel);
return(exchanges777_standardprices(exchange,commission,base,rel,url,quotes,0,0,maxdepth,0,invert));
}
cJSON *SIGNPOST(void **cHandlep,int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *payload,char *path)
{
if ( retstrp != 0 )
*retstrp = clonestr("{\"error\":\"unconf is read only\"}");
return(cJSON_Parse("{}"));
}
char *PARSEBALANCE(struct exchange_info *exchange,double *balancep,char *coinstr,cJSON *argjson)
{
return(clonestr("{\"error\":\"unconf is read only\"}"));
}
cJSON *BALANCES(struct exchange_info *exchange,cJSON *argjson)
{
return(cJSON_Parse("{\"error\":\"unconf is read only\"}"));
}
uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *base,char *rel,int32_t dir,double price,double volume,cJSON *argjson)
{
return(0);
}
char *ORDERSTATUS(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson)
{
return(clonestr("{\"error\":\"unconf is read only\"}"));
}
char *CANCELORDER(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson)
{
return(clonestr("{\"error\":\"unconf is read only\"}"));
}
char *OPENORDERS(struct exchange_info *exchange,cJSON *argjson)
{
return(clonestr("{\"error\":\"unconf is read only\"}"));
}
char *TRADEHISTORY(struct exchange_info *exchange,cJSON *argjson)
{
return(clonestr("{\"error\":\"unconf is read only\"}"));
}
char *WITHDRAW(struct exchange_info *exchange,char *base,double amount,char *destaddr,cJSON *argjson)
{
return(clonestr("{\"error\":\"unconf is read only\"}"));
}
struct exchange_funcs unconf_funcs = EXCHANGE_FUNCS(unconf,EXCHANGE_NAME);
#include "exchange_undefs.h"

91
iguana/exchanges777.h

@ -0,0 +1,91 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#ifndef EXCHANGES777_H
#define EXCHANGES777_H
#include "iguana777.h"
#include <curl/curl.h>
#include <curl/easy.h>
#define EXCHANGES777_MINPOLLGAP 3
#define EXCHANGES777_MAXDEPTH 200
#define EXCHANGES777_DEFAULT_TIMEOUT 30
struct exchange_info;
struct exchange_funcs
{
char name[32];
double (*price)(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert);
int32_t (*supports)(struct exchange_info *exchange,char *base,char *rel,cJSON *argjson);
char *(*parsebalance)(struct exchange_info *exchange,double *balancep,char *coinstr,cJSON *argjson);
cJSON *(*balances)(struct exchange_info *exchange,cJSON *argjson);
uint64_t (*trade)(int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *base,char *rel,int32_t dir,double price,double volume,cJSON *argjson);
char *(*orderstatus)(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson);
char *(*cancelorder)(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson);
char *(*openorders)(struct exchange_info *exchange,cJSON *argjson);
char *(*tradehistory)(struct exchange_info *exchange,cJSON *argjson);
char *(*withdraw)(struct exchange_info *exchange,char *base,double amount,char *destaddr,cJSON *argjson);
char *(*allpairs)(struct exchange_info *exchange,cJSON *argjson);
};
#define EXCHANGE_FUNCS(xchg,name) { name, xchg ## _price, xchg ## _supports, xchg ## _parsebalance, xchg ## _balances, xchg ## _trade, xchg ## _orderstatus, xchg ## _cancelorder, xchg ## _openorders, xchg ## _tradehistory, xchg ## _withdraw, xchg ## _allpairs }
struct exchange_info
{
struct exchange_funcs issue;
char name[16],apikey[MAX_JSON_FIELD],apisecret[MAX_JSON_FIELD],tradepassword[MAX_JSON_FIELD],userid[MAX_JSON_FIELD];
uint32_t exchangeid,pollgap,lastpoll;
uint64_t lastnonce,exchangebits; double commission;
void *privatedata;
CURL *cHandle; queue_t requestQ,pricesQ,pendingQ[2],tradebotsQ;
};
struct instantdex_msghdr
{
struct acct777_sig sig __attribute__((packed));
char cmd[8];
uint8_t serialized[];
} __attribute__((packed));
struct exchange_request
{
struct queueitem DL;
cJSON *argjson; char **retstrp; struct exchange_info *exchange;
double price,volume,hbla,lastbid,lastask,commission;
uint64_t orderid; uint32_t timedout,expiration,dead,timestamp;
int32_t dir,depth,func,numbids,numasks;
char base[32],rel[32],destaddr[64],invert,allflag,dotrade;
struct exchange_quote bidasks[];
};
void *curl_post(void **cHandlep,char *url,char *userpass,char *postfields,char *hdr0,char *hdr1,char *hdr2,char *hdr3);
char *instantdex_sendcmd(struct supernet_info *myinfo,cJSON *argjson,char *cmdstr,char *ipaddr,int32_t hops);
char *exchanges777_Qprices(struct exchange_info *exchange,char *base,char *rel,int32_t maxseconds,int32_t allfields,int32_t depth,cJSON *argjson,int32_t monitor,double commission);
struct exchange_info *exchanges777_info(char *exchangestr,int32_t sleepflag,cJSON *json,char *remoteaddr);
char *exchanges777_unmonitor(struct exchange_info *exchange,char *base,char *rel);
void tradebot_timeslice(struct exchange_info *exchange,void *bot);
char *exchanges777_Qtrade(struct exchange_info *exchange,char *base,char *rel,int32_t maxseconds,int32_t dotrade,int32_t dir,double price,double volume,cJSON *argjson);
struct exchange_request *exchanges777_baserelfind(struct exchange_info *exchange,char *base,char *rel,int32_t func);
struct exchange_info *exchanges777_find(char *exchangestr);
void prices777_processprice(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *bidasks,int32_t maxdepth);
double truefx_price(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *bidasks,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert);
double fxcm_price(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *bidasks,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert);
double instaforex_price(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *bidasks,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert);
#endif

BIN
iguana/fonts/MaterialIcons-Regular.woff2

Binary file not shown.

BIN
iguana/fonts/Roboto-Bold.woff2

Binary file not shown.

BIN
iguana/fonts/Roboto-Light.woff2

Binary file not shown.

BIN
iguana/fonts/Roboto-Medium.woff2

Binary file not shown.

BIN
iguana/fonts/Roboto-Regular.woff2

Binary file not shown.

12
iguana/footer.html

@ -1,12 +0,0 @@
</div>
</div>
<!-- API fileds -->
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
</body></html>

13
iguana/form-widget.html

@ -0,0 +1,13 @@
<!DOCTYPE HTML>
<html style="overflow-y:scroll;-webkit-user-select: text">
<head>
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="-1">
<title>iguana form widget</title>
<link rel="stylesheet" href="css/bootstrap.css" type="text/css">
</head>
<body>
<div class="container">
</div>
</body>
</html>

4
iguana/help/agent.md

@ -0,0 +1,4 @@
%s API
===
%s

6
iguana/help/bootstrap-theme.min.css

File diff suppressed because one or more lines are too long

6
iguana/help/bootstrap.min.css

File diff suppressed because one or more lines are too long

7
iguana/help/bootstrap.min.js

File diff suppressed because one or more lines are too long

0
iguana/field.html → iguana/help/field.html

1
iguana/help/field.md

@ -0,0 +1 @@
%s | %s | %s

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save