diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 index b4382289d..a3c30f016 --- a/.gitignore +++ b/.gitignore @@ -1,14 +1,18 @@ *.o -agents/iguana -agents/libcrypto777.a + + agents/iguana.exe iguana/pnacl/Release/iguana_unstripped.pexe +iguana/pnacl/Release/iguana.pexe + +agents/libcrypto777.a + iguana/pnacl/Release/iguana_unstripped.bc *.deps @@ -18,3 +22,9 @@ iguana/pnacl/Release/iguana_unstripped.bc---linked.pre_opt.pexe *.stamp *.d + +iguana/tests/.priv2wif.swp + +agents/libiguana.a + +iguana/iguana_rpc.o-2ed461a0 diff --git a/InstantDEX/Makefile b/InstantDEX/Makefile old mode 100644 new mode 100755 diff --git a/InstantDEX/index.html b/InstantDEX/index.html old mode 100644 new mode 100755 diff --git a/InstantDEX/main.c b/InstantDEX/main.c old mode 100644 new mode 100755 diff --git a/LEGAL/AUTHORS b/LEGAL/AUTHORS old mode 100644 new mode 100755 diff --git a/LEGAL/DEVELOPER-AGREEMENT b/LEGAL/DEVELOPER-AGREEMENT old mode 100644 new mode 100755 diff --git a/LEGAL/LICENSE b/LEGAL/LICENSE old mode 100644 new mode 100755 diff --git a/LEGAL/THIRDPARTY-LICENSES b/LEGAL/THIRDPARTY-LICENSES old mode 100644 new mode 100755 diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..4b4578781 --- /dev/null +++ b/Makefile @@ -0,0 +1,21 @@ + + +win32: win32_crypto win32_iguana + +win64: win64_crypto win64_iguana + +#build for win32 environment +win32_crypto: + cd crypto777; make -f make_win32; cd .. + +win32_iguana: + cd iguana; make -f make_win32; cd .. + +#build for win64 environment +win64_crypto: + cd crypto777; make -f make_win64; cd .. + +win64_iguana: + cd iguana; make -f make_win64; cd .. + + diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 985d18afa..4c1fe8141 --- a/README.md +++ b/README.md @@ -1,10 +1,8 @@ #SuperNET Client "iguana" -[![Join the chat at https://gitter.im/jl777/SuperNET](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/jl777/SuperNET?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) - > #TL;DR# > -> ```sudo apt-get update; sudo apt-get install libcurl4-gnutls-dev libssl-dev; git clone https://github.com/jl777/SuperNET; cd SuperNET; ./m_onetime m_unix; ./m_unix; agents/iguana``` +> ```sudo apt-get update; sudo apt-get git install build-essential; git clone https://github.com/jl777/SuperNET; cd SuperNET; ./m_onetime m_unix;``` > > The above one line gets SuperNET installed, built and launched for unix. > @@ -12,6 +10,8 @@ > *Continue below at "Running".* **iguana is easy to build. Start by cloning (or downloading) this repository.** +*** all external dependencies have been removed, except for -lpthread and -lm + #DEPENDENCIES# ##for native (unix, osx)## @@ -108,3 +108,35 @@ iguana can be invoked with a command line argument. if it is a name of a file, i "exchanges" -> { "name":"", ... } "apikey", "apisecret", "userid", "tradepassword" these are as expected "pollgap" -> gap between each access to exchange for getting prices + +on OSX mksquashfs is not native, you will need to install fuse: https://osxfuse.github.io/ and a squashfs for mac: https://github.com/vasi/squashfuse + + ********** + user feedback: + A Note on Installation from pebwindkraft at bitco.in +======================= +Though I had xcode installed, aclocal didn’t work. I installed homebrew, and then: +# brew install autoconf +# brew install automake +# brew install gmp + +2.) libsecp256 +it complained, that libsecp256 was not there in includes, so I linked it. +Loretta:/Users/volker/SuperNET/includes # ln -s ../osx/libsecp256k1 . + +3.) I had to change ulimit +During the syncing, I have many, many messages like this: +>> +>> cant create.(tmp/BTC/252000/.tmpmarker) errno.24 Too many open files +>> cant create.(tmp/BTC/18000/.tmpmarker) errno.24 Too many open files +>> +Loretta:/Users/volker/SuperNET # ulimit -n 2048 + + +##### tests +in the SuperNET/iguana/tests directory, there is a jsoncmp.c file, which can be built into the jsoncmp executable via ./make_jsoncmp +once jsoncmp is built, then ./test shows how to use it +./jsoncmp {\"fields\":[{\"fieldA\":\"requiredvalueA\"},{\"fieldB\":\"requiredvalueB\"},...]} + +the idea is to issue a curl command into a /tmp/file and then use jsoncmp to verify the exact value of one or more fields. it will print to stdout JSON with "error" or "result" and to stderr if there is an error + diff --git a/SuperNET/Makefile b/SuperNET/Makefile old mode 100644 new mode 100755 diff --git a/SuperNET/SuperNET.c b/SuperNET/SuperNET.c old mode 100644 new mode 100755 diff --git a/SuperNET/SuperNET.h b/SuperNET/SuperNET.h old mode 100644 new mode 100755 diff --git a/SuperNET/hostnet777.c b/SuperNET/hostnet777.c index fc9c99f58..54341bbba 100755 --- a/SuperNET/hostnet777.c +++ b/SuperNET/hostnet777.c @@ -146,7 +146,7 @@ extern int32_t Debuglevel; #include "../includes/curve25519.h" -static bits256 zeropoint; +static const bits256 zeropoint; int64_t hostnet777_convmT(struct hostnet777_mtime *mT,int64_t othermillitime) { diff --git a/SuperNET/index.html b/SuperNET/index.html old mode 100644 new mode 100755 diff --git a/SuperNET/main.c b/SuperNET/main.c old mode 100644 new mode 100755 index 1ba57afe1..b429a8eab --- a/SuperNET/main.c +++ b/SuperNET/main.c @@ -216,7 +216,7 @@ bits256 SuperNET_OPRETURN(struct supernet_info *myinfo,char *symbol,double fee,u bits256 SuperNET_agentannounce(struct supernet_info *myinfo,struct supernet_agent *agent,cJSON *network) { - static bits256 zero; + static const bits256 zero; uint8_t buf[80 + sizeof(struct iguana_msghdr)],*data; bits256 pubkey,sig; int32_t i,len=0; uint8_t netmagic[4]; char *sigstr,*announce,*pubkeystr; memset(buf,0,sizeof(buf)); diff --git a/SuperNET/teleport777.c b/SuperNET/teleport777.c index 352cfa4a3..d32106c10 100755 --- a/SuperNET/teleport777.c +++ b/SuperNET/teleport777.c @@ -96,7 +96,7 @@ uint64_t parse_unspent_json(struct telepod *pod,struct coin777 *coin,cJSON *json copy_cJSON(&tmp,cJSON_GetObjectItem(json,"txid")), safecopy(pod->txid,tmp.buf,sizeof(pod->txid)); copy_cJSON(&tmp,cJSON_GetObjectItem(json,"address")), safecopy(pod->podaddr,tmp.buf,sizeof(pod->podaddr));; copy_cJSON(&tmp,cJSON_GetObjectItem(json,"scriptPubKey")), safecopy(pod->script,tmp.buf,sizeof(pod->script));; - amount = (uint64_t)(SATOSHIDEN * get_API_float(cJSON_GetObjectItem(json,"amount"))); + amount = (uint64_t)(SATOSHIDEN * jdouble(json,"amount")); pod->vout = juint(json,"vout"); pod->numconfirms = juint(json,"confirmations"); if ( pod->txid[0] != 0 && pod->podaddr[0] != 0 && pod->script[0] != 0 && amount != 0 && pod->vout >= 0 ) diff --git a/SuperNET/tools/common.mk b/SuperNET/tools/common.mk old mode 100644 new mode 100755 diff --git a/_API.md b/_API.md new file mode 100755 index 000000000..e69de29bb diff --git a/agents/.tmp b/agents/.tmp old mode 100644 new mode 100755 diff --git a/agents/field.html b/agents/field.html old mode 100644 new mode 100755 diff --git a/agents/footer.html b/agents/footer.html old mode 100644 new mode 100755 diff --git a/agents/formfooter.html b/agents/formfooter.html old mode 100644 new mode 100755 diff --git a/agents/formheader.html b/agents/formheader.html old mode 100644 new mode 100755 diff --git a/agents/header.html b/agents/header.html old mode 100644 new mode 100755 diff --git a/android/Android_Readme.md b/android/Android_Readme.md old mode 100644 new mode 100755 diff --git a/android/include/curl/Makefile b/android/include/curl/Makefile old mode 100644 new mode 100755 diff --git a/android/include/curl/Makefile.am b/android/include/curl/Makefile.am old mode 100644 new mode 100755 diff --git a/android/include/curl/Makefile.in b/android/include/curl/Makefile.in old mode 100644 new mode 100755 diff --git a/android/include/curl/curl.h b/android/include/curl/curl.h old mode 100644 new mode 100755 diff --git a/android/include/curl/curlbuild.h b/android/include/curl/curlbuild.h old mode 100644 new mode 100755 diff --git a/android/include/curl/curlbuild.h.cmake b/android/include/curl/curlbuild.h.cmake old mode 100644 new mode 100755 diff --git a/android/include/curl/curlbuild.h.in b/android/include/curl/curlbuild.h.in old mode 100644 new mode 100755 diff --git a/android/include/curl/curlrules.h b/android/include/curl/curlrules.h old mode 100644 new mode 100755 diff --git a/android/include/curl/curlver.h b/android/include/curl/curlver.h old mode 100644 new mode 100755 diff --git a/android/include/curl/easy.h b/android/include/curl/easy.h old mode 100644 new mode 100755 diff --git a/android/include/curl/mprintf.h b/android/include/curl/mprintf.h old mode 100644 new mode 100755 diff --git a/android/include/curl/multi.h b/android/include/curl/multi.h old mode 100644 new mode 100755 diff --git a/android/include/curl/stamp-h2 b/android/include/curl/stamp-h2 old mode 100644 new mode 100755 diff --git a/android/include/curl/stdcheaders.h b/android/include/curl/stdcheaders.h old mode 100644 new mode 100755 diff --git a/android/include/curl/typecheck-gcc.h b/android/include/curl/typecheck-gcc.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/aes.h b/android/include/openssl/aes.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/asn1.h b/android/include/openssl/asn1.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/asn1_mac.h b/android/include/openssl/asn1_mac.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/asn1t.h b/android/include/openssl/asn1t.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/bio.h b/android/include/openssl/bio.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/blowfish.h b/android/include/openssl/blowfish.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/bn.h b/android/include/openssl/bn.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/buffer.h b/android/include/openssl/buffer.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/camellia.h b/android/include/openssl/camellia.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/cast.h b/android/include/openssl/cast.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/cmac.h b/android/include/openssl/cmac.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/cms.h b/android/include/openssl/cms.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/comp.h b/android/include/openssl/comp.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/conf.h b/android/include/openssl/conf.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/conf_api.h b/android/include/openssl/conf_api.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/cryptlib.h b/android/include/openssl/cryptlib.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/crypto.h b/android/include/openssl/crypto.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/curl.h b/android/include/openssl/curl.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/curlbuild.h b/android/include/openssl/curlbuild.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/curlrules.h b/android/include/openssl/curlrules.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/curlver.h b/android/include/openssl/curlver.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/des.h b/android/include/openssl/des.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/des_old.h b/android/include/openssl/des_old.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/dh.h b/android/include/openssl/dh.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/dsa.h b/android/include/openssl/dsa.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/dso.h b/android/include/openssl/dso.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/dtls1.h b/android/include/openssl/dtls1.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/e_os.h b/android/include/openssl/e_os.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/e_os2.h b/android/include/openssl/e_os2.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/easy.h b/android/include/openssl/easy.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/ebcdic.h b/android/include/openssl/ebcdic.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/ec.h b/android/include/openssl/ec.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/ecdh.h b/android/include/openssl/ecdh.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/ecdsa.h b/android/include/openssl/ecdsa.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/engine.h b/android/include/openssl/engine.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/err.h b/android/include/openssl/err.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/evp.h b/android/include/openssl/evp.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/fips_err.h b/android/include/openssl/fips_err.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/hmac.h b/android/include/openssl/hmac.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/idea.h b/android/include/openssl/idea.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/krb5_asn.h b/android/include/openssl/krb5_asn.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/kssl.h b/android/include/openssl/kssl.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/lhash.h b/android/include/openssl/lhash.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/md32_common.h b/android/include/openssl/md32_common.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/md4.h b/android/include/openssl/md4.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/md5.h b/android/include/openssl/md5.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/mdc2.h b/android/include/openssl/mdc2.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/modes.h b/android/include/openssl/modes.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/mprintf.h b/android/include/openssl/mprintf.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/multi.h b/android/include/openssl/multi.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/o_dir.h b/android/include/openssl/o_dir.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/o_str.h b/android/include/openssl/o_str.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/o_time.h b/android/include/openssl/o_time.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/obj_mac.h b/android/include/openssl/obj_mac.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/objects.h b/android/include/openssl/objects.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/ocsp.h b/android/include/openssl/ocsp.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/opensslconf.h b/android/include/openssl/opensslconf.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/opensslv.h b/android/include/openssl/opensslv.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/ossl_typ.h b/android/include/openssl/ossl_typ.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/pem.h b/android/include/openssl/pem.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/pem2.h b/android/include/openssl/pem2.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/pkcs12.h b/android/include/openssl/pkcs12.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/pkcs7.h b/android/include/openssl/pkcs7.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/pqueue.h b/android/include/openssl/pqueue.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/rand.h b/android/include/openssl/rand.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/rc2.h b/android/include/openssl/rc2.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/rc4.h b/android/include/openssl/rc4.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/ripemd.h b/android/include/openssl/ripemd.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/rsa.h b/android/include/openssl/rsa.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/safestack.h b/android/include/openssl/safestack.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/seed.h b/android/include/openssl/seed.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/sha.h b/android/include/openssl/sha.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/srp.h b/android/include/openssl/srp.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/srtp.h b/android/include/openssl/srtp.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/ssl.h b/android/include/openssl/ssl.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/ssl2.h b/android/include/openssl/ssl2.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/ssl23.h b/android/include/openssl/ssl23.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/ssl3.h b/android/include/openssl/ssl3.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/stack.h b/android/include/openssl/stack.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/stdcheaders.h b/android/include/openssl/stdcheaders.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/symhacks.h b/android/include/openssl/symhacks.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/tls1.h b/android/include/openssl/tls1.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/ts.h b/android/include/openssl/ts.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/txt_db.h b/android/include/openssl/txt_db.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/typecheck-gcc.h b/android/include/openssl/typecheck-gcc.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/ui.h b/android/include/openssl/ui.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/ui_compat.h b/android/include/openssl/ui_compat.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/whrlpool.h b/android/include/openssl/whrlpool.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/x509.h b/android/include/openssl/x509.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/x509_vfy.h b/android/include/openssl/x509_vfy.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/x509v3.h b/android/include/openssl/x509v3.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/zconf.h b/android/include/openssl/zconf.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/zlib.h b/android/include/openssl/zlib.h old mode 100644 new mode 100755 diff --git a/android/lib/libcrypto.so b/android/lib/libcrypto.so old mode 100644 new mode 100755 diff --git a/android/lib/libcurl.a b/android/lib/libcurl.a old mode 100644 new mode 100755 diff --git a/android/lib/libssl.so b/android/lib/libssl.so old mode 100644 new mode 100755 diff --git a/chrome_extension.sh b/chrome_extension.sh new file mode 100755 index 000000000..812ae85eb --- /dev/null +++ b/chrome_extension.sh @@ -0,0 +1,67 @@ +#!/bin/bash + +echo About to create a chrome extension +rm -rf pnacl_${BUILD_NUMBER}.zip + +mkdir -p pnacl_${BUILD_NUMBER}/pnacl/Release/ + +#copying required folders +cp -rf iguana/css pnacl_${BUILD_NUMBER}/ +cp -rf iguana/js pnacl_${BUILD_NUMBER}/ +cp -rf iguana/app pnacl_${BUILD_NUMBER}/ +cp -rf iguana/confs pnacl_${BUILD_NUMBER}/ +cp -rf iguana/fonts pnacl_${BUILD_NUMBER}/ +cp -rf iguana/images pnacl_${BUILD_NUMBER}/ +cp -rf iguana/help pnacl_${BUILD_NUMBER}/ + +cp -rf iguana/pnacl/Release/{iguana.nmf,iguana.pexe} pnacl_${BUILD_NUMBER}/pnacl/Release/ + +cd iguana +find . -maxdepth 1 \( -iname \*.js -o -iname \*.html -o -iname \*.ico -o -iname \*.json -o -iname \*.png \) -exec cp -r {} ../pnacl_${BUILD_NUMBER} \; +cd - + +echo Listing the contents of pnacl_${BUILD_NUMBER} +ls -al pnacl_${BUILD_NUMBER}/ + +#echo Zipping now +#zip -r pnacl_${BUILD_NUMBER}.zip pnacl_${BUILD_NUMBER}/ + + +# Purpose: Pack a Chromium extension directory into crx format +cp pnacl.pem pnacl_${BUILD_NUMBER}.pem + +dir=pnacl_${BUILD_NUMBER} +key=pnacl_${BUILD_NUMBER}.pem + +name=$(basename "$dir") +crx="$name.crx" +pub="$name.pub" +sig="$name.sig" +zip="$name.zip" +trap 'rm -f "$pub" "$sig" "$zip"' EXIT + +# zip up the crx dir +cwd=$(pwd -P) +(cd "$dir" && zip -qr -9 -X "$cwd/$zip" .) + +# signature +openssl sha1 -sha1 -binary -sign "$key" < "$zip" > "$sig" + +# public key +openssl rsa -pubout -outform DER < "$key" > "$pub" 2>/dev/null + +byte_swap () { + # Take "abcdefgh" and return it as "ghefcdab" + echo "${1:6:2}${1:4:2}${1:2:2}${1:0:2}" +} + +crmagic_hex="4372 3234" # Cr24 +version_hex="0200 0000" # 2 +pub_len_hex=$(byte_swap $(printf '%08x\n' $(ls -l "$pub" | awk '{print $5}'))) +sig_len_hex=$(byte_swap $(printf '%08x\n' $(ls -l "$sig" | awk '{print $5}'))) +( + echo "$crmagic_hex $version_hex $pub_len_hex $sig_len_hex" | xxd -r -p + cat "$pub" "$sig" "$zip" +) > "$crx" +echo "Wrote $crx" + diff --git a/confs/BTCD_hdrs.txt b/confs/BTCD_hdrs.txt deleted file mode 100644 index f455c5c1b..000000000 --- a/confs/BTCD_hdrs.txt +++ /dev/null @@ -1,1772 +0,0 @@ -885001 -0 0000044966f40703b516c5af180582d53f783bfd319bb045e2dc3e05ea695d46 a5d211145f8e6ba0920b2893d307c5d7c207ae0800a80955299678d1706ea8ac -500 000000000680a9a697eb71155b18a5827e0889fca28afb81fcbb46469ed7877e 79f80a8f54c6762d6408347c6dd7dfd2f8b8c191077c1d7881dfc5b7ec6a408e -1000 0000000000000cf908c887020f8970b7fe952f8b81164d83a87621dfdb581d08 3356ec4296ff2f04281492b0dedbaed80edeb6dd9170b87230ff79f6b0daade7 -1500 00000000000010e39eaa987e695caed67aa0f3c33576fd2621422c7c09152ca2 e9d31ec9f5dd4dc2688791edd4cd1abc964a7f843c59b948903c3492940e459a -2000 000000000000029e318c44be8a5e1d5bc8f7823907bad160aa63fd6121dd0ba0 15e2439021c4563c7eab5b91c916a0c9c24c3fb374b49ea24a4e2aec241ab099 -2500 0000000000000b813b136f623f85155cad3069031cde918b4079e907e1a9fd58 76ef339392ae45dbfeb2c6263e4e88b4cf888264d7ce8d0361258a81061fadb6 -3000 00000000000000e5ac27d3bb729f5c8a4312f69b28c9cefbb18b8fb55ee42c87 dee1d4ef373897e52847416837485706f5c0fe29245eccb0819ea5d32f594051 -3500 000000000000123b4e50db3f3706974f7e3593c2897bb545177d5c8a5a11fd35 75c65538d4fd33e5a77d5b9e5d756587f45a7cdf55646f1cd72f2da2b7ae5772 -4000 000000000000013e3c1513a7ffd71ba89d7440fcacef6bb39a76527815a71043 6ca70d4bd86a4dabdf5312a88a99aeb874d851df717879049d8d91b464109adc -4500 00000000000006e6d70e292394dd1f4aaf1ba3ea7313ae981a0b2f38ec4b0503 e97f1c03d9e0445a00c160c648d2f4920845502e788f5c3f2a5a392544e18d0f -5000 0000000000000278ac01346559ded91fc585defc88bbaa9d7f111b199e516779 45f12a1790418c3e9000bca11394719138f398232fd62ed3c801b5eb1e9199c5 -5500 0000000000000284e3d2455f09d9613ff71c49144823f882b003ed3177c1abab 149ab9c582053c69b64d9b3c3041f04527bcd47c572d600947d0f737d675f953 -6000 0000000000000bd43190ec79e54ba203c9387abcc8c1c03c52452a44466f24b9 ab0f1f81aaf4000295bec7b21ad5c272aecf7dee60c451bcbfafb0beddabd2be -6500 000000000000029e27c331ad9865fee87dd19e5ed0e526f9974510649616cc1b 9ee7b5e21984f8e3ceaa88aba5ab2d88dda10cf28c57b826e3bc8401d0bac0cd -7000 000000000000034bfd6bd049678a41563af84a9581d1ccaeb4952c954e327918 e09213923b66de743cf8edc0389ab1b6c07c0c79a175b3e93364ed73c2efeb69 -7500 00000000000003c5a246cab977e3f339041bc95aec5cddcc3d459d3d2cd546a7 4f26360f00347667d1c2f108ad3e2b2f599a599cb77b1ba9936988664ac53d4d -8000 34d2ddf9aa94d6e02224588d3d6585028a22f05f53529a19a202f41ceb36cefc 8bc3244b74f884ae355598fe0200a7f09bfab53de1b3e122020c4e2daf08fb63 -8500 87ddea52f5073e5283ecaf0efc637da3a47986396ad30b3adec8ea2ba5f6a09b 65ae81f7094626494fe8b984141c265f689f4d6abd33a3a74eb491c31c5d02eb -9000 000000000000016845387841c3d5a584d82763471d4b84af3921ee2832715e4e 11b2851886bc2208cd41c8381ff7bd6350379f6c0224f9608450fb0da56a59d0 -9500 e64e3a10f2daca17836d2bb5868e76290da1fd3e0574da496b06182033fc70ac 5d6ac130a3a5cbbf28cf389cda08aabe9cd5bd9a4da2d0ecd19c27d9ab2320fa -10000 00000000000001634bb95749a866092348aef266f9169c3ddbcf226d4807ba09 986b59e97d259c74881bec99d68adad8e219a0fcaaff6af3fa31b0b5a89e1b33 -10500 9a98c541a5e55bcfc8eb6d887d83dc6049a33381fe0aa3f4766006c1fb066905 3dc29b2469167c07aab94fcd87c03e0bad1a99d47c3594d80b700b05190eb526 -11000 54bafbe72c3547248f553615eacb2254fefe5a4d4cdcc66a2efde3e1ad9f3354 7113b80a2fd13692c85f39cf494ba0d30285981b4829caaa92b4b748df134346 -11500 9d6f0308699be5bed63c54a2518b7a69aa2e7f5076202ec077d3d53159b291e2 32f1b2236a56fbbfac8b1a72e3e3cfe24531bdb2c38c2619828d11c1474df677 -12000 00000000000000734778db2ce455744e1a50745ff4d10ad3d787e49c9c2913ba 712f312d18d3c817c33e522dc5b7b50b9a16c0dbac13e56ce817e8b6d7f75ccd -12500 00000000000001209c8fe742d1a45c5fa9689f8622217ace049fa3864ae24321 0c4bf64e0024dde945ddad558a13bb180d931ed8d6ca79c13112a154db415794 -13000 0000000000000064fade9e75fa24d1d1974f5ca69e84e8688ef0a58b9dd2dad2 b3411ebcf6385fb575beaac292c70d4e79686d832d6138ff3b68cac8fb8e96c4 -13500 000000000000012cdd1996be2f29e14c0654b11476e254e4ba4c6829c6887ac6 054f36fdd7e83ed836fa5c6ca63ee54929fe3549b45da07a1efd1cbfca73188f -14000 00000000000000b930521b5956b17943d5dcf001b4d319ba7157bd7fee6a6fa1 80ed5287e00bf627a20e525cacd1b6ebc2077a3e2c71a400bec64eb7b80046f5 -14500 225abc3eacd079cc0949cd8d0eb8978b5bb00720da7178ef5652e70754914d88 c87e7237cadf805554ab3f259bc89eecda51149fdff0ffb29925712a218f76f8 -15000 000000000000001f08d59b246a225efd70b813c3df8e468bc9d99d7d686fedc6 2ec038bb14816230448f041cae3a9ab64f4e237a53cdb0416dff8a2e062586b5 -15500 1181e59d86d7026c523659c152db3732c69e56a04ead32a0617be36ad3f2f0ad a2511b8ee2e0158dc668e0de527e71455b7245c01f41ad66e296118715aa33a5 -16000 0000000000000015155b08a0f074b1ae3c960bb90e96549a16d0b3eb20a4353a 05409419f76edb4ecdaba62aa65195063865344c93cfa1e35bd41931201830dd -16500 91d0e76a759d19aed57d2657cea4dbe861e849b57602a4c5c69028d24f795fb5 767a41f042292ccf2acdb0b91163b18dd6b59aae25ba60a8557a01f02a5db8d9 -17000 000000000000009f949c3d1a6eb1d50cbe5a3638acc49987902526df0d4c3eee dc090785300641d04d64f572fa7d645faa11c4677d74ff356bd8d51f50c0517a -17500 00000000000000376f6a1ca86680e16d0127507a1182507e502c6cb85cb6719d 89dd74d7a8b4f5ee127e7b4aebe54f4cb2c91c79fbc3045a59e5f94227ac6b12 -18000 a02b59af01d4fc762d8a5708b22be769b7ef651afa88ecada21eec58dfd53cdd 42abadc5ef27ee4c954518ed1a1e865a3b2bff3683baad8fb35589f8953ac5e4 -18500 00000000000000dc2e6182da1a35d916b98a4778fc35c50de27a770b9f63daeb 7a44c2603b3d31b23a607a40cd63f9ce9486a7a3de507bb26f6ad7c1e0e75466 -19000 00000000000000017207a368616b26632bf68e16984c098be64d2fb064d3a2dc 190ef6e670cda631380598333765702648c55bbc0c92d68d3c2bb5f76bc546d6 -19500 00000000000000ab3d7e8810b7ca9f8b61f630ec6e596ee105cbeffe80c41d4e 5bb4af1b5c912873e90a93c0d2c998b367768f05fa8650246bce8dd4e8b5f0a8 -20000 000000000000003adb97f0d6976b906982f3272ae0d656e1c593406b05bae17c fdf85ac01a396b796ee5dfdf3c7869dd3f7eac36a61bc7a30a5c7e8a9c5dea1e -20500 dabee81d7aeb87b59d94c497ebe1552b3f5a5ee1e366ce64143e9fa426a6462b 017e99080b6064d5f8852f6cda7563f8bf299dd15370a64ac74f89f22bb42220 -21000 7b549feae0c08f58c44ece421b89b0626d15547fd1199ff172704a51476e17a3 50e176972bbd1528d333c01501e05baf97876b8a51030cc3dced40c1bfd852fe -21500 4d7df2acdfee2592ee66f6498c2b0de972ca6e0c8e2ab38eb641dfbbce8aca04 e10aafa5c02a56181cc6ed4b48ddf1a52370d95c99678bcf5fc6a106df343bd2 -22000 1f2cd2094e85ba89286a183da2b9135d94b2be2c5b3f31bafe89ab3f631c5791 b97f1ff53a6a11d6ad3b0ff270ed2bcf70500069ab5651b8466110d472a1651b -22500 e797c4b4ed2720b494a3501a32a247f7acc38f526245ff89c8f148babbbf0cdf a5b1353f344534e8a9ef6365be58040355391297cde74c723c6a5465e39f727d -23000 50b9f76effc822c9f1051b1c0ce25bba6112a31d32a055520d84ca0f1fc39b8c e12e33c6b273416adbf598ccec93ce0dd6a3fc817c6f8e4753064e9ef78e89a2 -23500 fcf644a9930ec30bb933cc37061a17d0edc29bb16a04ea4bbf8b27444d442415 d5a23580de1505a7df77130fda147aa774abfa1f16468a55b542f69bb6199019 -24000 144f4d11b3a867d17560ef3ef04362efc715c89c30082882df0692a214cdbd75 add23a1feaf6ae651d6d322142bed5998f2d3345fc767082817ca86139d2de71 -24500 8d8fa5a290cae00be37053ee99cf2ae70b37b4806b41575a09b7a948545215eb ce758bf937c83d93671078985a70493b6bc1ab33e680143c6e93c2c5aa3674b6 -25000 b5c67f326ffd5481bdd18f140c03ac34a9d467bee8116c7a559a8777c688ee18 2e618ba056f201573ae6222928d56fc3321a3b16c32681dcba8c07587ce581b5 -25500 80d41cb90ce050cb9db84205aad00db5761a465b000b8b3a74bdf57e7bc272c4 fa5e727492c4a83fe816724e80c54ef2add090d60c3fdd788c44721b67331726 -26000 de58126ac82bebb58f841f75602b4307ceafa0d9aad7271567ec69d734b3422e 3931c58b417157cbfa4e990ceb75e8f2aaef945922962b671c17fc9076be9c7c -26500 857f050c1a4a323b2f9d808bf2da8e11a9d691517cb0189ed2f7f103794bcad1 a7ea3d0c368fe526c8a1a79c9ce3b5cba52634c324271b3982c70e2ec1698800 -27000 43b14fcd1424ed78b3cf03615ba16c8fdb53c414e894a6fe555b5a0221053ca9 6719c5530a1c6579dc00a6d6bc26c59900d5437d4bef8d03fc47cc018937a52e -27500 503b22cd2997d3ff79a7857530f975798fe48a3b46bad0a38a3f83653beb8d1a e013d7f398f337d83d758e6af4eec6ecce14d080ab95f037e8c4354b1e4265b3 -28000 85e03383bd64b7cde88467bfd7973ad219d635708a69f925316e958d524c1b2a 112902560ea7fe15351297834affe49c0a8e768b587d1a8e6574ae89903d8143 -28500 57c1ce655a20e5d4639e934776edbbc5ad099c383b62c7bfc623368a2c3368a0 c3e03e5754ed76153656787b565a0143d538298277c55ac0ca79e99b0ea134ff -29000 d9963c1d22e68c2492bef7a33f34bb7bda7b326b4256104ac1ef7d6421862c5b 91dce271c5fcec2b60e9e9a7d1670f191be7f8e76d3d13e75eecbad77dce8173 -29500 43f543efd477664f84ee78bac095d5413449e552ef90204f79bb8463ecbd5e89 4e93e04161f98d745707c6c7a85bd4b223f124c6dad64aa7080dc612526329f3 -30000 23da6267be7a1511a4f9892875bd61bc1ae5d1b35063d78a7a448379db07c40d 760c525285ec0731ff71deed949476248fde392c8bb15f100af786b7d7e60642 -30500 199d170a784a96d70fd6421057653141b423cb730e577bbe490c4d9d5b31621c f836756815de2b187d68e2729bc667522ac6f00379759c5a7815c728d52fdd6b -31000 a2f6774be3decd68c4fc0d55249a61d73333358b03a5d7f48f19ff53c6eca193 a72c7c5328570231dfa7e3b7fb68ed42e4b4f9f4e05505ea4526779d279b6045 -31500 ead2b784815b474f24a12e57068086c7cd2b59051e4570eb4eff43c00079120a cdfb920e73fa2ab6278a84292a23123bc921782c7b9648c137ea3b5d936838a8 -32000 51690f90531b33b61489e34c805c7d1235708691163d0b25a9afe161b5bde918 44ba77a723c883778528e872d4cc6779c6485e4274ceb2ee7c1f219274c74297 -32500 b8f881e8f20864ef1db26eccd81bc46ce2b5dff8359ab86cc0b915bd6d1437e9 f390ac467135ddb1d88617c29db574c34ee51a4a79cf041bf7444c522229f8f5 -33000 8c8c61289e79ec3e22d294ab824743c29194740fca09ab44d460291599a33186 24bf35eb0ef662470b75fe38c332729ec8cdfa122a52be3d81a97bb9cad009d5 -33500 958755e9cf4e957d0471cfbeec0913140759fb3219aa74096c26cba2536579ae e88ae01956031b06310eb260b95a76e2e4e9b66d40df56300ecf108cb4579c4f -34000 d4effcfa7746bab24f9c3d12bf94680770ecc8405b5b0a17bfd0b33c2f4f475c 9e5f3f87097c229ec5011c8ce05cc12a81dfd166741ad2762a0f156a8d3b3928 -34500 7f971e1a0d2e94dd8cd0ccabc451fef38429ddbf2400bd45278fe000210d5f87 8b08d83e6bebcb12ae7b2b9fc1de91a0566ed33f2c40125d7810e2a97566a28a -35000 90e4d16dd67369b4b5795571fe0cfe63be8c1796ecf5870cad20798a752d92f2 619428a018aadf7a144b3981ecf018bfffa7975819a58cfc0e16f9ef0ba274e9 -35500 03aad5e354d5019e2cecb5a44c4ab79c7120543370cce9830b1d41590a59706b d94a9fa2f0ef62b409348c56bc376733e50fcab89ecd7fe711845f66c03a8409 -36000 5659c47e9c1b006ddb991b7b0163777977d04d70b4b52f4e3b87bc3aae6fba2c b1cb79822ef346bdfbcaacb59b7a289bd07b5cc02c8c6f9c9b1c5d27111c892b -36500 166c22d2278b5d4960af665a6dcb8c4718ca3c489fb12f6744a60337a6ea4a97 b55d2820c96584bb049d4f57766a2fb7b21ac2998038d1dad3c39dd553309a5d -37000 0c73b35172fd5a08dad4570ade1ae552008a801be8f2df85e52ae71957cc8bf1 66fceda7365584ca4e28a192d4716cd0bc61da166e5c6036bd2dad1ba0f034f2 -37500 e25729880903dd4f6562deb2c3e076c00d29e08e9c531518b2920b3e747ba6ce 886750b60b53c72b8d9bd1cf744d74fd3947ea62b878fd186618a46f1ae114af -38000 fd1aa8f0791fca7ab540a37b8fe5a6a23a84d0bf372ee35d6b12fe540b53f746 3bb81e40ce808ad93fd0057fe4c8c111478857f8ee143a27383a4d64f7c9cce7 -38500 73dc7035d76f11e288a04b87036996efbce8dc6233d00a1238f40ccd95a4ddc2 b8f0d99842fa481e5b0e6011ddd8abed25c9073b259e37ee7bf2f451d4ad2c92 -39000 f0e3715e1a7b82521f8d39fb490f261c5b8684008f5b52fbca7e5f7b204ddecb 2851428725cdcc924d42f907200a50ec708342cc1025ad035dbd7f84c0818340 -39500 16693e3a20a6c2d2d823b7c3020af1a20d555401ab098f94ea8a83b7a2a9af4c 400ac0ebe9428f526123f90c8bccf69a6835ad322affdfcfda314ea795e1a1b1 -40000 fbe5242823fe378d36335366cf45b3309e8fad0df3f9dd542e10eab3b7a296fb f73a533f1c917595a88ca8058bcf54b2d8e3c8cf8c46a165c84ef124fb07d15f -40500 448e82eebd5d00a7ed11123f43f8ee955790cab17cfad0fb4f1ba154b20cd1d4 f6c092a7945bdf4ce8bbb08645a349b208b054925376821f469309fcf46cb4de -41000 42e29e0fc3e8fb2c517bf4b7d24175f7467980d793bb18d4b1903fec0292d0a0 b8d88a3f3968b88b98e51232a0304506821c7c83f405515d2acf89a6a39a7048 -41500 fce90b09826a8120907462a95aef4b8dd9487efa4b0b2cb7e90a4d6d3d40e4a8 2a4319200375bf38a272bba432cb62054c4863db024e4a30c5bd20bdd569b939 -42000 f0815d389fe88bfbf5c361762efc5bd1264dd9256bf895b8dc6f39128e130154 b26d951f8be8ab9091f1e6c56a539d1d7a01b50c265ae1c025b698f3edde5b6c -42500 97171a32bd838c19f12586fb03992387b4b4c8d1342a0ddf3397e44b7c9b432a 04737e3fefb938c73100a32ccea93455aa0a564e41e608a1772ffdd2e0d10033 -43000 a1ae4df09a7e3f060a6693d9bd75af599a658f501b0a5583442aed2bd0393dff b6290ff23b70623802b15c12dfe3e19111ce081bedd2f24a0c6b4ead9d8989ba -43500 85e2d7b7fda1433ec964d4ea6cb4fa7af661d38f761877bb9b0aa0acead5e437 8dcd8aa4dd692a271a4e6efe7b8314f2fc5adc4b96bdd932e2ffe76b496f1347 -44000 7526450969b0254a66686dd28d61c10d0bffafd0bbb623d0ac71f6c45048b195 7c626106e228c853ba6d6c9d63f934e51661ebd7ecaa02d66608bc2f1da0877e -44500 313c4a7250c92bf888dbbbe977f119854876d877cd7ebad97da3e793e4167084 e1da8d161f08c6e7cbff74ccfcb80644b571747988ada991c4982625e59d1a0b -45000 9fde3334234a707dee9c6a2e3ef6069a30c0bb4293555f59ac70ec398c818e94 987db78e383fd57efd0a1b0b0b8fe38c50dbcd648da9a1eaf5d5f59d0c15235d -45500 30f5524584e0e3016ea738b1984cc7fdbac63956d6a154ac474ff28c873eaf02 2a6909db1ed2d684bae8cacedac0453a13e37ef1485760b0ef6329228a71bccd -46000 b79943e9ccbd2513710f58b3a5ac822bdcd6f390afc8258ce7fa1ea6822daf2c 1db10c590ef1fb219c3b98c707fa294e263bf95a4ad26c2c214ebb19d4236297 -46500 9680afcbae2cdf4712605c9d592ddaeb87f9e8c522c6b5f0beb219e71de389b8 75ab5e40232ac575b25c0b892af025d5405aafe1f808551e7bd33abdca9a86cc -47000 1deba95895fa7fa09760b2b6f12395e6a40dc7ed3b14e629b7d85875e6913eda e735fd2aefe57540d02327e774c7069d08a3ec5b35e6ba939b1609d98a29a245 -47500 400b71a80cf5c7a408363c4a88a6f17b9fee56830f9639bf682cca7f6a1b9ef4 179f44d13af45605ea60c9fa6e0030b5de6c274104649283e5929abda3cabd0b -48000 b62fdb21ede8c1760346b4325be6d08852ea3944fb0adea0b408742977fe122a 8ff82f9540381a20ba68681f6e5442df8852cf38b2476d0a6bc61162d6eeabf3 -48500 baf6f61655d7a53726d313806841300c1d729f7206f62a267c1b4c351b365763 fde6fd7055e1f6e03b9d327b3c502fc02bac00738ae0fb079f128e2774d0078a -49000 854ab5b99aa89fc7d03f0b2d7f8a54aa7c98b23957520ebc8f4e6305902cf2cd f39213ce4a4fb7c2de3088ffcef3712113958562638395dcfda8ff6da621a09d -49500 c964b7057db84d6b9282baff7f2f09dd72fff06dec110201904bfc3846923bdc e2c15ad8f20ec681283af4d88c56e1433c9c20ccbd11e269ea267bbc2f9ebf1d -50000 fab7500f5f0b1694a9c65a4b02e84dff228af92fa447d810200a3b14c35242cb 194fd02a69a66e9293a06d354206757e2bc23484e3e8cd80522ff71feffbdff2 -50500 ed4e556f251680672e442c00cf6a48f3a787acc589ef3e83019851808ffd05a5 b51a4252fdbf12378dae10ac1c94690365e096f786feadb8e75cbad87c8f8a99 -51000 2410005ccfce88835da97372f39ba6708e7eb10f97a4428ba2cd51e8ee87f7dc 64e4a8d5a545ffb1af7a5dc66be6ff2aa517a99c7bc5d7b2d1d1afafc1b93a84 -51500 ae13af1cc26f53deaa57482111239bd24f99814dae1e01580a1957f11aa49a63 4a0c54d391ad8bdc303e226fa1aca24cce0ba24370424396bec9917804f0bce7 -52000 163e369cecd2362ecebef4717e206124e3bd47dd40104efcbbc8610fb48dbe46 3b68edeaf66e8bf1e1b187fc0a5e0424b6cc896661e2a4f44882cb060f9815f9 -52500 c3e5334bfa7c8d5d577b1a74df2deb553a006f68b384ebd44eb7bdd7aca3a297 fa5cd9249e7b39e2aef8bb19e83e214d77a45b4c67c4504522f94baeec2241f1 -53000 3a790689d0f51fe7dd6115b7f0e5f5265a3aeb912692596d2611050a17795705 23b602a52f2e393f2cedd9c8ea0597931f6abd7b4f4f1d85f1de8d6382c03ec4 -53500 70a1da282b26b9dffe0b36a6dcdfc0c4bf218a86164adfbe7df4cc9c0b978969 f6ffbf0fc14817b41ce42831d14add2f8ec22307e5b6baaa9f07dad06c387e8c -54000 630d02d2f2a8889fe47a4c2235a60b2dfd31ca78e487860f59d24637a2032af3 901287c9cb47c082b5329f422d94e71def436bd0979e939e7def8c60f99272bd -54500 4943f865d3e75ddd060f8145558ec7f57c10d186b3bbd3d90377be4713e1fd22 26a8c618d328579faee0816d1d723736a249dda1e95647ce7775b0aae5b72854 -55000 6e96c77b0964fc2077455aaa2067110351212e2ca707fda778c963fbbddc844c 350612a0426a630a0b001ec51d875e2d1c87d20353a480539e5fddf91cb3097c -55500 cd718716c94cebd61eafac70f8562db8b48735765a8613aec79d901e0c5a05e6 234209073d425564622dfa5268e7f2af5aac71a18e2b15d23ceff1da4d876563 -56000 04002106ca4da32c5c7889c8f17369d23a35bce62a8196477c8f8e0e0dbe4efc ac25f2042536f1a588ac6747b2ff3b45de9aed063b096ea59632b3aa45441ddd -56500 6460fc580380db980f3b76e9480b2dd98f4fec5c9642b211f7258f50575522c3 12c289cc82037f732305d895742cb703eaa35a4656faf84c6f7dd9a2783cd2a9 -57000 7f1a59ac62a06df2d3d82226e03a1081fa9a8c72c5333ba485565f9215423362 5363e6896a5eac3c62543b82b6260a18b07597b5963d038e728a9508ab55b181 -57500 88bf14d568f5b9d8e88d27a92f2aa97a569f371850be3d6d1ec175fd9e1dee54 56aa31dfeccbed31839cc2399397a826f2e64a16c4fd309ba87ebb2ae7e7f695 -58000 0ab0e582e675d0ead1173cd65e71157f13841b22560251a2aace14ca86fd66f2 bb20d53b616962e78610b02a60785252e90c54d78f33a3578172cde77075a776 -58500 637d24d3f5e56f5481735d0853d74cc85c170dc95dba4eb733af11ec3ff048d4 aa8d5505be6a30af2a0292fcd19800b0744acd87634bc49ce43b0d767117a5cb -59000 2d88b4676741afa7b183502fffd15bb1580f81b4b8631844be86bacaeec0524b fe841a70acbed4f52a83b35cf30c0cd5ad38b36b21b24da1a0ead110f5e7b2fa -59500 e5b98e82ea2968293969b1da31bbb8e30dec3ab5cf10308d4a979e3264513bff 17429be3ddc868c9e3662b5aa6223340d57b7284138db428c725c8fe69e1f89d -60000 98764fcdc2a2f8a740a4a1c891ad966b44062f64195effad2ba0aa4bb9c4370b 55053a4d083f019f602ca159faef86ddf421c4c4c3bcef9f0849f45e1f8c1c44 -60500 24bdb847b0ae121363eb0d2a7ab69d672627b4d68195fee18df5ab5c076ba3ed be197241a0c377fa6982b5c24af043034024f889cd3ebe42d4a9b3fa5dd18953 -61000 54222686316d912f144e6d0bbaee1b3fa50549e9da65ffc21b04c5beb3ec6daf 6c5a388a8dd7f9d104377e1f5b2817b50f9269145da48dd0d71f48e2af8b8731 -61500 f14bee1d7d3830f8c316f448ca36fd0591371a63fb9d04596c657051ab4c2ff8 86c9232b738073c671adec011771072c92ed0616c361bcb6e9af6074d09bd6ff -62000 5903eccbe3d0442fabf30748705e88e9cd83128a0bbfbef66841f590b5011bdc 4de78ca5e16fc438337a8d5f7aefd2cbbc66790d019a1bbc5de082a79e39c303 -62500 35db59c0b059705518e07b3beab25716c9fa347a1fdf7bfa0089d011e2586419 961e208bd356ecb07f838ec1d1cba0eddd79d5e026ae350f0945cc321dec970c -63000 5fb6db58962ea9eabcc50dde4f473a0adf58eb9a409665d57cea3b2d3d2f44ea b673d848fb79ad142be92514c27dad64fbf98d26e1e4f5957376bcb2f8542288 -63500 92e31a33e15bb677aed01f2ed669a2700223a34fa7342270275561ed5b88eac7 7932d5bdbb9c2fd7f172a79a9e93f73aa3703c284afa98e7530ea4ebbb4ce7fa -64000 065c7297e545fd1739d04c6ed41da4a82a24404c7b3573bbacca0c266c4cb716 912632c93e91f5f539b2f9d6ff8b16a1817c8eca88b6d579dab56bf4d48eb31f -64500 a011434ee029b50acdd49262a91b0767a897a5dfa7f5c22dda0a32aca9ff334a 37993dc2223b292109f02e9eda7db4178f6602aae957b80eee7cf94dfdcbf020 -65000 5144e900145e481fb1e569b1b522143348a38052d35452dc7d97e2140b812e26 217530b550c589b0de7d145fc8b1059215bf5c124be7e79b5854acc200b511a0 -65500 6db49e04b2c1ed108caba28d4de98628fc786f5224b098de1636a697ddbd6e6c 5cc92190d39119982836cd5b0759902c4c61517aebaba16e6515cfca53bbcba2 -66000 559d2603be7835ec386467221e23836803606f7fcd7068f6a42ac5054e48fe88 68c9698e2684c3375d6b4d83b33155e15ff1d50aaa0fe61276a854f7c022e3c5 -66500 d724f78b706b6a58400a729586b050fcbe843a3e632376f24db6fd4cb9a44177 968a75dc8e7e9128b5e7e00b22a78fb53553102b54247bf644247546a9db85e3 -67000 8ddfa37cf395f7b4b8d6d09e29cb7f11e7d06f929d7ce7a77ced27c79011235b 9cba1d323704f1b566fe4b639737ca2f6f96ab6f9f1373d95e1d8cfef0a0a1fd -67500 2c5e2421936073eb47199fb03dc0023bf42572f507f484fd9181eb1a862e8972 4928ddef10d983dccfdbcce08743afe2a0d1238fd84bb4b6e1781ca7847d6ff7 -68000 cf49fb97e127593bcf3591390401803095f71ea86922369e573b1c6bf59ca692 accdaba238ebdebdf85fcb74a46d17e5c29a996e3f1be6147a3f6027a13c8412 -68500 eb68bd36c8212efaa20bcc2d1c17f17af6ce65b060ca7ef80dec2f44052defcf e04d8a45c474fb6ab8071cadd8fb14f5d208472089f6a22ff5c04904f7a01d55 -69000 03609399659eacd9b55c608e6f35195530a35358812bed13782f9d5df5da1ebe cf4d7449a4a7aebba820fc84f3dca2a48ada14feda094a425833d4a5aec834aa -69500 1d23b15a2484a71d270170f32918f36fb87e80cf4020f6a3e6d61907276fb3a5 2a218f285edae9995b3334352864684c66f4a919c92031ee3b24510b568f6246 -70000 5667dd2604c90cb15f49a75456b0bcc2a0098bc025592d48379f4360844b79c5 1b6966e82886048d64879d2b76663fd70689c7dee808cb42352f57af598f9bca -70500 745715d010b5ab51456342b8772a53b95ef0cd409980df39c443531f2f6c2346 a1ca05cd11e6f3d9eb2f0498b8a4743defe546c7602c3fe06642f0226cd22719 -71000 c622f3d2de9a6aa2d649f10532164082ff6ac21da796b037f2b2a210fd2910ad 3c24535ccd8328940b86980f1797d0c4e0dd0fed2ada72a0d9ce7927f4e3b040 -71500 c4350561b063c19326afb0b38b7aa70a65a928ecbe3a545f26f1dfba40d16599 7167266f09bc1b259fc6dc6ddd1c4e03514e4b4e5a985ce79cc320d80f376e9b -72000 df857691f4e2d2ad6a7de6a3fd77cd3e1ee19be220f7f92006e30c4cab62eb8a 1e962f15a4472d511bc049be123041f357376d95df56677c32ebf69640fa5459 -72500 affa0299a9d64d61176179cb14978c6dfd116b0350638b5e2633c5a73bb9e5ba b04e559b1ff6d04f2fdd2693c384bc89f05ee28f5ba8cee49cd057c575b0acf4 -73000 a50964b3523aaffcbcfd0be0a6fda32ceb87018450ad2ff81f1ba61de5fa20b7 e3301d1249deb8b1065c59ddf02c4480af9208ca0fe70f0b94f7135e3baed857 -73500 629acc1dd038725bbad7598fc49a7178771332ca4f12372248da579ee5dbbe54 8d2425646be01e20cf3554feec43cb91bdd92f0a6e8791c7f8fac4d21767b45e -74000 068954a253aa54239a0a4169f50ee7d37b0b5bdfcdfe9719ce9921a5917715eb 722bb617216427a0cbbaa037d1234bb7d6765707108aaf171cbe14e24392a8d0 -74500 e688640c22b3c55fdd29e86a159e1cb665cb0937cd6a5591730a1b5de7c04b76 4ed22bf35c9c19ccb01db47714af7f2ed0a7d2506f40a5e43b92b971edf62250 -75000 31c015b503c6830b93948a51598beefedc78d8957af82aca6ccedb2aa592de8c b75f99a073680d704089e1a77cca65d027722aee3a4fd7c1f9578b535150d5e6 -75500 3eb906d2939c3f6ad815a51421f488025326b8cbdbe28c15ef32ba410b7b8ab4 39ed4ea10fdb97d192dc03a86a397b24f6883439e7ff6e82d9e6738cb90ed5d0 -76000 d21f08b186c4d763e03ff71b1ae4e7c07a9dbd30c518242740c2c93119d8d96d 3898b748f911a413cf66daf2e319b3e72ad25ceddb77f56a7de9165484405cd1 -76500 5c8f54cbdc2f5f83621da3e57c28d8e19faca81a438cb5f4aa144a4c037a0055 979a3726654c4e3bc195da85f13e24639650c2d65c460c91ff1b377e27a3b73e -77000 e5e2e50e27fe46845384682b593999c03b4848a5912bb45d22974cccb551d125 75be98b3706894389661b6e9c20057b55cdabfa26ffd74bcaac8fc01ba273340 -77500 be8371eaee6d9fbf2c550f71e9b41d135201b8b4657b94e6660c908f239f986c 32b8f8fdb525510204119ba84666c0713d8f486328a98a130c166f36a2582523 -78000 2eff5feda9ab021f5afc380a7f931e7d52e7fe2ff3e2cf1ee7fdbde0eef82b64 65fbc737d459fa4f14f34704e11ecd9adfd51078f45626671bc698ae18d849d6 -78500 3018bc8d8b545e9ec88e936af13fee6bdf3ede83f61d2bab5f723803e53e0062 7b2380f5e4d64db1aefd218b868cc51902a54d0a0db42cefed99c7e8de87a218 -79000 b0c165f1302d8f19256dc2e278a7a5ecb99eac7c998306a50c8b4686a077356d 491242e8fb5fc40eb435f931bd11bc42428634a5b83abd1fb9f19059712b1ec5 -79500 68a1ec922af3091b3f2d59824979ab0f53a92198465ba557236cd41723deffb8 fb4a299d949b55ea78834906a69ab9022a49d8de653310369fd8ba9af477b7ce -80000 3b7489d3c34d0848f031a2325269daeacd8d00cca588b2b0155a81bf5bead1a2 9ec13567c8ceb32e9315afa4321f0a088d662f7853d492e8fea9aa0825f0c8ba -80500 a4bdbb1067263df39ae9c3fe98b7e436bfc29fb020ca4e0caedc4b92409cbabf 5d94d51295cffe3419841c9aa1afe3a281863f571789ded22dbee32e03726946 -81000 ff01efad3f1d35001246db4167727135f57b0e2603185bd8f43310d2725b4da5 41766254f9700bf8590b6bfa6993eb56e866af75377438b7b7ec4aecff1062e0 -81500 1e6d76e93daa7db4bef0b866414eb884b80193359343f7984cc4ad813f10a555 87b53a2233125cc8b28fa7fce0ed9d4030665fe83b9e63a76e545f7eaf332fd9 -82000 f77522692699eaa7adfa876193ff59d445443d55389e9110c211d4892d0e4501 a283d883a0705d2dba7c61cb45d6019a7e464aaaf297d8cb28103358c12e33db -82500 ce6f78297eeeaaae876c2528e2620ee91005af068e45c079f16523772b1ad1ab f52cb36181b62da6142382debe8325153fa672ea2a82ae0f4f1f05d3945ab944 -83000 fb926dce75fe0237ca38f35e58a77ce4ee8be04da61b16f360b029ccb889ff75 28adc102bd9b8be9013e2400e65d2d57750e995bce1b03ecdf1cee59712f359a -83500 f41912c2e881115560d9b957f91a8463c082efd4b887d3a9762fa7aa70d7dac0 aca22527fa30f5d0e0a8f2505a12fad648526bf7c7a0012b2ea02ecdf55b6fa2 -84000 04c39ca3103cde71f02315b339936f58cb04aafe9990c46326733493897f848e cacfdbf9b2ae2aeee8bfc355d807badb9cc02835889a999e93c14ea7800d54c5 -84500 5f40a8c35de9dd97ecd7244e84a895deb4fffaeadc22ed8d206d303578471ad8 e1c2dc0617f6e76b2ab84179c8bbc55c46d9732c6952beabec2d14babd7fd9c0 -85000 b181b9521ee2b12c19c5db467c39855af3e1f636a4086e1c6a728e2b45165402 8243d308e207fc44be4180ad0a63916aef3877e6278d30cb6f795d463541d26a -85500 b010687cf83e100f2d398b3927659ca342b25e443147badc9be5f13331fde93c c635b1e609f40f3bbd4aaee0df1ea6b27f18094f1d00377f69430b6507012e88 -86000 291fee34f060bf3d1c39be96f5ee8cf18c625515947c5495775924f5702abfad 47e1684b5b4942e0719228e060af33e8f13389619e91925d58f86408ea149035 -86500 bdaeabf298427c06e09a2e646e10ca3d17056bf1ba9619371327ccdb3f72c09a 4eda2aae345266db3c1d7f8e49699c30e70c8675735a83972d0dbf0db2372c24 -87000 8f8fbadad337ea15f63bc845e472d58d4c6467a516d77d08fd603ddb3b98d823 2d021df329f3c3bd4a39a5ecbae773b063f4baaf776f8ffb519b0fd4d803373b -87500 109c6f62e3aa5e0ade745ab3544f8d055d4ee1bf27d217bcaa0815f8b31118f1 1cf68acbbe94735132fe7929ae72e1fced6fc8cf569bfbc088a16c93c3e9e403 -88000 f46e00026587a254cd7a382218d9f2d61d37139d7c3c4f0ad76d35c76a2e8fd3 fc2e809bba17e3198bb92edc5999820f19a4d7135330b2f7b055252ab91f4896 -88500 a048c5a363aaf55cee60a2a4286afc8199b7bd0d57d5e039027d3db2a6cfada8 fcddf7448b220764d0452dacea67e5a91d537830349e307fdd20763143f92bc5 -89000 95e0fcbc78961eb79d44bd8e8055a26e77056036cb235779fe1ce22086a8705e 3454b0857e99663789646a938c33241ff00e4f7f853870665767bfe04ffce0bd -89500 8ed9d4f7f4c3ec8eaaa57d893a9464cafa4e2ea705756bc00c9b9719d51ee56c e836a5257dd6be6b167b7cf6c39b17a2433b07e86b2ceecc6886e57cddfa2a94 -90000 bd2cdc7f05511794992b0ce31ee8d58e428ddf12874905f102d2ca0a37adf8c8 e182353321678e537290c24a2a9c09d226ecd91044cc139038dd134ec1ef1a73 -90500 a996f4865ec304be3972056e4fa5890baaa296db692f4442c5b0b7337e75054d 98a91f31ee5cfdf960e1fcda3ff3d8d058471e2df6db7bea0e3937dd09baf06d -91000 f6cb4c4b3fe3b7365cd9e05f757498cef6da8eb0e6730f4c569bcd3700ba1d2a 91a792fa965f57abd8c8c95a37069682f68a3ad2112883779fd33fddf3cf7368 -91500 4421ef207f0a56fe208ecf3cc145cefe926784dc163500dd5018585c6bc4c0b0 2870e9bbe0c6ae16f66d6255485d6c6c5c198e16b7a721c0a027df05bcbb46d0 -92000 eb18cde79b36e5cfb7047d7ffd72374892d294d97b19965f67c264a42be981c2 77ce5943ff19145cab30c4b25f762f1e93afbb25e284388f88b4078fb934db67 -92500 2a1e0986047c363c557e0719dc464f44cb2a5530f36ead6455caf22579fa728c 3fc8941af430a2cbbe3a9e51ece9042410bce0c9eec2905109433485e8dc6eb6 -93000 759bd6b0b243739d3d6c28227f3a9eeca8afc6d341d17da49751065ff6d9027c ff40f2c094d151ad356ff66fd39eaed507a78f9d3c4ed2ccde744d600d3ee843 -93500 0c1648e1e670c38758befb41e8fc48f337f3b9c2aa8cf162c2856bfd44dfb4e6 e417032b5b7a38c5a9812822810148a15818047c2e8364ec0766a33cba25ef34 -94000 66cfc1f322a9971bc39ee18125a9464b9f82eef9c314670e51261402e50086d7 34ddac2e7b943cd760ed4863497ce0ba2a723bad5afb6f391082f1f1603c5a51 -94500 0bf23f1c069fc47b2289bf52f8462229a39ace7afa517a43a52276f5cb8a0f00 6d333049619b2fa4f612c1a6bc8bf82ab8a7db7cbedb51a258ea1bcc33b03f90 -95000 1781fded2a4d5a2ab054b04de3935c97fd5f535f0bd109496aab9abbc6564dba 18990d4e8be1e75e4e97a92e16bb4fbd805afa2d419629a5eec4d46a269438a1 -95500 ac453fe6cbfc81ed0c9b32241f121410d4caae7ab57c62ef99e08750f2d5f153 e3c4ea5da181b0fbd82e45e106a9c3dde36c28382093708d8cebbb72d001960c -96000 e464e4c5f135dcbdbe41de354730b1f633f00f458994d6ab3e7b272a5335e3b0 093f11b3784b1ef794fb06db18424f84c6a1bea0b9038666ac5eb0d36b18258d -96500 82345f602aad0d7ff796eaddddda22958f4d3c9c41fb987378947be6ee12f808 f6bb034032bc77c931558568182e10066932b5326940dfe562048d83dba4c126 -97000 eae3af1d8bfe6d1c40c118e0c78bae2bfb1800401d532b63a3c875fd3fc8a24f ea34ca2227308ab8818f085e7fefb2f140dfe9479558e6dae8c0dc049e09765d -97500 60dc3e9f055602d3673ddb11ab25d7c094057a0c71db2a327a491b3be93eb9a4 186a25fa3609da954813d575a4128ff890d571f0c003f0e6d62a6322279125a1 -98000 5124c9f250499786c2948dcf5e2be2c7c61b446be3972adbc0d65edc8ff87b0b 7f5892932cd29e78d17fda5c3d15bba0a600f1e9ec2281dbaf0fb1dc67d5e8dc -98500 6f507567f549b3b1e387f1bf80ec0fef03a9a1af73147dbbbae2134d6d1633c1 60d73750b6ce4d508dc18cc64adc9e68b6bb7ea4828f09e8fb7419b56eb652dc -99000 64999aa405a2a2e5de34a4c3547ee525b503566532d82c35839a9e74a1389ffc 20052d2448a28485dee72fe536fa8b6ffda1e8465af82491e87980c8f806c8ac -99500 3cd60a841f4913bfaf6183237ebd325b7baee3a5992f092118fa49817240a385 08f5df63fb4186638211b70120a165898891fdb195aa8a5b4e41bb0f9f0f16cc -100000 f0394d3c54a8687b6090333aa03f93f9369846e7c142653524adaa9192b37b7b a739c2cc2c59123a161c9b9864a4c834dfd5021066198f51fde3ba9348d195d5 -100500 c5ad61c2da15ed8083a3d3dfd80d226b9977dc831c11e83b75b3ed68d2af0e25 e3121bb1573ace63889a3fb9305fb95857bda6e889e9a88aa2ad4c76cc407386 -101000 27c2691b9e3e9cc2008da070c0af12d0997c895fea5c405347496c6a37570f95 d465e2fcce8e1b4bf7355b4d87445d2557336354b86db40bc924752796aca840 -101500 80c3bf7835d6a11fcaa22931aae51bbc602af4412ee8ec0e8b96c3a9c7128f16 1d7c3e519be3686c4b9f09708e225c8259c5ba6647fd78653b387539f58bdbdf -102000 52bf59cb7e10047df152f35bfb683611f084d444aac4301bd0284d3e458b6022 7c8226cd17af258fd69631ce4cfdf204dab70dcf93bfed953d6cf488d576f56e -102500 5dc7c42f2501c79ca5d610b8b69d408033bf0f7d16d036bea01e90e6c1ac9342 403edaea352b4da33ec3269ccbae23c226a39961f457e5d3f84b806e517074fe -103000 719c3b85ab62248c015de680a8fba158d0a336492668bc0b202ff9fae1b1b5e4 d90dede7a044e1b11ae429bd313e841c12e8d0303aa6626db4c953d198b0f531 -103500 fa0bc10bbd112c733022783fa67cc4ba045bf93115654e1f25e680595024ef04 e55422d2e8d2b8b6429ed85747a8ee57c549651eda0fcb2871ae5762862a86c9 -104000 e63af7f5547bf8bc2f36058a43569a30f7edd8286ce44ea561e63a3bc11ea7d4 939e2e2c30e66ae3b9077e947acda9b7dc0b9f326c55cef4e4d2e5025a0df9a0 -104500 d73f74f43bc0653041db94c60b0e68c194199041c830e4f90345c1dee78b9c23 d1b14fe1a0631af85d0da1b0376a93ed925248fb2c5bc47d4284832d40fa318b -105000 460580489a262514f5414c1fdc95ef0d8290a23bdca4af93fd226d72ca79bb11 11fedbb936fb27e227c2602d32f688f1d024a5fbc8d31823d273818ed142ae62 -105500 a461d00c1217d40b1774f631ce44e78c974be18cdefc160ec33e865b1c7805d5 24f67d2f822429d89701691d7834c58593be43e7249530a9c1dae9aa12cde4d2 -106000 70b95f002b31d55c7b523451d746df1ea1ab182f4e3d26a6a8146daa6b175f70 f59d284adbc90a549c211187c55814e85b8343c7797ade9c5f761e5b4c5855c8 -106500 5bcd8c94849d744d137dac85d734d893dea9963746e1d5adefc0852cc99c3c66 67b4fb04c0780ac951d84e6779fafa76dae5d46e84ef41cf690cd33392c6f926 -107000 aa50a7001438cb8eab4442c4635453881df972b8707150275fac0867d7254341 9e2451f91358f222b3934b24013be83c1fcc78415c12b4fab2cc5dd8a3d3c36a -107500 f83ed835545b9320da20a1b2961c285adf11dcde168619a3e7e746f93cb93cb3 e27c84ca437850f8aeb0cf3bd1a727caf91808663679f2dfca99f4c676a4cef6 -108000 d9cabd49da35be240bfaf8dc107e13fa3ead3029573f7711c51c874f09e2af83 85f41c365756daf80d25256a132c25ced262eefd77547a42a51603fb98f0fac2 -108500 e6f6bf4d75295e5dfff4f979fb12292736dfa7d4d8a7dc683f6238a4e00caf0d f294a30724f9d9ffcc244995acf528e501f6ffd0840f5ba8ecddbba1d1bbe250 -109000 154e12021e0e5198def8989a1d68326833d020409a76f980e4e41cb1662e0d47 2e486aa0080740653141a5219ef25dc79777d3976bd9fad1a7c7bddc2fae858c -109500 02a8b8fcee9f8a420ad024de30fb8f4b2db683b4f93e37d5a7936728ad1bc1a9 f9c26724d2d6e8398a66e8ac080c8aadfc5155ce4be3521b3ae5aff95fca7541 -110000 587654021f4afef0e863df85d5c48c1da57af439c890cd7c82f57112b523e567 41299bbc731c54c00252ac8506c5671a019c2f24117534a52a6dc243de19e60c -110500 1b144103a2729d255d2c79223dc4804e9ec38bbd07105eda2eda5d350933c8e0 47988c8a2b50a19d5c4cfd5c657b3bdb19848828866e762f5fe40f8ed3b0fc5d -111000 d2dfeee7017ce245109d6fd20d439a58fba318eb0853369ad740a4c7d8cb3679 89d0671f5c51cc5e682fde76759bf130bde74a8c3d0334013165cdc74df67a35 -111500 7bad9ae95d958cfdfe5f6f1ab0692c74023e9676aebf77696f0dd92f272484ee 8711ac67cfc650bcc9a9a3b170896959954dce728667035278b865e843c5f5d2 -112000 aaa6a01ee0e8be04b54950e9fc47308bea161476fd9e5f7d931a9ac7a177c6b1 cfbf8e1b380186cdd7dff5b1775e68857e0144a6cff5c699cda0df8a9b755879 -112500 856c253a4ff511cde2cd1138cc415c15fc4601a9cf20f97a40a3ed5a8e4bd28a 2418313d86bc12dd0b7ae5246d70c5c95ddc342c5f522d33a4faa38677b1cf74 -113000 d39c76ff2213efb6aaf21e1831e8dfd86e82851311214222cacd1065e5f442f5 7027dd65582113bd83834da3b8feb6f5e724156d8653689be02acecf664ed8b5 -113500 072de8c792fb777438dae0fe6605d05f84c05c478cf045595236439ed614c869 66e29b9bcaa1beaa8d901e8227510190b64b665c427147e79fbb03f4c7560df3 -114000 2727f22d9d9b83d232fb91cf7fef9923d998166a632e104da344aa5b2c33f963 afb687e99a9ef1e794a049e78417ff2b0a15bf3c0f0a01b5c04e381dfd3eced0 -114500 fda2f80a90dd787eb236d38096e1f73b7ee1b54d067c53ee62d4201004df7f96 434c6e214b4120e3df23c820dfbf7ecf3facaf2f30b55fcce4dc094d0d052ff3 -115000 f8642fb7ecc176c23e6919e2a5f9a3f69d60c1bf10329e853b94141d7eecec79 02a4953482c2887d0dc4d2980de20cf75b73ec8d81d5b3d6ca6df741a3f3fc7c -115500 96be8c04c6533cf914499dfa780622f64e3362ee67b888c3d187c7cd167c124f d160418c73e78f1f75972ff6fce579d50f936678a03b8e3e2e8eec885c8e7f97 -116000 6efc2af9311adf3ae7cefcd558b25335048a0344d0fcca48f4a8302e0c2f4e4c 5bd32d67887dbdc6482620b347a1ad8eb9c8d124ecf4e6966269a1ee537f7562 -116500 d2fca2b2bf347959eda9a08e76c269d1e00d475d90ed02ec7d5d537e542c648b 9476a9957e44fe4de208e4c707f0b6d1a2c0c0b3a32dabd912707ea86823f62f -117000 5ac65e76af1b75c9aee7eb49b22ff2fee88a1bda49287fc5dc7762b2c5b8768f d357d64072327f9db3d73ea738abdf89f5bd20ed4b56733bc9df37d200b6db39 -117500 3d7e8e1235d8f137cd5661125cc0627dcb3c18945254e9676e21f2a445ab8b9f 0f9c97626569303b76ebbd2cb960341f2297f69ae140cc84a40a83695993605f -118000 be2144efc3b4ccf0d4d3d7b66c5f6ba253d1fff069b89a69f8eb2cc4ff44fe34 9bffc6fa6a4cf35486018721652d5358be0bbeeef8b98398c9373c352cacd4be -118500 58ca03280dfb1e73dfe8ae35f67b60087586b36823e7fcdfb0509bed23c0f9d3 58ce09f4189a7f9263ee9292d7cafb880bb3676175c7553a04e25bc261ca21f8 -119000 907a0fea05eed4572602c76515bfa03d5cc79da72496d41d84afb4ce4098be07 32779d699cd1abba0d653a332f07727b9a2094a4149fb66cb11f16df7c68d34f -119500 ee7317e1516104041197ebb0bba085bb14932972d5bf4ce305a3bacb9ce17dbf 6c779c5b384b94c7649ed90936688e83762407a89643aa89f730c6c399abcade -120000 7105703f4cfd592d639e0b5bf6f2d25380a1787346f24331401eeed04f146130 2a44b6fc864aac66301c1b20def1cafb0704830fb07e2684651513a6f8a89843 -120500 1dc347ca251ff3eda0a459a85d9df212ed27b9e7521bcb8445d5a377e23da48a 3da9eaf002870bd0bc46688093150e254cbc0171abafafacb2c03f6381a532b1 -121000 7b8f755c93b69f842a1f9ab68f67e597f0fce31b94e0cfed7f3847662dd1a401 f175a7b245645b0f769638a6ceeec460e87782994586ff8be749cee06da716a4 -121500 2e5aa2e8bd0b018cc58a7d1cfc18d19903cd57882ed5ae8f2d6eedf72efab59c daa4a0635304dda991bc047ed1e075a9bfce603bd3bc1dcf93da809f82b0c5de -122000 9c662917653809b60484673f8f223f3ccc52f9288b8598b6414bef79181de9aa c8c62e402da8ff36b5833ba9327dd92a501367be811157fca1f0b80ee49a4ef2 -122500 74a15173b1a78cb7e95f220178205db14c5bb67dcc64f8a1e4feb2cb5b2a6e28 f480c746a1436fb843e7f5935f2a8eb79007857b4c110a9348d4391302537110 -123000 38b438bda7e108f97112d984725fab27d277a08b1a72affda99b79654c21e0f7 b1bfac6a48327a4005f79408df343adb7c9cb22d2b70ebf2ad79121cbbfddfde -123500 ec7a4edbed36c3d7a0eb4098e6c6bca397bf08cbc0e0b190a4cfd506df0ac656 7700c27d9c2e7a0360bfa2426fb3688bc8b3ca935de69d15b6dce9ca6b31a4fd -124000 c3d8229a44faa337d05e0b5311a5dda37b91babcf95e5a8ccefbe872af0bd2fa 793481678c778e8653890f1145e178e42effa2ea7f8e50522187ab298ec6b512 -124500 1510db798814caabdc90f2b18282456d1b1be40948ba43fdc68e2da017c2dedd ecd23539bb6699ca362d898cfd6181c49ac97b0d9031538fdc0303cc8441fe9d -125000 82460aef9d1133d30707bd416b3afc2929a388ec8d1431e92699aa625a4cc3e9 8ac7f7dd700d26de62506f88cf117282a7840236bd66aeb148cde751ee3f7dbe -125500 cf883230f6afd44caf802508a9bce39adeae83cfdaea0ca10c5eeb7e6e0f7abd 269f3d0cfa2df454579a4b7bc758970ffb853aaa7600808071ff130b994adfc8 -126000 e36d486bbf7eed518a2a1b1668b516daf85bcfb0359337042bb8c278a5826863 8ebd6563987e0969505718a915e7945f0d26213475be39a4b36ce9928d313935 -126500 41b57270dc8a7fdaef0345502f3ad6ecf8012b680714cf7723aea4c7cb03a864 e422bcde2c4b3e00c42dde121d189205de9acc58be35d92bc590a67fc11b336e -127000 34d5852f2c7ab91f6b7ba43851efe2838a874f1d47e6c41dcf413f263617c4e0 296613313aa18e97281d6dc14419528e0914d61bf8eb26f4ee08105aa358c0d2 -127500 07f471a70c1d559e6fd70d2adf4720987ac72e71d29c4bafd5f78e428aa6dc00 c32efb7a2072cf74b7124a008939f8093f7028259a69d8c9d175e0bb4910f03a -128000 063c53a0e11590d0f370d0a3c2fdb3722c1c91e0203558436fb43b16b06f572b 2cf68c71009f221feec16d73d8ec1b729b0624f854851153bf78146935b69148 -128500 32a9b0507313417fdb97dce6e15852a8a55c80690028759b577723b629ec0234 b2e0756fd80ff838386d84e8d82e2704a52c07e56c10a88fdea969948893b808 -129000 b3dc6186f79ecf8e7d4b2937ddc1ff5372684cf818665a730771a932461fa8b6 6da8856b4177dafa784a25b68c4df9c250a664cc6831c9804403cb021239d03f -129500 1f5e8b0c9c4229ece2580e76e5164e1beb86e165d959cff8d7a0a9f74660505a fc76b8f58cf2fcbf3f2821d871788cf4cfac6e52b0fb0476e96769311865d90c -130000 3052fa9be8c4f5f24f40c5cdf0a8eef8087e08f1d168dde5d1e502960183f137 8d108e91ab41a1057413efa8794611be06459dc53a8d2099457073ba932acb4c -130500 73ed2cd1c1fa06e01c3c6fa4848d31b24564e667e3871ee032a1ae04812c4383 df3d5e20f9ebc94bc84af002cdc9211efbbcabee00cd755653a0cadfe4cf77c3 -131000 f78703a391119a15b5ce6a2a2bebf2988fb164656c968f72359af65852080c1c 8fca74427f6789147cd1e233e020050d9babd0bd6f078ed53f704c6922b5ce3a -131500 e8873601a44048b85d11b25b05c225fa970d4ae14a3a30c0072bcf6459f2d828 140c8f3bdc90be5ca51e7c3179c7b8839afed4458278759a35c4a078ae8cf4e7 -132000 98752c54d7a5238387599ac3a0fe44b3ec462f88eb0c3c6414160ce79c128a14 f82ed570eb9d3c9078ccf41e675c13fcf6e73e6e5bfbc4b6b2c1e4649dbf8a0d -132500 7377043aca01beda7f7d70c6c2a9f59ecec4769cb330c231abf8439f231a6355 3a35dacdff298a95ee0fc61728b4711d99c4d1bd4806dc738c684d2632fd48fd -133000 0d70e8ae76041c02ab65bdd3b0f6a456288532d5447dab7f7e30123b28e16543 d6b3a5ad40a90d26a4b218b8b90852d49f508cde1bb2a23031f64e765d519dbe -133500 37aa235fefa6f62af6e393639361a4109369d0393d66597a3c63736fa5113a02 9c59c20c57628b250fa5757d8d2d55feec38752453f21232141f82c1be4dea63 -134000 2605e14bfe5b9a39a4d01da070c05d9bce4b6453b599a1f6f95d8a6344138edf 1b02cbaad0ab46a737dd848c3db0f111c3fdc248d472636765ede6a6c2389b74 -134500 12cb93a2b1e5ce4d9c6d2266bc6984839271c92f8ac34205dc621da8033af81b 6346ab5cc2bca05485ed517f9e494e1e35e33ab9ce011923c6713dd0bc28fe1c -135000 5d475b01fc5b6a22c775b89914c3b148431956df26fff2631111e9ee7d1ea55e 182dc60ad5a4689e655a00728594807ca659ea3e870a4c71152b220279fda836 -135500 d4b244f6df6c05a1c918ec0c80b4a230c2e40de23847a3c6a48b8706b55191a0 c0ea29271b681e460441fc515fe8af217459716e9116ebfaf9899531e55b9181 -136000 123eb5d144a44b6940cc6194be4ba041c5fd8a5ffb342b5d62d8779605d1fff9 9836476b408a143b336dab7cfcee4c07ddcbf6939fd40267f8315a7d4d576fd4 -136500 c169555d2b59eaf45046d5c3832203dd5109c6e3018504de66fd99242b41d5ad 0884992c307a5b98b026f9885b6c81082aaa18a12ddd0b302fc5e358e313c810 -137000 123d022b5482871c55b3638324b5713e225c6e36ab4f83120d883ddf3c0fbbf0 024aa453462e49f50c55c36736542e4129f56cc81956b74f7c77e90b0e6796cb -137500 3dbdb568d735e6c47c5fb8f459bc448693566ee30140da275f786fffb244901b c0e599ed4901402951a3663d225047e94861817b0a412b01e4c770c9719cfe53 -138000 9dcdb63588c3f9d43ce67bb6da88a144e98b3340eed60478d67941bc1f3e48b0 0c04f84ec720ccb4908774fb474149dc069c8420a53e89e9007dea32d90e380e -138500 918f3566304f92ee937b50939e5224bcefce1b61503b8cf5c75cddd293115037 345d16e0d5aa525aeef890c1cd118edb3d1e6bf784e9445aad720dadc3408667 -139000 5a5cd26abe8d7b66b82dc847fe582d00c1aedf51bb747cda126f35d177df3780 b11a4c12939538a057f35a15f561da8ad09ce4ec33a1b6b965e6c35d7f6da935 -139500 883ccc866e98513c10d46ce62ffc4b2f52914f9d3c77835ea88b2d772647098b ae7d18414cffeb5073a788005a70e1e80b3c04abc1726101177509d0872ef2a7 -140000 0d53fc7a730aab5b7751832647af30f6ae6de5f66a26aec228c9642132460c09 d157b0bf7301f4c28143ea0266a95c92a05a3499dac2ab929d57ab75b2be499f -140500 b67b7cad6c800acd1fa41cad0e075a544368d679d03d620f5cee45cd966b61ee eec57bbe03beb832a99ab0bc6b77817e6bc459e365367b09fbcb905f3edfa85e -141000 68756fe78e60cc7191d62c387eeccd0030ea6a67d4b1fb6667c068c5dbe20d53 113007738fdc702b03dc17993f916d40e24e88d12a95726aef18156355990d7a -141500 12aa3f916704a9120c99c22977c22b16bfb670c9e9d2807e0cadc444c9e8d02b e7dc3dcc436c770ba20dcbc3f4f762b7ab343fdb180e867b3f3db34f8b279871 -142000 629495f161c45d033130f52a4df5e06cf5f705842039b89c3d499aa658ce5a6d 865d4be2b339178a44d8d9ac4a53abc6b4f710b723583053f23b73c0dabd77b0 -142500 941a5dbf034317971407a4743fe1c5cf11ae87be184fe4e7749e2d32632deed5 d8d4c2edb8362a39b9ef8b2693e1b4ed597a9b315e60e424e26797ac5266f353 -143000 b8ac8abfe7b81372299d2a8be307e13786a5aeb4c3a671c8ae45d32f4bba9281 8d7e1ac28129b56b0ee93dc931e54293f181d3aa253e844d1807d47b31193f56 -143500 610bc499b94eb7e00d1aae8388937087aa421bfa9cfa70baf798b8f97e1b23d6 e990d00ff71509c232b43bde64c749bb1fe597e52e40116893e02937c7943b1d -144000 58ab7580eef5d40c0ec3d7ac52425ad5afcbccac834192fe71ec5a1d15cd4ed7 d9194f449db3d58a1784cdda50ca32d4212d43a12e85c6ad9f8b77687ca04a6f -144500 9a49c8d5f6b072b617ff80d4b70116bf3db461f9fdf283009cd9e9b2c2df0925 a2921c9b5ac78ceb49666c487d217ec303b1f5347d6902baca9b8e3779774c5f -145000 29f1fe68b8289b62a4eaabaec5abe811c61b6f2220dd15f04bf3d2ed3f98ba02 8d3672fa9d6c4767e8d3819f09a9bfdeb98a6f35b83f01faf1f7b85c6871118a -145500 677d2c090d3beb31d1e611e42801e75fd3e2004e10ba8ef1cbbad5e2b17eb02d 93a4cedb34458ef8b90ee740a6b19364f5ba6c0096a16142929987d2386358f6 -146000 b85efd80a2171505e8e2a83feb7f7d12e3793fa4ed2999d7b6148a1673e574e7 c76311a2cba2713e1e7706f71e22abd117ec5c45d7463bd7cf9baa7734468c79 -146500 f1dec5d905557b23d644829ceb4f9de311a05ea717740e9103d155157e4d1354 3764ee8b0d6ae8dc762a3b43d012eea45e1e5c1008e90403ba84549502c3b62d -147000 1e59d25367fe453ea1e39d7f0c870f14bc37e99ae2899a6f0e67dc8ca110804e 238df05f6e2a851137fb165117f2feb458487307ae95d0683bc85fa748cea31c -147500 4547d35c4821dd671dd3d4d99fce894d455c083985eeaff26531187f54349bd4 13f4a0105947e707604293a632917b8b93caeb00c02a28668a9559de36e5822e -148000 f50a828d973baaefd78a069efcbc42389c7a9d0e17cf4476d6bff763d3b219a7 7d057f6f26c87ead3d5a3bd63b23ad81ba5a9a84258b46921f27f07919be82cc -148500 219d8ce760106e41d5b6cb72360801884950e795cb80c5cb75a4cbee7c9884cc 66abe4202adfd1c91b092dc15dcd702b0e383c2a9a87dad84efc20f2391d6024 -149000 e13e98351891f9940b40210188016098d67d555ee60922bd710d234393583886 2751b92f77148b0b55b15c1e1939f566749d8bd28b70f9fa9445d5c66b116a4c -149500 bd0986d58541fe55bc5615de06174615007bb0a4e9b7d52a6e1de27660ff5e1c 075df9893a744f62bc60e850104f6ad60764b8098a18f89eba4418789bbb7c6b -150000 b0a52b599b482e9e081373c2d0c12adae59742c92c3feb16f2b56a536389c566 2b66e1c89afb06043357c8a702e15f37c6cebfe2c3ac2e2994b387b111852c2c -150500 348a90e69dee425ca95455f04bb8e0a9a5e8e4c9efc06e8358e90069f33cbd87 6296399a3fc3e48c09ff1bfda646b6f19277f2c2562c8cac5c850d691b2c2110 -151000 c2fc138fb4f13487c8f0ba65b1843cbcbfef598d66205495ce12eded834ed5d6 6b3d49e0f596367b951b6939dae4629d81758a560d8bbee402b4258fe3896e18 -151500 f22af8f0a616af674ee4e07e5821c6ae1ba54d431200daaf39362d203283af2e 8c445485555c915933539ad6c8ec776b65480a6b6100cc2f2355af041d37ae9c -152000 ffb05330a4e59f90c081b821c1cc26def98eaade28aa6fa36688c9c9ec2a0ea4 7c94c4bbaec72efc42d8c00f50f777d09fd0bf0c71475a31183bc391038e4fa1 -152500 b7c7e8aa6953c0ad15cc9b003dea50f9f8bc08d8c8ffcbb287918a9e570affbd 16591b434c6436280873b7b1d81157359b67969455cab02fcbf7ed9dec87e64b -153000 fef11d21d57c34ca41af06608c09e6d0a1623e6970123e654a81959089913630 0683353ede70fecca1f5f072916105b0fe941d24b2744dced890e2d4cc114356 -153500 0decdb908b6c897fd269156ef088ea6c5c76ad98cae97cdab6b9958fa458c4f1 458fa9b12274e81b31d551966d7992d6304bd3486a76d9e484af250b4d725e83 -154000 8e921a4716e55e2c03536ace904f1b76f2e1c1f44eb1efc293e819619fc64a6f 9f3faf97a3d07baee0cab898c7e2c16e1e75cb08b8593b30897f9290e7564464 -154500 b2ab747c57f1e073712e5c7c63d14e427e4c5aecb70c749d686ae6740eaccdd0 5b6d69da753ccb8fc0e7cc323bc544e272b607f0fcd7ecd3afc27fa454bb13c1 -155000 4a27f6a366c137b5b0d9a7864ad6ae3aa2aa4f92fd96afad203f9750743d1b25 5618bbb8a52a4a6523d7b79f9da38af51c38ec0b250918f9fe13df1f5ca4cded -155500 44de83681d8bcc4a775141039552a3bc94ae7150ba6cccb0eb51d12f67cfd3db 526775b79eb1e6f88bf7b11c21c21cd3de6b70c591b146f75dd6f7dfb25d8258 -156000 fd67b25d5f2f9e33e0717ef2eb6f7a8b61c0e369d1bb27d363c2fffec6934c6f 069fcfe28f96738efe2241bd5c46e5f9dc2568399dedf97a3b222e7db1f8d479 -156500 e4ccbec221374ecbbed5f7515a62ab145566ca98f91fca6e9e9e5faa5a302e1f 0138154cbb27aeafb8785898175459b8fad1a50e5526745da4f3e3fce73906ea -157000 7931d577b76d43c21d638b392ce9e89deb30440d5965bdeeff5ddca528b23f8e 2b3023999ab4fa8af216fc6fcd1b74a6d9b91805c25286b3a9b5c21d111bd929 -157500 5a785cae6668099aa3bba0aced796a2efd3f32357d5cda07964c38bbb8547f11 92fa0afcea0018aa72753e44978b29517c44b86583a7e7293bf41d0fc52adc33 -158000 215585110369813d5c23324bba75c2fba77a3cbbb8074822747d1d5f7a54459e c2bcfd99aadb46819152e678172eca6ea41d068cb9c3644effd3da1d90fdb6d9 -158500 33ea7e9a89e3e620f7622a67f945e6a84caab88f8df84416920e34611183a012 fe4a8ca54ee30957c1c4ff378addca94aa3c2faa44d6dff2c90aa740c94f322f -159000 5dac31f23e99492315f0ec0395c5913a197ecc6bfa5a1f1c38fcbbce10f5b2b1 3f33701f476adc2de539a516353507c2319ee322415cbe2d2a81d25579320df7 -159500 e49f3c6d819ba98b65a07f3e2b4cbd4ed74f8f352ddcc5b29cf715870ffc96b6 8d4baf5eb4e709a1749ffab123eae1c16c84c08c2b10c1bf35b904214b55622d -160000 4ffcbf8641b4b794fe4e304f3e33f8b252b45c99d647e26c174830811d5214f4 d9feccb9318af01dda19ac1b834e8aba8f1a31b7e3c0c874c2340e5f963099f5 -160500 940e235e254ce7e8c7884b846860faa5a7f8fe08fd7d05bedf60a178b294bbc2 4c96d0c1b2293677ff55acaca052f84941b801d35426f5f6fdd0985a772e140b -161000 49a2fe7b8f78e83709f195d11f092cd5bf6756dfbea8b61f6ad4acca38e0f433 c61985a4419ef741b3255effd2490b3959d9a37b9fa458a01e314acf2cd110c5 -161500 adf7a049b0055137358e82ff4cd0b223d4f1e65a99cd9427eb8892e9b3956546 f2ea625ab6cfbd295435c3e70fc60ca04f444e88a9951351519c27066044094c -162000 78eb9152a6249d26cfb9acccd3be7692835f61a70f9c4dbca7dbce97e8eaef29 92bb404d3deec9249fdb8e8b0c11e1e6ffccdce4f6b76e49185e0e0aa6480b30 -162500 f0016f65cfe29b53a443c3117392b631edda432fb508e67f537158d939bd24f9 7da855957173b1caef3a5be9882b88d6be2feb3860bc528822ac203df9480ef7 -163000 16310f334b323b1c422388a77287e590286b436eb1d54c99a7dce533febad9d1 50b8d182a094d5709040d1f8be2ed7aff41c50d3dfb49b6474ed04c7563a2afc -163500 54529c58d723c981aa51c3bf7202246d09e30d6bcc22b28929b2bc80b970a46f 81722de9f999145ae10c5a72cb03be616a2c631f6239f01243836ceaadb219d8 -164000 135d6c860f9cd670d82153e8e37e5202b6b1632cc35280c0210587f4cb4d8f49 c5bf964eb82fb51d1f5a4507bc2c9d658ae2f868cd517674ee1d81266971aef7 -164500 08495f35f925470863e7dfb79ec17bd61029899bad972ca0e5bdb0512a0ad908 8901ac98fdcdd833938280eb495214ec81269d8ee99e0c10886b9184b0aa9d26 -165000 5178c8e3106c700a225efb2d7453be3a94616e980fae5a532c0a9fd103aeaaab a71b7ee462788bdcf6b6945da2a2b426770bb4e31c7063db4b9c80f82ca88af7 -165500 3d1e48c8657aa62207f24888630361eb85ea3f8225e65deab240e5a242fcc463 b16e47a7ad5a208fe467efb2f7a2aba78cccc41dbcdfde571ded9b033b2c660b -166000 2a5df181ba84755d4893b8af164abc28ba9d67f0fbf70a9fe44f78202c19e78d 6382ac5c3033076f67f758d9d4a66006b6c67983e46eb4488b8482e5d020cc7f -166500 f33bbe1188c265e4f52649d90a9c853742c89348276119166d9dfb5b0a1c1d1c bc724795f0704caf13beea8188647ee2d0d8c05593cff788541d1f694f02e7df -167000 278a49c7367096b101da81aeed3a9b3763b9087446e3f3eb7d279bbb180ccd1a c90bba777861cff1db1ef3cd40e240a74bdbeaa23e2d4716dff0700608431547 -167500 de103832de75b420ee01b8eb238c7e5ab2fc2895848f1fb934bc0979af54ee3d 5263039373a72cea915df57bc9369aa15e7dd2ca6c3b6df27938d5240ef4cd8f -168000 c347ff8a9e0c4297f74db5943de2edcda14652f1e707b0d789878424b0f50555 fd732e674ea0cc59454e599365d9526a135a67ee82a1e54460f90b934957f9cf -168500 7c4bd55cdd16268ac7da91c44a5c204519aad6dc79a173d65227995d8f480ca4 66e715d9afc7e37855c6f1436bb3344b440a7db44fe5163f2674b542a3a8affe -169000 8d8295fb630e487b21d46f82e5e0bb95d667635b1c0cde080e9965ea021f0d3d 32309e6dc4e7812fe36a3e9f14079eb2f9a04dd910965a631f76fb23f29f2c5c -169500 3ff4f89571d4b7f8e2b25a761e2b03dbe82d9d2acc565c8f06f8e61b7b84a48a d71ea82c1b352917a9a60feeb3ea40f35447c58909a0832d17451458c4a0a079 -170000 e4612c319a4c8cda00c8853428e0c57c4c688d9c7ed0ebe3adb4ea410066230a 2428df1325dedaad3c6c2e18ba57184348603cb4e5d4fad961d9f66a33e8d4c5 -170500 38f6d4c55c456c85b59d965db3386f3bebc9f3ffc101703667c9ada2c6f110fd 7fec7fc3f24c1f7e635e06427d949e9244c3383ae8a1cbe5ff92c20318d1b303 -171000 fa2d2abf42e47345b9b06ab4f0dbcb6d818815b383959b5b0f69a207e755ae18 6943c6e99feadbcc5f22d2000b715e609874953a2f6b06ab18c6f6fe0d9ead08 -171500 b269e08b7b8fcfaacc4cb1cdc39bea13237265f03eeea6df488039715959d60d f978606a7a355e240373d149a0bf3b2a80d735371506f6d83a7eaf2a05f6a300 -172000 c1ff70cb404b9a3f97513e00fe8d713ffc5a1ea49b29be1480dfd3b0e4410d1b f2d46aa05b23a697e347a4260c9d14b51e08af5108bf22123b820a54c73c3fe0 -172500 6af8406f49ba05570e46ebbea295e07ff856de60f7f7a85f29ccdf0483deb414 2bfa8eaf8be3fde78ec35b8bc4ec1274cd089732617255d9b1450f676d359631 -173000 4187e88e79ee333c661955addb9fd1ff4853bccda1c1f73585fbc4b866d46ffc 2c561a6112ac2531467818ef79bda7fd294cc2d1aca8d700ffaa8ca3c7e2cabb -173500 979cd0755a559b4298c4e1af1ca1ed389c152f6800718aee777431e3b84b2975 817578adb3539145804a17166425c07a798bedb2637e8e6567e77406da8cbab2 -174000 84e476b10a846c1f76cd25ee8721aa8098a3a794f56a5a6e2fa8ea08dd7de954 7e3015ed948fc061ef3955ff4d18f5c9f2ccd86794be959d5e51e604c4ba315f -174500 daef6a8cec458daee2a97f145d74867790d12697f424e390fa5ea96c0edc5889 8edfed33a6db9e18b19b49a451c2278d0df8c17b86a5be2703336ad41ddecdb7 -175000 3f6c5c68d024c26235bb054fe0e892b4172a50c900ff7e36a061b17bb4adb44c f36837bd4b44bb99bc4a99acdc71611e6bbfef26095aad173d5b6c2847cf5cfe -175500 2a25fd32974c49ec621f4256e89f3c1569734a675bfde35fe0ec4572459a99ce 0de2de8ab8f49f684a4ed93762fad169165b9f29306fddcce37a10b3e0f324b6 -176000 ca43896b57242e50c5e1b0904b12b7008d63f30810c9d1728929a45a051b1c28 0c0a240dbb5b8d9c5303c2e401b1a9be3eb940a2ccdbd40482b18ebd9d16fdc2 -176500 01bd824255da4562af0cfe656645a2e644bedd67f5c4c2266e9d706d724f77c3 c1c8c3eefcd2a0dd893ec58a59d9b4b9fca2456b4ebfa118caf122316ec1758d -177000 1931b94a1d1731ee2fb2b959098279a73f2938815dabb1689c98ca64ca265eb3 9ecec3dcc0f626eff5310a338ac6ec36e52cde0e31dd2668510985504dec6b76 -177500 d5e641f50d45b9d3c2f81c255fab7812b79d778bfbf3acc3a905255009efabb7 780102c55e6488511505df92213d370484505fcc63e36844adb4e55e28b11891 -178000 41dc7c791cea13b0c22c556ecf0b9c43bcabfe110cda05fdffc9a213d07878bd f502dfc4f8e1e754fb19789de0195d3f76515af97df6f6a4dff9af35e9e64cc2 -178500 86fd0e05f7c975edd10fa04040fcfc06aa5988f25a24dc475468023fb5ba60d5 9a9d5b0da31bb391cfadb78b79de03e6d2f9356b6e8f2a6b6f3561718607666b -179000 9f87f2c50cac2bf6596533b242692ac06dd59688c85711dd3075556a42b5a51f 62c5b9a2f74642239aa89a9468c1959af35f4218d16ae1c0e22879ce5aea14fb -179500 2802d26be7d5a8dfa0e84d507569ab54eb2815addf1363e844143d4d1949aae3 04a66a42a874e8a94de4b35e0fe5b2415e2806089e62b0ce867206a3bbeec923 -180000 fc0f88ce08e8dfefa8774c7b9e101f82f4c7928aac246233b5d97b178ea1e8c8 d2cb3429b3bb7ca9c4bdbffed735f779979900ec989687ff9563819b3f340a40 -180500 55068efb221561b62da4c6cd3933963165b99679274f0a18b57e12a0f59c02bc f4a3a53f8756a0f1ab9f0dde456df65f68b487f452e35119a395990224589672 -181000 87c0badaa9ad1ee338a1e0bee51f0e5d95eeb69b608604b687e1b75cfe28b1fc 55c6a1f3d35e1ba2c56261370b991094f37b2e0c94c585c83c91ceb0e66b4205 -181500 0223e4ac4db7cb7aca8c5dbcccf4dd6d67c261e158579465c830d00f0b2065a4 1523b5a7b17c5f0a487b27b05911b0b023b7b70c1e93a676178193e10dee764d -182000 3bd580fcde83b72980a98de1bd2bc33f5d2e5260a45b2025f8993ff148006fc8 b5867c690edbe8ebe6938bc93774d516dc0de5a71a28b48539e4029162825354 -182500 d5ed6e8efecd96800b30644154dbaef8704783309362f9cdba26c757fcad2d70 f64f64d8652b12527197f54411334ba0ba66f2515e4c99281a075d1df597c8b3 -183000 e926c6476da9f0d3fd84aec136e029881901667ff07d80ecd1e6e6e4a1e78979 e74160bd9ff069b6511c0602a1c72fc61dddb22899f805cd9c2c0be184848033 -183500 5bde7c982564b58b9d46d8208922b3ae8cd1d50f2f68c7a4a8d71e636b66181f 00d016a3247ef22887c0909dc0a7370c62bb2601b09425bfbcd93f782e1466a1 -184000 f1cecf410b8d9f5cecd6bf19ddb1c7157cdc5c42e110a42596620d9b54216dbb ca3d938eed902785feee39efcc9a60f26ba5a53ef969f174ffc7f44dbe544bfc -184500 89d6e5e381ea4c429428a773caa457945d6e5986e77830699d64ca84b6b7cfde 30e5fef97c937baabf267183b5f8bc9de88eb72b00c204abf6db1962ad1e1f0b -185000 d55dfc02a7dc5e64f615b9821e7738cc3f4b1cea50e291834b3d950457c0befa 3976b8fa6d5486bb07e4f6a5a63f200089781bc8c347f858bcd2d4a8eb4ebc7b -185500 b74792db4244be3b16341cd6bb1af5c7a9b71df58b812691901a59e2e6889f8b 4523193666a8f6eab2f73949efa94fd98d9ac8821ffec1c8069abfb1dca83b0f -186000 673e42a71dc7428d516a2bd892f5bba9740deb4a8e7100afbb0db70de4432d4b 54bb7fcf882d25f7e4cc19b41bd13e44d70c04d31a6b4e2ddc388b6ebc0b1818 -186500 ac9d112147478ad6096daea4f3b9b76912367605cfb6ac68a5951478787d84a5 7e112c5297f3521039d52a994be89b1dc3b6387b4be5398d7673542df3db0945 -187000 b06838fe81d8bc39304fd98dc9f24ebdc0e6a05a363713e028382d77334c2afe 53c32d4af24bd19d1dda8c23186b6cbad5cfbaa6ee169666de3b028473f3d388 -187500 c3f730a1d3977c557401a7ba920f22b768e9e89924a07598af8f6dc0930a4585 a83e748dec264dcc6494d6ef7c63025e554aea410915c25db93249088c287442 -188000 4a74ac7ebe38798b80ff54f21a428c40915895bc44a528bd8e4ac3b9f378def9 847a11b8eb71e0b5dd698b277fbcbbfae9c54e55477320396a602a26b1f73d8d -188500 59891ac998632472cdca935fa4a3819fc676d23702621f0c41d6d38fb9e354a0 4393d0b0d5af19f6c123777762a186fd30666e8498fd76468c3cf928b4e6fe1a -189000 7c43d2b882946af37b0d1b1e0b3c08a8c55e83b9d93e0d3c10ecd3ac7a49c1c9 0a5758bf838434644aedcccdb7905d4bcbd576745f82e53ef74c9539b9c95cd0 -189500 4913cd6821bb3900bb012df98da308582c7f99c8907d1dcbde5caeeb04ba1abe 83dd01f4f3544a1254fb7b6c1fd8654a10b4ed99581b1058c79ff2a3a08b3ab7 -190000 825d6842d16dafb7b6d3fff172fd176916478e6a14c50efca5e2b6990f7c2299 0d7f3744d4e18d9132d3bf7e94b9325900ad8a574c6a48b04e6594f2ed07083c -190500 b7dbfde08c23efe184956485d0c19d62325d121b493560ebb0d45321b1832b38 227eab03ea5949234a281ae85657bb5fa39b271fa2218e294c4dade8273639eb -191000 e61629b5f59b130b4e6fbe4d3aa8027d13aafd890ac3a16b1ffeb1d3f590bc5e 7736329d7fc7d226fbce139fd58d1b21a41381b442fd62f1d03bc53b5580f906 -191500 06e8304e59c8f386db5f89bbbf524959e5674c1f560121ee65e04b5902833f98 5e099e60aa5f56a39831962822390e897947b435b4b84cc2f45a1e98319aeac3 -192000 7a94bca1896611bedd44c28323897ac0b065d2832d36000b51da6d8da42ba38e 640f07390bf420c0f65d0b59112d66b148df416f2a139f961bee379df0928bd7 -192500 23a1270346e2cd8b1439b2357aa6d9967285d727963656385edad740cd66922c fe551350fefafd463b3d5f47a53ab239b346bebeaca875c6c7a87d42ba976bf2 -193000 5c7ee526691d558d00b30f649c4f77ca4c595742f23e389ead78633f8ce2dd35 68a041f99854b2ea4ae5bec9b030b48ef9edb3aa89a144bad9c7e744b234d409 -193500 d03957be53c5a92ade2f6caa1e1999c3dfb567084580cfc618fc7bbc6758fc1a e218bdc4ec703cc01b2ec52b860b2bc0ad51b90087088c9cc0e58736d625de91 -194000 d50b3435b1f5fe763970370fe9fba1f0a5af9e9a9abe295e1e61d8832b43ffe0 6f3878f181e0dadfd1dafc8b2e75c73c6ae0fbf97a6bd1894b20aa93139cfd80 -194500 43f28b5c1af708ef1725ae8b0e4542dc6c6f33585455e6763038d93b37992cf5 6792e3e7d2ee64a48ec47e9fb86823aa726ac49948e3843d43ef80995a4ba7e3 -195000 27deca29e0f720fa505c64794b7904c2f15e2b2bdd539f6066bdbfa8b9cb16ae 53d423505456177cb9e6e39879e51b1a473abc363a6df7025d6c523f71fe10aa -195500 4996255d3fc243ca9b29ed6f5e7cb2799330bcf2c11e42ce9a82c017fa4dc47d 1ee2de24a628d83a4a9b796d5f3c6c65d0327202191554d0362ceb1418904a26 -196000 c3861c14add9fd9665a1751e1bee488a13e0156bbd37013e3e6a8da54da26550 4da431d08df43f875267b70903b275831281c28902749fefd4bbe544989a910a -196500 9e85e9ce7c9f969af748556cb124ec97c581e6ed8367c4c44e8b9b12d5495ea9 14f7254f9bf3d122eadff425ddb06f86c16c4a4954bcadb5e99ba6ea78f8f0f1 -197000 387b990115d39fb36240de77081a933eb7d4f8ae20cd72f0dcc162c496717a4e 69c3b4cee6ad5d2d315e2b133a716b8640b170a0f5ea53269343bf4455a886f9 -197500 0db48271823bfbbb62c8d9bb68a0ff7f46724dd251ceb8244253418b3089060e 0c2cf4682db25fe743e7e2781ecedaa243dda4d9944edd9d1aec7a9e93b831df -198000 c65104e71ac22bf228691460ed6036046fb091eed1059ce756e1056bf149148b 3c3f1f86ad2cd5cea8a979c55d01fe3dfcd5d6ec6fe485c3461d65604ad4adc0 -198500 30e8c038e2a43c5ddc9e0f3a030070380cbb09e577ed7d783b83651df9ad5015 dd0bd23d500ed9eb599249629cf07236244c001e0517c93dbe6debe262e7f4ee -199000 4b4e61aa4eec7a39dd94aae2c114994fe32185c72050d3908b7fc0860d41458e 0443985e3352c7ec9e83fc34187460671679f71a3eff263956dfdb306f4e518b -199500 09e62ab674ae8526370e0059097c80cbf382fa098e67d4a1175bada96d5d87a1 b78d27bf65267b4e1e7298efed4270582f8c9e26d53af59d73250d4862ca4968 -200000 cd9a04e20b651dcc4518ae71ff5b0c8bc2ed5c6eb3d5fd2196b1e636987c3a95 6160d970d27a8f799d74d3e01630761bd655268486a9107be28b128fbbc9dbe6 -200500 03609721a5de60ab9175d5cf5b9dc444f8c9d420b94814be90e39e4d5411f33a f1625e3d9d93f152c9e351928677f1e8cbca9c6812473c759de6216321fbfe53 -201000 f1be5c8c40f967dc2f1448f38a7e7e6a47c6d7e6ae9eae150762642394644f19 562f88889f723e4c4d2a7b0f8b0eed383db6aa34c8e094f88238526206af125a -201500 668f7b1463226ffe529002e0dd28b813c68396ed381a5725d166691660a0383c 0077ebac17ba34e5d77c492ce62473602d1010d21a99380380dcf52f1a6a3318 -202000 60ea6173bbe62b24b704cfe2b6e1d1995dc8854d618fb0e42e0c712110b70e50 aa3b08fccaff9887aed03778827f73871a658dfae6ad99b7521142cdf8e86dd0 -202500 6de298a7a2fa7ce5bba344237129f982b1071969df56c15d0ca2c0fa39f9c1c7 dedfea5340d820409423688ebf7c236cbead8e502dcb39af7686681b1f4cdea2 -203000 0e117900e8f0bc91b0279b83445b8d9cebb374dd81c84a52f0b3e6b94c880e1c 74c1495fb1f720209dadc85404e75bde143a59c7d21ecac61204734dacf63545 -203500 ee347878394b9da8a6c11dcad54882196eb1a6acd7e323154167e764d57f00b5 6ef1bef22de744dcac118ba398ca60424a713140fbb76fe0555f1e89369458b1 -204000 a687e4d0cdb3eb142d1acaed94b80625e8d9a9d472545ed1dec3c5e966db98b7 728306e941f0ebde00511bfc3a30e50cbf283e1850ad4145f2697671f14c5775 -204500 c813ad2efcaa352e786ef9dc912e133bb1f32fe408a54c114152223fa3c4e96a fefab4b9604535559292b1b31c4996dd815f25a8ac474cf8bc31d0c176aba97b -205000 b67beac20c8c3dc2e07c7d88d8bd4922b8803da3a5cbaec8c8b0a6601314df69 88197fef17e17da657552b7cc5ea2e09377fc466d37dbc22ff8a948509057d63 -205500 0937f7527f96ec479765e3be263f25130d7898056813dfdc67f3f95f4923f2c8 716b95c3c62dce9b236cba23dfd9dd3fcc68cd41cbe9d13d6f8349503fdc3827 -206000 aaa70022052f41b2195c68a4c77c11b78e1a8136f03477d310a57ffdcdf835d2 dd9991c1a086391127322eec9667bc193908aa869a012b36f0968270c8c679a0 -206500 7724e797f7f8e157fe2292c5a76a018278bd7bb95924932df289d975c4191c6d dbe2029b6398ed4f32b906956006915345255bfac82ddcd79e44848574c50d36 -207000 3d779550ba9dcc4e29106cfbd2efd9b22340432345c0df139ab31eac25a45226 cbe3c2dd884e9ed7a1dae427c3d475a8c9f3c8803d0f3507398b92a6cf5ddb96 -207500 5484677fb6f857f8009fe0e371280b61ba15d0a5fac08bad41392dec1f38c85a 649c2c9faebadeb93551828d590b757b444b6a54b40298519e5aa8505fd81009 -208000 cf31a458b286a4f77890e65d02cc506bb0454be9f373a1685f2f6b2b91a76207 22e9abf8f61d55f7fd7b85e0efa3d8a0f6579f43020b19cbe921a79d0122000d -208500 4fd3fc158e9219659c7ceea1c4f02bb89563c7524e9b8e9f158b61bc82c52881 4a0ec89610a1cbe8193dc195991742ac08583b9c86f9d24a5b63241f8da4b476 -209000 d54f4d0b5a8ce4ee97d0ef4cb455ac54b93b0092e177f1532e6513052439e9fd 59a0a1d9ca71393c4e4271d8d1ea63d8f0fa6e8388c610fe4bfe8362dc0fb231 -209500 14e2bf16398fc52492652cc0ef3fd516eaffaf2cc3b7f89e37f3bce63d1117de d9a9a12a655ef80cc830f766200a05617bb235555e7cea98818bf103a3a6c1ab -210000 4e035fb68e9d78b953e76e14a90355fa127db686af2bed4bdb301fc3223c322a f6916044d1b6a16eb726cbd05a2e900f5b9f828625c850cccb699327c22037ba -210500 e9ad24df7fe871c7a87de17e0c091b99a332b47903d8d39da2a18ccafe02dc1f f2cb48175161b22cf3369f59e67941f77675c6109590ad622a4bc476364043a4 -211000 21fc2c297b7bb7c088668fa502215ac26b2ded973796765acc4feaf2bff112a9 e21b83547b49382c15c8fdb2929711d49eb8693d08c0738813df68c359fa2442 -211500 a83b2da994898b752271b844f26d88d300646e04c4e89786f24fb4c7397ce6fd 4d8d8b7364ca603e61da4d09bc9c0b1dbc2373e65f5db2297828aec6395b5991 -212000 ab0f9dd7169c2b902f4762fce10983fe94e3c349353e189a510781244d66b77a 3ba1a0d61a8b8a750cebf79f5c00362bf3c909f11725bc9e9762f21de08a7945 -212500 b1fb4ee2f329a5664e6be5c85834dd79452b1f89551d599a70852bf49daec183 d9143da167a6553a85f452745577ee6ef19fd21565b09ed5fa6cdc00a0f01a49 -213000 dc4c87ea7c60026a65104a0d8a04e5540e3952df79a62e59deebfef6ae235e81 8da8a14d3971436306dba00351d265f0bd06b1f59005f94336aea44880498b5d -213500 2466c2e233db8e30bce3d5ba87f694c3095fd391b6c38c2edf907a4f97d498eb c3f5734faaf87bcaa9be69122a144ad1f26009d8fce1f859a17c2fd4bc0c2c0c -214000 fa84d9bd1c6575cabfcec73e1834d129821b6a94d7814d15d038239cbc4a568e bd1413d32f7719df41ee9caf406a30c8b97e2f875efe7c9ab2fc56555136b5d5 -214500 556dbda0caa051476bf896fab40e8854a166c7bc416d5f3121fe1d312369dd0c 4e5d7dafa56fbb04283e8c41e18697dac7beddc742d098bfb87d4df1fe90679a -215000 b7ccb76ed29ea49301f630ca5e9cf200ba7a9388156304636814ba6a6b417265 8392386752e5ac61b9856b95e9c833b57fbbc5717e93f63e3944676202df04e0 -215500 a56a071a789afd22ee4a9e4abcebd695a26ff824a895f5291ab639336d609bcf 6dcf6a9b561236f8f627cd567d937ca4d7e6e9df72d466fcbcb505af9bf1ab11 -216000 0e1a9b2d055f2e7b637d9fdeb778c040967a8a2fbe0a38ee57bce4e8f4bb0a51 c5532c221b5cba08f4ca281a247e98d28654b934c8595e57873232111c347ecd -216500 9890c0ab7b427bfa46ae90fda04503f1b17a2493c7b36f12fccf0dc010d3f9da 24ba34ff5619c38e4dc516e815af584f4c5ae6518a57918aedb59403a3b356de -217000 b282a7dbf2dfcfa4a46938422e557404ddcdf11509053fae49f5add5dd101d8c 645bf6456c36a43bef5c217fd00b1e457ae136d52396e504db5ed9a97e406594 -217500 9539ac7cca0ca0524060e3fb6ee956d28ba115c7ae3f54d5927492d0a43eb49d 21f680a60447675216989ea718c68c63361fab5615c683a7f047960d50ff8873 -218000 dd15ae9a3a001651303c757cdfa162b252b9aea2d1c4fcac645cfbc1d7dcbd7f 78cd6e280ca819c264e6447e6cb93c616f0bd03547259a0f23ae38234e907dbd -218500 6455bdb4441ac37e8f0d04b645fc033010698430944a873c2c097f7c0d3a02bf 466f4eda729538e0604472f6c00c4f7398a28c9e59c89602716f611ed8731edc -219000 a8944486d2a12285430d1764ccfa03bfed013dbff38ff5fada97148b883db9f3 5e8d4e1d9d6b8bcfdb3ca94ef5d0f8c75b9620b7bb5f360d8172e1becad9353e -219500 adad89636c4dbae0dc680326d95d5a2bec6ffe7baf704f26889730681328b3e8 d17aeaafa2e7a17d6aaabe48e88ffc53a8e61bca58de2e844fade3461f4931e1 -220000 69fc4cb8e3103151a20add15fcd55a9ee3c1f2cf78ed3bf9ddcd0692b78c2a71 25cbfeac28f67981d5d011357c01ad82e097c0d09e77f0746fb11a93329c6958 -220500 fb7731f8712f081c1e9f446217bc1882d62d3db40bbe2711a25654e2e74c6cb0 796240f85e38b57a751b19d648938d9f8f66cc8cd2e8611635832cec8d25179c -221000 488df413aeead90e34c182fe75cd71227be759865df577cc6a4508cda9f13213 bce1bde7cca72a43d9d80b03ea33c845799313914905c7800f7672654821a7a5 -221500 84d958c341c484ca8e85984cbdf5ea436fc1564c95baac52ec00e9f03d5dda3c c493d1eeb83f8dad5c17eec83e69277fc98e519c639d3c892faee2d6f80a5fe7 -222000 24f8be00386b9a38f5507e77e72cea34598910fb8aeb57c5d7fd5b8b082b1d16 77d77f3bc606ba0a8ac17dacf2d6d794bf655c58709a5e6affb1c2238149fe94 -222500 c9db027d5a71c17a32dfd7694775edd913f829900532a36cc673168de4b41cd1 c98ee6b634235506cd78e47c3c51ff7f20e2da5be5bc51c9269e0585a77f344a -223000 2491331dde706d72557719b2d51300a41185e0a231600a748cadf6d76cb97be2 f464bf83372078d78b37b0aab9e98a697eb07bca9eb62d65919635d9a62c29f6 -223500 757897eb0ef5db6fac3a16b4167e73ac300fdf2126d175ddbfab527fe72e5cc6 8033074e1db6b73e123b62aebd8983887d50385f70770bec207b628e9c945425 -224000 b07c519e796e7ca9ecf620e6437128ea8762b00f16ffb3f2ee2abd5973fc3b21 eb8135fbce4a5f3d73713eb67416be84d02239e85bf87dccd22763075438c693 -224500 4a873566e5cb9ef793cee37c09f7bc11668091934776eaf0cc5254cf8f565ebc e0b9c689e95ff5d675aaafc9916f010b7e5b9a13b201686d4a600c5516a8e263 -225000 b4b671d3954ba70856a978c8c173096a9db7ba168c8815730cb445ed0b921f7c b16288a5f727839ad38a64139741eba8f93f33035d294365e841e714927ce5d6 -225500 17279999d391f86406797119b105c9f5f6a02678f7c3d34d9f272c73dd77faf8 d555247b00f10b1b9825a09d2692d22129b967e1ff244d1a60a756e7b2d9cefe -226000 94d997cdf120719be0ea6a4eb198704a18baebdf13f65e28e51b49df7de1d861 d3d5f6655db1fa41b2f916399ed5f36246ad98025f6943480fe15e43b0a8a034 -226500 dd41f722e300bee85cd30450c9fd08c3d4102b1095f88617c10b100556c5da49 f43f89d4fabd9330fee3336ad9bf701601c33aad3abdd56eb6c164c21da1ff10 -227000 a0e48510962ea5a5f18c8d413b48688843e5cb36b8b74b5e61bf357b43334ec3 0fcdb763c6a77599a872c5baa6fd1ddd761889eca1c53e882b616dbe40de391b -227500 7f5337c81192ee64e2e1fd4da832f60ba2d89b0336e8e169423dd403d6f76a7d fdebb66099af9283e9c026e1e9a112a66af6e3bb0f657ef78392a9dad4768963 -228000 a8779b9ce01000a531f400c46d8930c487ad00315f0ec4ee8acfcbbd02ec9e7a e9b6fdc4d73e7910e18d95bf096bd5becac7b96a9989d60e564f1ac2480b1fcd -228500 074c0079bec868361a58eae22d107577538fcfcd531bd3b0516becef48d25083 b0bb15325aa285bc0890e24b0892efb113246e6d785554e59022c0917ee4c35f -229000 27c38d7adc92ec6c3b2e5c16ddea6cc06d25cf138ebd45a935953a357143cc68 f916d1f8fef52c7532988bb984eea0f136d7c777fdbab72ca0011b4535c91e46 -229500 1010ad9db0dbaf647e510b73feb8352b927c1170dd09dfa15fa0f5b9735852fb 7a7b2eb60a9dab15faf8e37370dfcbb6684a67faaf7ec1f50980694c26dc558f -230000 e84c9aa480b0a7900f557d49afdc6273171bfea6e6adee45c3c2c7408c7a172b 1f03b2bfbe709d7b411679979aaaf2eccfbf14b2a08aecb7139b191691acf77b -230500 1cab5352d167b21bf28c9b3b0f8cc821eda60b32ce9f2f77de5737edbf28bcda 8867625cb142e048d056cfcfe5627fb7ac7a20a83de0a9fc008bd4951ed7def7 -231000 a7e7ae0369d5839690ba5cd0f83167cf68e6dc9c5604feddeb986b17cd35ae76 4f7deab8e1ace7033b726836f01863f33677e4ecf1f8a488fb19b99630fd2176 -231500 3bf6451daa832303c2242f195ad2ee1a205ca168fe132087ff899461f29dadfd 6b87a643ce4a5cdee1f45ea3ee7fcb9b5df8452209970de76513c846c73ae7aa -232000 6e1ae43ba56524a6e2bda4d769f8ec8e99620690baed8d8d1764c3a42509af81 eff179dfdb3a490f2038514a8ca3c65a1ce73c266f808378d767c60d1a8f9b16 -232500 95589eb200430bba2e6660842109cfceef9a90889ab8eef7091685dd052037d7 2b8b93e3ab1fd3b12368ba3dcb7b087d84528932cd4fef51ae863dc40718df55 -233000 edef1536377488c20d7836daea81dc7b542347febfdb3b7f0e89ace9a9a2f980 ef9ee2dc8e6eece115a4fa188288ac21117d58bf45921924db619655394ef4d5 -233500 7cef0816722fc26a5a131003a9df2d08cfb005d752a7211cf52c6c27acb735ae dc9115037b26543076cef7cfaa03c2839378b0cfcb8b164f883f2f73cfa95b11 -234000 da363a034d807c2ec1aab013d8695631a0d24c50c34dc0db04286a1a53fd58ad ef5a49fea7936d6c151fb533277c19b7e2bb3e88e9351cec946bdce22c5ae5b6 -234500 e35fd8c71da099b9f3f1d6017c9b799b6f150e553ef827f83f84b4d62ef723cc b469f833b3d307d9f12fdfcb7a9777aff2c37a2ccf713d2239275f39ccdac37a -235000 903c98a140b5e8ce72a2571fc17c585544c4076e6d2b2efa8c58b635adcef6db 5d048227793f68e79facf5538ee5980089562490688dd1f929fbfd459edc3263 -235500 1e0c48356729ddb9196f9bc8cfff295e2205283e468534eb127eac2a8503612f 152dff3242d0914c503c8ecdb376d1cec2426abc09cc99907b1f43b31dc197b3 -236000 48c76115fb5c845fb7e9b8d9bcbe2270755b054db11cd6ad6c2ad89152607576 1420e404d7b541a053200034e94f9bdadd705dbfb57532c2a454b9b17c36cee9 -236500 76dbcbc51593c2ced3dad33d42a9f8c522f01a21383b227b0e6511c76363d782 f432ef854ed6a03b4809d3ecd8a46def940a0d251d09484ef1b6bcc3271b0f17 -237000 8c821cb30e183a3f5a3b28bff8b16d1606566e3836a2eb0d47f6c02af8d3f324 b4bd12526051dd6ba2a2d616a95212c8ab4d6adc18ac21822a57738eb8284e2f -237500 ed4f21e0bf654339e17083701448309eff81e272b89e00fdabff166cdf812bbd 9d03191f41bf9d7bfe65b5cea79e55f32c57765ed5909e11ef961fa56f3f69fa -238000 5af7f4d9b69ce00a56f5c7d89de2ffb0df0ae23520ff218ab2330ce4817ee326 509f60bae30c0cb7666f7baf33fedb510f3364abccfd0881671650caceca4cf6 -238500 e95df9d3b7bae4323a4562627b9926d2a3f4c152e93513f0b57d83ec88ad8868 9d0e160a8f87e36e9fc815538b27d8636daf94ae5c8701d323995054446ade18 -239000 17dd8f7338c85dbdbaf0d87bfa224d5fc13e58aa465cda17eed21ec1e5a13051 61604321167ce51b0c2043524749d385b40cf729814d88e0394149298e1d612b -239500 d10a85ecd99d5fa8df9df4aaae9ff7b6360bf0f6c541fa6e1c8d743ba350d1b9 085caebd6ae46fd58b66481d21579720316fca78552121f9252ff8fd5019257a -240000 dd21b880d234b770079e0478bddfc53646feba611a1858a82be2d68a5f70b5cd d0bdb4e68e287851256fe8cd8518ab06b2f8bdc30984ef27feb96cbf2625bd81 -240500 4bb3da166c854ac97920a04fff729b2da619b130b3b257fba10f5be47354faed b7081936dea5f45ae555b58ad83d42234183f80123236a1474f1df92b289dbb3 -241000 cad2acf8c8a9802e5c162170b2cb7112447b1b5bdf3184dfb6ffca5d5ca066f4 50a13b720476b0d72efe8fedb30d6c24265a0cef374e1de14df89e3488fd3930 -241500 f89869f168fee009c6b743da990e96a296823c795da2fbece16346aff95cc0d1 f1e24d47abbd5056f7d3fd322a882ef885585d877ebe23b86787fd8bfda5c03b -242000 8cd2957d89f5937f87ecdc188f5ad6b275768752b873f36348fffde02bfcc4bc 9e37495c487f19227aa0b4312458907ff749f668a3cd386d46318281e03497f2 -242500 4d84991c165bcd35c6f24e4124e5b93678214af88c683ba82419330162070a43 dbc9324659ca8a138b7f72edddffa009859cbdfe03dd397da0d897b40eb97efc -243000 99f2ae7beed98478d52ce8a3e8106262d777e9220d54159cd29173f823002468 f1af12a5aa6ba842b39e357a45bcdcf93c9f718992cc160e1849c693211642cd -243500 84b668ed1334a0f60f2b7cccd9a1bd05b758fcc1d3b6de13314b60b1ce8dd69c a02d27be36d8ff1a07ad35d80e1b2340c042bbfeb7ba7c0f4289eeb8b66ae117 -244000 58ccb25106990e5eef0f7118707b96402f853599ec51917347012350230701ce 989a5646dc6e9f91b27d9d3f3eee07de2267b5b62ca8c2e0faed6883f1d04e18 -244500 60b50cdbc1be5d94c144f682c62cada4668154d94b909100baa392bd914fabfd 15fe02c7705d1c3860305d80ae479410c94dbe8ed03f942dde09d3a3094163c5 -245000 538eb0feb39a02cb69f673a6707d23f80be40a922ef8fb43ddb1782d8bca83e3 ca4b24d390ad10642d096a14bcf8fd51d7135681c9a750a80144b107ea02ce1a -245500 8e7a40c1deab5dedd03f960399dd0a59ae92ed849f0288ed447307112a4679c4 fe223451b524113b6d13c696681af1a1004e5be0fcd14dba4edf5d43f1b52894 -246000 e5410e4186cb320449ee28882d9f32cd3eeb79104f807651b8dfa0164ebbef82 0a4203ec776383111ff8f9ff697c72bd8fe1203d55242790a9cd42086b2f6013 -246500 0c2a1c0920dffa7e8a582bb47b121ac02167b2015deacd3cc2a4151419dd8dde 1df603f77f223501d3036d16d2201004c712f86aed58cd0b3d89b32fdd1b2032 -247000 def0d291743461c8680127c4393f912663ea3e8105026bc76c315de3f7471a17 830d9dfbf53d41d49c1a28631361db55fee2284001c16395ed3046f9a9278212 -247500 41c85aad59b4ed9baa25743ed3b2205550292eb7e5e4dac974f0839053d0df75 dbeb22eb94053b3bda3520ea239bf64c51d046da08951074dabeb73b06cce009 -248000 e34f803c19b9214d128703d584947a348459dcb0191cfd0a3928447747b7e3cf e58a6b50690ab0de2e1d7e5eaac39e60495e7f15c0e494797c49ff0a83e80d6f -248500 779f30864bc7a0eff2ff65a65af9ef49ed7125f708e923cff6a7a88d661c1688 34ac76a53fca6d0daada5f7f12e339fddf5d654bc1ebe03267716822cbbd0514 -249000 46d582e130542ed696e49a52224757fbadbf61037d15182cbaee9d6895261d72 7487aaf55ca988670dec71cb5386b80d8975446ba57feecaf64b3cc9c52a18e2 -249500 87fdc18e9972ab01bd0f1c0314fe017d5b825b2a802da4da2be0c495e8a6c2fe 364509f6a5c984e616212b9a328735397515d8392c612f774a55e8013b80f868 -250000 f345e75ffd358b61924b0bf3fcf99156f97c1479a0b31c53713c219a38846b5f 156b414c9c8d5782e5ff3c541bae9a14641338757b351f8cd7340d91ffe7c8ba -250500 111446c3129d174c80978898f17b8c14c485a4c92396a8c2b15c76d7da4e4ee3 67bc454190eebae6062bcfbd41b10f18161d777d0c7f1547d9c922fbe59301e3 -251000 a1d9e94171306fd7e28559cfdfc8be43a89ce142208f0b4a4319177bd6e1821c bb9e6ac2b06ece214228cab806b96fafd12d7fab5899ad4b8f6c57764c04b65a -251500 011ed051ea80d7aa8c5631cc3f6c808582b7bae9533a47a1e9336280e244a66d 5ab6d307a8215f078406e4ef5256e86f30683732743e4e102fca988e3e9bf157 -252000 0f60353af5fa6f614467ac0b793c0cbfb723b48353e45a163384288db9039860 977d7256cf493f632575935a40240e3cbc08e8b82b9cb78666fdf4e17a80748f -252500 856aa75176f71b2613ce0655d8bbefc03739a2ea066d1a396f608d596de9214e 6edcec572883a3e3e60b10a312a59c1e4486a0c4a73f5726b7b3cd1fa5ad8a8c -253000 135cd797ea002f028f372b545ba294120d92fc0368996f3f0a4a2c3aff5e2178 f6f35b4573ebff09a1d86085a7c5ad8f5154bc67cf6f1b821780ce3f39d845c7 -253500 7e62b3ed039f164bd4b37eeacc05736f7160fbd8ab2a0ed7c8789817ba43f47d 92fe7b5cfff4d6c5fa17c317ba47417e2841e65a9a985499f3ed0ebccb05993a -254000 413a5fd20a447bae48dd74c04912c73ced49cb866c96a65aa447164084dc3723 dbdf24cc5fe71f376465115ace1ebbfdb9382c6a47ffeca175f7b1d71d077109 -254500 dae6ea70719a1798ef4cd7eea67fb84482f58695bbf68106fb1ffca714532549 aa0bf86ce61e6a6801a133340c93e099d26f06c45ea6a7d0303866d59720cd45 -255000 48686fa37b3f22077cadd219544c1d55015b613ec8c5a4c367b0e32a1d93f114 8419590a10c931fc7b06e4f0c9cd66add2783839c03872569a4d84100fd3ec7f -255500 3480ad9060e55cf444b9f63adf976cc48c8e68e9c5d9f2e173d30ee5e21f8e55 22d1784cfffac5b2f3587152e60a93c18c3ba34d5872ac90a1bc249b98aa17ab -256000 773459b90dc0d860e1caf2eeb99f85410a17adcd86b9c7a91e282d7375f69b87 dfe7baf5a19c7d41d0be344f1c0648ae6a720b5c9b50d1a1755908da38ca28bb -256500 5c5a4002c3f5675ed11fbe0d1640a0cf72150462b9f38f2b6fefa04e2d47e57f 504eb85fa2d5bd399b16262f3ed52330fd25eff4396ce7ce96604c58c835314d -257000 f957080ceb81d1ff1a57fac8d99d89f92332198d332b82ed19f116bb2e4bb232 2aa6db9a7e207b621656e249da6a29182bb6e77489137f185c4adc4b43c2063b -257500 124667d3ac4e97b204a238e688229f21aac351bceaee670bc86b048aa25a326f 0806775e04bc4c3536af5ee7c404d2d53e780775da20c269b0c52258be37dad0 -258000 281275e81b624913ab150bb6061bfc3d065c3b8e876c1c84c933d1340342804c f2a8c5a57fa4b177d510bd095fcdf765e7b4c08d8ded22f12c07e3fe85011df8 -258500 99b3f45ea656e722d919f59a89e1ef97e171f1422ef68fe6ea17e84496369d31 4b30ebda14fbb69dc80d6219066b66d8716e2235595125113444f28e2e0e3ee0 -259000 a3c8b1010cff2df85b748d06b4070653855a780fa89c1fea1df8af1b99e1f71f 611c731a6c76c22ace3e93b064a4f73f2debf5f63d270a9a3a59a7a46544d6ba -259500 6f80b9fc49fe6de69d6ca2ec1a783fb006b73c7e2fc0caac427088dc31d0b527 d9ddfb40c125b781b7780845a78f6c90c2b887b8c28a0a930ccd6ce7020bfd3a -260000 d3f3a0df265b13c30fd6d529da8a8628c98144abee10ac66feb2d98972e52f54 31ada4b62db504d84fed898117105427ae16309d45de494c4a266316f8225d25 -260500 10c9f1214c1a77cf5d4097d05a4ecc043d8db4dc9ed855892763104094e4a1f7 273762c7e60334efe73f1325072dd8829130ace31287493f4028fa9c22c98619 -261000 bed3ea15e53cd2a4b2f8d515efa665b1552ac7bcdd575048efb6bafa8b3d0f0d 3fe66c2acc1cef4355c4ae83ecb34597060c44da2aa73f0a51618f4f6956a8e1 -261500 0e9b83d06669715a10a70adbd0a89d58a56a853be8c6b4e6fbd3894fb865c224 992896ed5c5c7c262850a9d3f7b10ab729de8fc572190e0c08745ca9aa2a5433 -262000 61022120589859e23c0c4fa1f2650329f44feda0823bd30d597be34ed030c86a eec28d8aa336511816f17eb3cbff661e6fb35bdd9cc7a63e9ce830e7dc1261bf -262500 957872933b3a7c22e527930d65220a77ebf04077130f18703f4d9eb8384edac4 e267fc444b94c0c3e8312c063746af1e93887e4f9affb11d03d5728885b63cc6 -263000 e06e647a254beaeea41f7d2cf9d88531c5193df8a75d4f1d8df403e1c2a24309 5aa9aa86564cd18ec3e2dca55315b46958ed92e4ed8710e33ecf3da9b051107f -263500 152388327d812eedfbbaf6f841061eb28be5ed87dc9453402355d8d06c64011a 23552aaa4ce81d4ada113f198ba4c848defa3870f8093576be677c2e3c92c149 -264000 ce414cd76a86b1af60c778ff9e5b04c31464198d303c9f1d53126cfa930e706a 2a3acad69f31b7b30208aab2b1bd15695cfaca2d8aa20bb2751afcb5755ac0c6 -264500 d259e8637b4b48b373b6a1a7afcd89b1056e2adda59b819654f393e63ad2653b 31bbff6e4910bae42fb446c184efe8191dac8d6a86156568daa369230b5198d3 -265000 ead49b3a388fe07616d1a8e8c391d50dffa01899a7444df60d4d2c40fd8afaca 9fa60617a2f080f521628ef3d754f1706c464fb43a8282bd07ce2ed26994be5d -265500 6bacbbb516631a7922e9a988fcc5e102d6f58601085f09511601f4672a3fe316 4a5b61cce54e08360b9b2e338f39f45ae427b2cc49034fb0f1e71948a7eb92be -266000 b6993a4fddf6404fe544fddf2df238c999366b43e7a335b81b4524f9aed32999 91407232bbaf55fa658262dd6269b1ec6c620eefab326e556434fa1d0d64cd95 -266500 a22adcd41d7ee4df6deb8633f53d381e9826dfbc7709e68b7b1ad5d71e8898f6 314feaaf908e8a8046ab6eba7cbe3c97aa478b2ad93c39aee7df9f5a72955db4 -267000 d270af2ee0a98e7e407e39d50cf4cd22005faa34480d638e7a6b7c10b8d59e4f 024ad7c62e3a9ab757d4905bba29fccf5ef435e4471fbed49ef50f6f9bd1075b -267500 1fa94c5777a0fb5f2c0b89389d3b537d5d6465bfd432810fc173dfed7a666c36 b4e5805d093717d9c5d8766b1ccbf2791eb10118c9fb51898f0c49273c3ace31 -268000 ef3af0dbba05b3633b87348bfa9492b90d0c500f8427c2f83e485ddb4e326b7f ea130ea23e47338355b0336648892d7c09251bcc9df307a7f587d7a425d2a741 -268500 f7d6e8a528849da7d14e07869feea84c406697ae7a16ccac0ef890aac5fcf4eb 489c417d04b8a41f630bca15696e7a05ce36d4d216c04b1a6560db25e03e3cdd -269000 0237cc909ecc6a560183034f478c44d9f9fc96d5a0369b89d5f9510676274123 e84c666b3a8122ccb250bef7b603c2afde722fd985aa36be484e76368f13f10c -269500 d342e101fa8308700ee1a663fd05b05da014141725d0b3655a3f0fb15da83771 93daf70fc7af5e7fb37d973246c434cc834a37a1fc69fb522f9ea5b82ed2bb2d -270000 83e4f6c8831be3fa7b6b6a0aa13805ae107ebe64f496be123a4ed9711cd69065 ef10852638bcb24c4341161935a116bf5b764ed34380ee55243a35c938fef7fe -270500 557c88f51ceba0d2dcf7bffe8ee8cb308f8fb2f14998db8b6c23764d00d756eb ed1e1382a827b3dbee6c583053acc263ef365697a9325d3ab3bb60f80621b66f -271000 8cf965660be26838d4edfc4ee6c9e3f700c5074a0537edf09d19fa8b25f9297f f717dc6ecf1404858433dea8353cae36a181baec3c8ab3fb0c8eaf17e76f2f46 -271500 940439c29f8259ebd1f7a7a76f9cb7c34981795365d06cef15b272ceafddb513 e013f425e7b9e0c919d3a8a6e584fda18d798f64cd32003c79d1b9acffe92f8b -272000 6aa33a0d087f0a56f911acfa99469611ce6a9fc336e2ef2ede07c854c0ac34aa 34612581d8665965d653cd9736459b2708141168a297c9eda4c73e64ee4b3511 -272500 e165b1f323ea11ebff46a9365e5c15c736a639c87e0e7866a790c212398fab51 6e2b03ecf9ce016d375afd28e4895a3905c5e79e64a451f4b5863d6f8ad37c15 -273000 7e8e42c625a39262e7cd8ba81d6042788c5685fb7e1925556bb81d87f23fc9fc 60337941f27f0191f55253642397b4141c09a3796a2e8c972154c90847a04adc -273500 50d2fab64d92e6bd34396a65ea083c254392b73b806c9c23d10a64fa2046ef63 def5f3f2d73ebc5c90d4a3e5e8100e51e3144b63d3de0fed9a6393ba3138f62b -274000 86afbaf7b386a0a5ca9199f42849ba58e03c52c3e14e4796be5a47bca65c3e56 9fa018f6e78596557adb6a6294c3ed8c02e5b07835258d38d00714b662cb88ad -274500 f4a2f13cdd599a02991bab088d21e7d28d907caab124755cda5b5da1a0ac3514 27a84bde9f23b95957a07f3950a238602bd158eb9fc3d8b7ba88884425fa2eca -275000 a655f397a1362429e51239e663aca0a3582f4a984001c6093e48c4e0a2e05941 c3a045ee8c5239615793c006587052cce7d63cc81c2ecb2af75e67f3c53a8ab2 -275500 b3b6e311d0f5bd738f2502c2684af690e0f71c2a4c55afd5661d069e604ef3fa 0690d029ffaee874f0407d12906116c79bba67f9b8378a31334b25483daadf3f -276000 f24a85fcd91ad6a82056c8a76c2d3d5d04070ffd7d9b84a94ad0d6b8acc0c187 5c21716aa2a15d63d306717b47e86748fb203faeb1c6b19d63a5349176e9fa06 -276500 787f090210f18af487a5a4f9f284f1d3314fafddfdee64723d3237f55d7597b7 3fafdf028ccf9b4ccc043ab7159a37ec9740b5cb34847a6ef427e117ed86f206 -277000 b431470e16022c9e3e58e772bc8db6482f309cfb72a197a773b67ee7ffcdb756 894962f8fdc8091b4f15d60a3ea4de232e7921227ec9092e4674338c6d0907d0 -277500 d4f3d44e493b537d6f5a6e63e315dcf5031240fbe6b6ac65a76eb8c35f5db13d fed8c64ebc096321c5b99ff1d5d424c213c3e75d13375645f37dc5aa807eb57d -278000 4f76c78fc8d544c1e8a0d0429f7dac32c9f0857f906944503c80f58d809d25a4 eeb4b5d853e4a976e994c9e129bad662bd03d8f2c7e78fe68bdbd47c28480ba2 -278500 494b9880d486e1151d466eb73004b3f226ea90b6127a4aef1b3a90edffd4d0ca d9b63101013dfd8dac4895a0d5ece4c62702aad7cdb81a6b186e530df840996f -279000 8722865896dd4d2351ef4e4def382a2e622b1e46ad54b3940a16f5073bb1d844 2ee3816538cef7b1d029887af7e39d60cc1e336036fdbf089439f38cf13ebcef -279500 3423afaedb970d2a590a0f3e023906bef4110f1389bdf54e2c4620c36b72a3ef 3e7446b32ace025408872375b1f3111075f305cc83f615ff2c6133e49ac96d88 -280000 9cb8d7f3caee172f2a7b8b8c2bab3fd01326468f8b5932bb88921e06167a0e31 468c01acf084fd4986b21d1c0e1defef6a874a01b0ec21be66098d53fc4244c7 -280500 6cdf47d170a6a5e57f6a9cfef7f2239d4f15a61d5c37f5b44a72188aeabd541a dc58435982155aaba2de5c124a9f441a90a575c9cda3f071fc9c4a3c9db61c8c -281000 3228123dd268365939c7fd5d9ea6a151b6a95825ee1a49b9fbf3ab9f3ea45508 9320e6e8aef527e622e610ab13eddcf82598b3f2b744f6e90727ebbad920c080 -281500 a35ba852d6be87b2a614ceece176b04152feb39a95e52e641e7da7c1fcfd220a 547cc277e5a3fe410e5265d8622bf0ce0f722c39c23b3274458f7f99e68f0ef0 -282000 2533068b9c436719d1eadc4bd7e3e805ebd949d57e75cf5e0b17321d109a9a10 1ee93f862e7504974feb14b488a590aa9221ebf331beae0786bebbc013278457 -282500 47262c1b2c424270254ebc4ad32694e51ff4c09d8c8da9e944b17ca3bc734e1b f940a70f96d1369af5b0318ee86f9902bd122036ace273643a8aa0ae7878764a -283000 bbaa0da5024d6e74becb1d0d62b2aa4a8ce1c3bcfe27c587d3c89b581f22b893 b8f67f07d3e46ae0436cdbe91a4eac1ffd8a8de111cab322c4895423393be210 -283500 008c22a6e8d0b46e6c785736f6098de9ac43d5d1964b2103ab383498623a53d1 77b3fa5d6f930d2da8b1171725e9f6e7ac340b88637955083de8a55a0d129b70 -284000 6273a37ce3e5fe2c58d6b1bbc1f31822f9e1f78e434d62c9aedf2c6c18faddb7 0e5422505c2be9b93d74f39ddb43b8f2a6cebccdad41d3e631e56a5c075622ea -284500 6dd5efb7d0636ca3212a14ec60bdb9940d355e75c4c3890958c2120c4e0e92e0 8adad9dc3bad71a55635afc41505883ae38fe99f3c96f021137e049a1b829a55 -285000 7d49941cc51ef16e04919b3dc5c5ec87b62e98267f173202167ee9a359d8a5b8 d947bdd3999caf548887208f2049fe528335634f5762d6882d4075dbbc6c6b1a -285500 c06cb12bcc248f8a0c2e764e2c160d85ca356ba7235faa143eecf42f7ac2f7b8 7ef16bd0db693d3ebd90f3e9152a8cc1c420a3c57dbb6bf02a86cfb3b1d19dd9 -286000 45583c3f15ca70ada0a0c38923bf9a7c63a82d7be1a05dd2d3d098fa6040b522 d497cde577489bcf9ea8e08eec093ae16e80f5c58ea09344c27bf55b98fe3fd9 -286500 94f13e245e46c93614627914bf086bde72751bbc3f88b35877d73bc28bd4a7b7 83245d666cc2a32058839f630baf72c0d96977e7aa4fc400f58e75f2f9ecf78f -287000 eda15ec5157413f65856008baef31e5d124c511a95716b1f6b7364f5e3b5e75a 5ac1908f2739c718feb04686b434dfa4e7ddfd5213d9977137354ecfdf5eca28 -287500 9f7a944ae0a5d2caa33f72042e674d47334445b2f47ac89da38e29357301a060 b7fca600d7445e8470e57c18e2eadaf73aae7abe888acdfba5d458197ecc1e6e -288000 0853047a1ac1adb0d95427898e88464c078405fa22ec5def178eb5de7ad31e02 a3369699142afb6a7da295ca36953c883d67a31d3096d158486b578a6a585fae -288500 eab408ff9eb88ad56e302df11a2513c1dd7873311632911cfdfce5ad4f814066 4f39359784cfd3619082b590cfdef0d6978434ad01885e66ea50f2d96abb2674 -289000 1eacafb1bff01bc0489b29ebc39bf137d040e6641170ce3dd89ff6ba59abf97e c8d5fe21e49f66adbcfa0c7d71ddbd5bfd2210554315f1142656f3802fb9de86 -289500 887dd7480f6c7ac0983d66c8af20fde72fd415dc9341eb28e1c017cc0ca046fc 64cc676cdff6225d910a798088789b311dd78932e090292f289b965e35812bfa -290000 d537cc92d4d860c7d1e74c77d63543d1ee28bfccfb33a3798b8fe4ee6aad5fae b1422ca72d6adfc0c8ac92b75dd68b19615bf27ce351c07dc461e4a483a01d36 -290500 1f72a0f641f0e7c0a14ae8aa3a90a93130a302bc82616e7df2eac6cc893f8826 7cfd6bdf925165f98609e9ac990d9c91cb484a1b0c4f26181f519180b2cd0ad1 -291000 045c570b2414764749905e61329694b5feda76d2656dc07c208e0f163e8d8be6 ff11ec49560b7c1264cc610daaf95d5bb7f581edf89568fefcc83bbef13b5835 -291500 fd55aa9e9dcba1752e4c20055a1c9b6ac46a21a3a932f059ee574f49b721f507 3575b8d9556832ef3d4d929787f0ffcb147cb349499026edc50e4be282b15863 -292000 37273300cca125ee3ecca17ef0b26cc7880ad9b6caf876a4eb5f248743433519 9e2e93489d99a34477c9e7e60d7a971b7e7a14f2b1d1af1d797d95c945c26d08 -292500 c6d6356e96458404221b2fde26482fa42559dfd1caab1b600f045d8f6a2302cc 5fd0c22eecda0a4ec51190a6356fcedb96e3d4662a03d1c231575dca131b801c -293000 d3cadc149d4b135ec11e9b97cd25d6e1caac6560b16c0d53a798fdc191519682 e8fb2e323adbb30a6ac4a40239c68d2377e9c8fc2094901d694e0957b9815cb0 -293500 a0ebf3b0b17cd3dfce121b5a4466c2a60a9ce0169c79aa070efbab912bc0bdd0 c9da3ed914a818f8973e44fc8a4d450e68d775dac064b9baed30d71db09323e2 -294000 492dad282770f45e70bc4cccb1ff2d69568a4d761395515f41d53d0d703db481 7c090581b9e3e74b2ae80d821555b83a563442f01ec32994b87b8794c8a94dfe -294500 8923473c7806f6175ad2be0cc98c4066e69dd2acf8e7f965fdcefadbcdcbc930 689e66a64c3f66de762b38b5cb0593b6c0f076c84a04823cb1f927f5d6601c12 -295000 3d5870c04b03d0cfb60c9d47169b81aa5c669fcbfffc602ae51b930391d06f7a 34ef893941a5215eccb47786b0d108e5150cee56d691cd6d54280afa5ce5e85a -295500 96c1ad430e0ca606b9da9929ea3e6644ba7d42c02371abd5d1a1ae099654192b 8e03c6f39a7dc904f768bb459ba01c623791992208f124c37bc679e61a49fbe5 -296000 6407e9c420afe4be97d10102c8cfc0d7f5ebaac40f6d5e678cac8144f007fff0 d19593e2ea6bc1c13a6a3269bc9d7c6ff918f0a01dcc61daac670b37d2d80347 -296500 1f8d31ccc299f2c5b05e93383d8926862fbc09ca5b01085b3a1dd82d5d495d8b 31fe78d77df28d71d73858589dd74fd5362642fafc9c8d29ba137126bfc0fbc3 -297000 9cfe512e43f2cd52ff58f90464a04f076dfd0d12d59cdeb100818f109a9003e4 5e47ee43df09cc31576cd9b0440c619a16298d39ab9264f639b5b9c86f8af572 -297500 95a02da1b06b1593ea08b020b4bafdc67f5e176dde40de7a1feda249571e53ac 43777410c9686e5c56891eb7eb0c37f2110b339e5eefb75da0bb28b78f3072c9 -298000 0d802cbe03a4b85c23624a03bb35290b461d8d9dcffa128de936649b7007f622 b5b3a839917d03e52ba179edc51c12fe47a6dd9a5c57d678299387299219d164 -298500 7e4e639258fe47ffca25a4b7bc7b908cdff41c7e1a737abfd45fdea1ba62ec12 a8c88f6180fdb40fc4524197c5eb32ab9bfda23b88c4eda4a422994710030d1c -299000 d2980e238042ab1ee113dedd25dd97fde37f474e6ea666efc83ad169c7ac4cb6 5f89ed52f8866c340657985291ef23e18eb47e0631407dadde650801b632c010 -299500 a3f56b859e1362c88c4ff21ad8cf5c799c2ae565f46f15bcbd275e7cb0fbef1d 2a189688c70b29e449f6b3bc93fe61d4b2eef5af756039f90fd745b47bd74403 -300000 5a2452a4745eaa9cd3c1c42b7e4482193c4f7c3324ef185a4d0a403d2002c0a2 0276aa15dc1d6f0d96dde0520e357fb5ca4d8469115a894dd76e4a34d79b792d -300500 d02571cc76f7cdccf536b836770aa02a0d238cde89f23f767fde8e62e2648735 25fc046b62a57b71347be8c33dbe9d201af1efecf98e973b35294f32b745fe25 -301000 b8ef5fe2861b8750589ed344c9d8edc7ebb9630dac0ec507ce09bdd532af32b3 bdd32f8faa1bebe0c4d250a309d8e983c5444f63b8748eef76470b980c2542c1 -301500 573f412e4b6a3a7cd2506df938810bee7029b9af102e096e83861eb3b29647a4 e8fb5de4c13ef24efd099f7808c0952e287aa23d51a96d37ca919c3fe08b9685 -302000 18b4cdc5a75c82496545009007b5f488aaef67892f6886bb36ec2526f02a5501 c8898b9f003e3a651e963ce212412e35d3d825ad2170cbd1cc56bcb1f7a0c4e4 -302500 ca57a75391cd670c7e1ed0fde565c1c15d67ac4fadddf92549874fefc3a51c74 08a7221ce567158af54cd9ebb89e6cde68430c185f6ae18f1c4d7001970f0dad -303000 e6dcb8971d8b0e379173bec442b5e465d02e700b30a79598de9be17a5497cb89 41c38012157119f65a5404f0e62a7656673f033eb64e8cf4275bc81aa4d88805 -303500 e737b5b4805e4740cc8c50d60ce3769621294b1d20ea8b1bd3f3757c2a37e1b9 b5aba92d8014d56fa32993c21c908b42330c6ca382631f57162cc63aa1b842a9 -304000 9e5aa8da5821d8594bd9ed376f69dc851e5a7e0b4cdd755c6394f0eaf76d0e9d 225f9b063c89eac0ee1e3136e644cba4f65fbb475fc5a0e2c1fb66270f6f13fe -304500 45a43ebbca6f1cd31a03e301398c2e9e9d15f1bf91db745a7417b4d8f25ac394 4246e0afd88d5225b8ed8642d8337681f42952d0df01a71aa94d268790755cf5 -305000 153be3e755e4953c3810e08165407725c11fbf92665616c708bd3b824e973cfd aa39085be20fd4450a1a03bab45c09f669a0a50d84219505b7077c0bccdde28d -305500 c488fbfd55f3fc873ca49d57111f71aaf5a42c4bbdd720c0d96a5dc66eeb6736 546e53c9ec8cab56e41df87aa26122e2cab4077646b800b63134a712a1e3d543 -306000 83982570d251358e02e1b359a0d95b96b9f64f3736dd823654d47da633d48708 6a861e2b1c87c8002bf0794ea718b6be98b4d77ffa95a22a3decf18aa985bb25 -306500 96485ddc1d2d81f38a752fcf1ed3d7b734197c472e8ccfb0eb4ce3101a473394 068dc5f5f5064a475c7c84960a192433e9bf18098d581f0877066c60ff0a8861 -307000 0d209df0e3d2879d8a0f356f7d4041d6e0825ed0b33011d5c8db9bb1ec0c7d42 1f41650a79db8f7bfe188f47b7f1bb293ad4f178ad4cbea99d8f87876b68ce91 -307500 aad6c7f578667b9527223b8e4785e9a6739169528d9b0bb741119f224e0125a3 d56e00856dd907339c3959733761bf3d2ed206bdad2bbf9d49e8ce6cec4be663 -308000 1a02c273d30fd2bdfd3c0391715a78f6223c944db913c846927b8a20289ea527 232e616645960a14c845a721665ccbffe5a70408ac38dc2f9d53e306c40287e6 -308500 b5f04f2fd81500e1f7d817b94c566b97c38cddb21041bc5ad38757a1d11c3a74 5596842f2ec00ea253eb5a0a5565d21e871a511caf4a40f7e559d089ac67ae08 -309000 ec31bf5b86d611359ba7818f0926b3314c13e7fc6be4771e78aa66c65f308e1b 19be4c08d59662682dcf27d7cea164915e94d1ff761f8321d6302d7de2bafdc4 -309500 a40c3dc8a06147b339366c16bc1a21d4841ffffb9721f952276c35f6ebb0fc67 161fbd3c4ba1d443606832471979959ac0281462f897801dfc9e4a48d03df741 -310000 10eeededb4d54ad661d257fe3ee8b383d88ea175da4eca06cb0d2afd91d705aa 82535ab42a3a4494e51e508dcf04f233df0ee6869b14f12c2eeb3de7d0d9bfb0 -310500 5937e9322a0b8b1886bdd639f3fdea48392c3a1f3ce5c729f4300307b30a9858 463320d4b753e3deae3eaba1c7c0c81de49d883a7205d34efc6f933287bec340 -311000 106bcfeebd4f8d313bc06f691e30560fc6d5fd4e8eb2d3aa6e5e553d5d7d6769 efd1663f7e472207765e064537779ac8b52090326f6afcfbaccbcf0dd5c7cb49 -311500 81c0cd746d76874a8add01868bcc5465d7ff0a28ef2ba742b75c6c89986ca3cd 1e89778081b0b13e825bf16daf61ee16669826b50efc794cf871ea170399ca1f -312000 bdcec2a9a093b8c5e6a3f712c866bf78e720862b26918e7387d511de18af59e0 96fb2b8bdf01cf8b391a87158b880f38acdf15a6f761abe2cfbcbee83478566c -312500 a9716ae91f6c1577726c38cc4fddf8a39f1bac41cd1d9b5605e52184e573d6c5 4fae3413451a71a5f1e4ad71341035c582aa1aa721ded95eaabd734137ddfce8 -313000 cfa985aff09b9e7f22b17a600cbc428dc8e2dbb9c2b22420050ed8dd4597963a fc3335bb9389d77b4323758d39d7391d4896b94ad440a66b178b9366492fc79c -313500 959ad500e00153dcd9d8b6a8cf1190c799f69d3c5f6dfdff026a5d78ca5d0c5b 711b49060d7eee4f08a198fd3fbb3c611915c64cb12c8152210e9c4ffbbe9c0f -314000 ab6a7acb2629ccba949934209d7dc9cd895eacddcd7143dcd7eda19604ebe05c 3faeb9f09e3a75ed2247e4e6352c5744e091f5f44792ad20000721198a075c79 -314500 d9527af7b2e46e049c738a9d40f7720d8ac2e8e94b847cb8884d922ed004f543 03476229cf97cd0f2813169fab1ac07b9648a4dd86ea864feead69fa34dc498d -315000 626c5f923088c9093b00b846a1ee92657bae30a36370f679804743d1decf948b d51b5ca87ce3888f7299e3f2c0ab7f3e28afeef234f63337553c972f6e688be2 -315500 2446c74456b4b4b216b760d567abed176c12c2f474459d6be711490190904e07 23a8dd7d4d710ef6a23aada5e4fb960bcaff7873416c6b9904e1cf61c2abb0d9 -316000 32e55b2ff3cae917e3248bfdf7ebf79cdeb323cacb54348bfdd0b1f411c92186 ed4b4d67a3f55e5e3247f48d32ff231d24ef6970f8223e255c2870aa2ddfc92e -316500 634fd61f515e6ab677e142e73668fe41e462f25351383262b369e1a622bb9784 0f6cfcbdc1408b6bc3cf64c897fb67126affe7e82ac682707d90894d0c6768ed -317000 1a8b1bfb7cf59f0ea1d7141f2859a289b1cc0cc312836f5754121000a5a08dae 189e9b6ec139450bdf78eb6e37a63c60a13551e1b9d0ab737051cd5dc29dc445 -317500 d2d2e1c03ca763382245658d9e13d60db1c11199930c6edffa504cea704e9cb4 5ecf2ae923e1b0ad4bb52dda4d3c5b6ab31dae5a1152f40688992ac56cf7c1e7 -318000 14c481ed71e0265d9971041215ffa9d80bd9ae3d8a20bdd514b3cb15e6d820bb b83d25bc14861317c60d2a38c2cebc995004a3164e49dc4109d195ce719165a3 -318500 fb1bdbe68f6fa03555a52cc7c70086b585d1585bad7e7f36bd7849b20bd62d7f 56c93b2ec1e226511dc23b53e7c6992905a4c4875ee9146558712faf39024595 -319000 3d520676419671efd72eb59b19a912dd30419f5d50f9dcdc3faa15797e8b78ee f0cb1c494644102763b745ed186810fd2fd2443abbf4c8ef02dd42e20e344e35 -319500 e6f93385e77b36b8bd02e95a7be1daf93e43c2c15df61ad7a53cdf76581c93e7 8679904d6abde60c2f8b0628024a00f1357357852ea5e0085a8557cd55a3d5b5 -320000 edbd0041bf7c7fe4378c089724a0dc3d91bcff7efae1aa5a5e9b1d914d9f4255 83d2528f44d5537305cd76560b0fe1da24549b295e84a37ebc9f7e442f59a2d6 -320500 fe6af92a7429dc15ded665d91c0280feddee060e7a12cea78ab54f591a2a97c8 3840d83015f1c9053f2a74305ec9aaa4ab9c8fca66c62b71c898c0d8e40f94a4 -321000 09fbf5bf7f04579822b0643da9de72f9ffb4e3b086334876dd7ebd4a0b1e5456 3d01cbb877ed01843faf98fb687aedfdd63b6eef204d7a08e5177e93b6315237 -321500 79143aebef47a364850164688450127d503fb0b5fbbf6b3ff422a655973699da b65e2511ade0cf401a38d1089a5ee4a0747e003fdc2c29cd48e47b288d776801 -322000 03aa6946623b9252193d58e6dd00bf586ad4f57dc8fa04dee924b5c15d08d8ba 378b057486d0bcb43313d5206b5e08eeb06be740ceb84456f5cf8549e46157c6 -322500 cf8971a02d54a830b3729fb8f1d1c283135b1a7e30d5cfffb4462a2472467d66 233e6d4bb154d5d3fb1739a4e90a258f0910ceab33eaad183fd2108d8ed464d5 -323000 8d6c05ddfebc0476b7ea506c6edd8b1e7a1f04f46d3d44c404936fd8c8c97089 c8e2bb9126149c636285107b6b51a2ea4dfae6a9362ea82e9a01fc5b62317e13 -323500 f92d520784eb12d8ae3c11ad1803d5dd95a497c0084c88784702a5acce66ae41 81e2f522cc756b27794e1472df684a598aa925938ee87027d455dada0d2835e4 -324000 4d33cb6af695638f89500645f741981a2b96eb2b6f1361cf4915e9df14639412 0d5d58a71b6fb721127f551a4744091aaafc4740ce74e1e094783488946bf46b -324500 9cd5a93ac51080a0a3dfa6e7612adebfd307a7c2ea510d033368490c6d25b7be daf9a838f7b869ca77d3d1fbfa8631bd99aaf46967802148dc7e44fd261a530e -325000 ea1bd97d2e59f6bddba189466ffe1e7be63f5574f110d5b87ec3e0294b2bfe5e c4d8725f512f352599b2a7506b3c52e78012eded7fa5f6bfd99058046342b2a6 -325500 df8156f044118b84c3e2482e346c5639a19b2f1583944286cb9550931c3ca0f2 4310bc5bfec110e5da8fe1dc798b18d1b1453895c70554fb4d52dd7d6d7d813e -326000 d46ca9a4ec0e9126c9b570d00f7b47a005d51f25d9fcbf0c4ca71a29a5f255e6 426c81fa951ff0ceab76207fe576bad3be2279d802d5b95b45881c73827a1241 -326500 603728e060b7c7cfa603aebb548a3362364f3ebd83b07742458a412777ba9259 16fea467df6f746c0a430e00b12d568c7103829328a2bc9b57fcb55c74a66bb5 -327000 6913cd3da36dbaf5c6d407da68f46bcdabeb504269ea70c0cdc219590355796e 745d85006082600149a72c38c32e2d378917153b7c8dbade476f6ba32726c893 -327500 b6538b2705612808867fe5d1da0fb00b6257c3a4314d327b0c6403facc8c06fe bf9d4d5ad9f15c14615c36f8cc7ae29defe64971c5824f95aa535c1bba7083e9 -328000 ff013ae3b0bf04df355f954637c6ca2510479c51180977a99af805bcc8c2d63a fad93d54a8cd267fd2e63abf1da6b26f2f9bc1febac401d4731af0103b31fc6e -328500 ab64d04f26e2164824afa50c1b5592c172469531a20f35a38181993a087a5cfb 24d35a5eb7accd3545888e4c525742d90b01981447d1c2969ca744181e4d6b70 -329000 79384d9bb22811755a4bad2ca7d238243ad975b956019cca645144215ead0547 295fe151911572801c0d4e1ee4e753852edbf6078d7bd798dc5e2da10692e7a8 -329500 1839ba9cdb5db971f72defa707c006ef6ebeb93dfff2bf36ce873acd327531f9 a930915c8a7d58ab4774dffb87fa36a6f9b513b466bd73e5c96965f85ec3300c -330000 829b9c203a0c146c2794aa0ac22bc71033ddd15a68959064526afc2722febf94 e09093eed9d282fce0825778bd7d2c9415fa5b9adcfd2263e7137537d861d29b -330500 740e9f27889b06a301e355ef7dee62cf10dcda17d4023c157c55327420b308f3 a298a8255a0b30782c5d968988514e0437f4cb34a0a2f7df8475a18809007d1e -331000 e2a4cc3a53ac8a24ac52f6fc574d0e9fed0d240710de0694ed5656abfbcbec46 74e67ad885d1f874c4ae7453085f29d254c684ebc71eca3af50f3278c9e1c266 -331500 afdc42adb73a6717f48e35b3b51bb13dc6233645b8a4805723dd771062dfcbdd a3988534eac8b2c3f5d557d1277440783c624597b8b922df33b6fa38b824fc33 -332000 4812ec71190df534e5d8d4965492cabc3606e51c11e4f9181c470a779926dd7b 3d1fb3699e9f859472fd032915cab01de53232e123b1e4c93db2871f7c2aff6b -332500 50ae97dd398c25069522d5eb3b45a2332fd045f6be4d615c7d36c7ccf54c6c18 0bb46697d721417a2217fb4e632513d2ff82f34287bbdd732b9e2f893ac10df3 -333000 fdd8f58aece53dd4f24881f1007cbd0ed25d9f3c62f356a00dc92aa68a13539a e0ed76c2c22a2e784c8a689e1032cf00b65a2702f2b3f025c78e2d1e5190070c -333500 5ea2791919a4000f9e363e277b7522fd9ebc9c06ee5fd9dc15e4ca8984a2d8d2 69d3bcbe827a926dca144c589eaa175f16b6e523b487773b93fee7b45a5a60c1 -334000 cac1a3b80353133e863014d138b408202c77a5759cfc5642546416d73f66ed84 9005b02c03c93c41c6c78357f4323a3234bf12db1eaf36e81c1077a324f7a07e -334500 50861ba6d952e1f0fe4dac891ff4339ac5fb7094205767f2d6233941d2821c10 f77408c3140c620c63f8bedefb370397dab67077b4168c628d787d5b22419aa4 -335000 594b37798c188fab76d6d65c058115b58757893ec32173b45bfc618e8c857fa8 fe50dd76cb7dbe52cc6a9f6c25a3497dc5e4d141e59ce1bafed04367fb155b3f -335500 69b0bd40b74e7fd15be354b734717bf197f1800bec85120b26ca21ea5ac0255c 58cf057f1edd07227964239e7d220b4a6bae95793694841f7a06479c5e5f7420 -336000 71631092dff7d8d09d44bbf35c187c7cb5521c7a5eddb1422f790e52107b6797 e3bbb2e549a6c857855772ad5317902ce52231c464fa78a107811c8381629a49 -336500 ec3497d60fb7d85cfb349bd96712903aaf8a86e6d746f8187a54a1aa5b7b3d51 dc276fdf1858b7a7600213f9b06d4377dc53ef54e112efc864006d28c6cba3ff -337000 70b67fe1ffc39b65d7c3834439efd501fcb9e5d31202322a878be2cb78f741ff b91daa38e81b0b79bbd48c50f9d5ef92cd965e729b075e10b270e29effadcc3f -337500 c5df2f17757c5cf77fc421904662468bf003326049de85bec43003d97a5fc47d 29d4cbe540e3ac54271d12308edae379b59365521ee2f09a6585a82a046d7550 -338000 60ba652d7ad31c96015323efbe454694c5ec72dd732c8f4578ec2f5d072afbf2 2e3a1bbd3ea4e0f318830e43b20d53162ab6b6fbd2191524725965c549360550 -338500 c898aa2617812d17eaa3f8ee142c3018fe2807862ba6d06f309b3344e7d799ad 6bdee06900bdd6c83f8fd8538d75af113af8893ff99cf9a25de6842d3f0d9889 -339000 e0d97756042e78b1c14495a68291e5033c39c56f37a48adaccaf350b12f59202 913f62e783258b88638a7c42b2f403328b683f8c657520ab723ce2196af69666 -339500 1dbe406aeef28cf78b7d43eed5fcdd8c9d7d6d11363cb7e595d7bc1d1899140c 8cee4f37f98fc3da1826dbb96aa525a49fb1fa6db5b2bd64dd3bbd4fb7d6c238 -340000 99ed171ddc0aafa8a5b6f9e5890822c34f6ddf4bf63f1488afde10526c74c8b2 ffe05de29a9901370e815a782c7478c3075f8444ff473b20ff5a2ab311a63022 -340500 92da105d515c1952ffbdcb5f5b99acaa565500d8f4b6e45aa093b61ae53fb7e0 852c42d37d42f8d2c740e57b8e9e769e72445f57c8fc9d1f91e62f029d7d985d -341000 da401dfe258750911b7264ccee0de1b53bd7b90f63d73f46ad5d5914203b59f6 84e7b57cabd661c1cfb68407595a6a9607e0dcaf68f74dce2f8487b1f43a6ac4 -341500 ada69a2ac0977672d08682d195934176caaa7de0baae2f3a32b1391ebf550eb0 cc1d077aae6a1c18f60c874525182f8cc211cfd0a851381773cd0166c108a43c -342000 ff83fa02f1e15e52a1e6ab3f8690bd9c4bcc7f3adf77dda003c6871283b695ac 5983b9dee33342727befc15d5982f9ce987ccee38fef71c34c482c92e062308b -342500 cfcf80f28aefa27c6f09f71080e4af7bfb33f94d1c47e80633187f80a806c6cc 08f62f928db36fa7757f30edd40f93c20dc43c65c693ca5de4c87467d40377a1 -343000 55e1b51f72f048231b675c90224571930a59146003b4ddd3e883bcbe4c8c2685 1f6c53f636480ebaac6569f100e804de9a604dc1bca0a626004ba9852f2fb546 -343500 3d1f67b0a5d905f15f3fe5a7a07aba456ce3ce41422a3bd94f92fd19ce7960e4 4201088ace85294f87bf646209d2e9cea09ac2587654d57c8105b016ed3adac4 -344000 1e718e4e82839b50bb5409297dc94bd783264f1bd3da639f2e4b5444c6765025 c2e0bdb2e293d2940f99295b59d2fd9b57a02632605bc66e4ed69de4e26c4afa -344500 aee9558284286ee6de93a1456fd3cf6c81ff542b4c1eac2c7694b869742572e4 56b70751d01bc1925f288a0af1223f309b7bac54e1cde463ccc9667ea50c9ddf -345000 852cae52d99ea4f4f299f1b5f4a7629ab0d32f8693f503cf74a1f0a31a9a80e2 a627a26363ae216baf1774585d1159977d378f34b54119670620bb82cc9784d1 -345500 09a3e1f7d56b1662f10470c2497e662495b62065364f40dfefdf8d34f5939fce e4d96a1576f516b5303b60dcdded21cb4e3f382f4e7c4b10399ea4b6fc37670d -346000 3dc0fc157c00c40ca92c8125e818f8b5c6163761b0c6955a88eb48498b1d6a45 6f60e0950cb6f6ad48e5b56e9e94a680ac85109ea90ff94df6ccb58adc44d3a2 -346500 bd5552ed2748d686ed3540c52ec7a0f97b839254c953074357fc019667d69188 d1707671c71c75edd986ed69fa0d8462f1d7aaea3e0b5cf519972cd3ce7d73a2 -347000 68b383fb101b4ad08a4ab58777b9f3e34c69143bc3872785c281b155de8769f1 0105724a536021bd7c8fbf2ca7e433c247009c97aa48a8688dc7c9af88018688 -347500 af3af4870dfdc980d2bc5c946e773806957c2f5d98200d5e9ace72e4301d0ef9 20b564b903b75c62b5c7bdb911c753fa67a547a47d47e5a60a0a4790362adb49 -348000 e72024ff3d0ee72f4f78b7e63ade7a7ea037da43bfa9deab400f6739fde391c5 c0ed8b08b6b7d50bf86069b1e8f6c7c36435817114e27745be63db96b5f716bb -348500 1d9d9ad6a6b1a8d5392aa6d35a7472fbf80535ee334a043025cc3637d9894db9 101e9ff2c05137c25a2a270055264bfdcc81b290826d968ca94de4038f791790 -349000 bf0cadc56a8359bb703738a06f7a31b305fe7433989e7e4094f379511e27a19e 2a2cfebba2b09215327049cba461b4c56cf54cf31a0d3c6f8b21a637e6a4db5a -349500 78065cd5e2af5a3a4e838289be5d1460605048c1cf2fd1ef9ba8c88619631e91 aac94ac665bc7ba954323a07216ac1669f19bcae1541459f41534d8058dfd3b5 -350000 937db7a154c0d4c5043fe8bdaa0969670f132252a6c6bf8f7ed5858ee11c97de 8c276300614c430a75552e0cca7d83834ce7bccd7ea1d592012300ac2bc5bc66 -350500 6ebacc5b6fe9ff0e34d64a047981fd170f1b13d40139073e6e65da9a617fbd18 f181abacd6038099f96854c2c0ac8f7d19504609f36dd0aa085af150f21ef930 -351000 156a0053ebf2ee2e68a7ef337edc14044503653188c60669ec924fde43c21ea5 dd728a51d7f9e8f04e74e2116698305470591a6e7937b2c4b714193843eeb584 -351500 5cea6cb5b1b96a2641bcd705ae86c40ce7a8572ff4d6815d7531ebdbca13b958 fd4148c5b36775f35873746e962941ed43d95db28ef21734f4351f1d8a69d012 -352000 43dc3dcb74fcab2f5e90992eedd8a7719f7b7c7658b2086583ef881092f88aa1 eac1623de8acd8fd497f9da85f85614f5cd02c69aac6044f24a3685957009f58 -352500 6b895134f53c26c0b24e9909472962abb3dba5f8b8ab65693ff8e45b3b77e566 aa1abff115fc49dbd6847ba4779ee7c514dfdbe3895e7bc3105b74d0fcf1f4e4 -353000 7785e099822d5b6bac5c707ea57d5d2cabeb52e1e2d82619c8bc2051b486767c afcd99c877d144c3253dacf018ca36e61e95761e44f993e0a4cee0854a7030c4 -353500 c0790882442b7ad61aec5a64faa355a8486f8112f9a691208f38e9bc96230492 f7888632b88cc7800d381774153c34626ff63d859ce489286d9fe904403e9ec0 -354000 de0551272a32e89def017385ba1833443c4e2ec02196c33739deb8bac6cdaf25 78038315c2d8c142ae67a01dfb98009847380ad96cbf6cf700af8693f6260caa -354500 c2e4b7243560cd6e4511d175e2c3fe98df223524124f44faabfc252f57d503d7 1d0fc9a93c812ad30f81462a5ce1fb62d74f14a1672e69dee3a3b797fde53270 -355000 1a11051121727fbe8bf80391ee403566e3b0dce4ac611b37a516c7e3432aa231 f363b96bad7663c981865cd98aa36aa2cadf8b4a623a030e3c7e8a58dea81992 -355500 c877ee5b39b2a7ea9723e1c90b2e307f861e42275c826ecf5b6c84f97c120385 d7cc21f18f45fcba316afb516f70ae028723a709a1a0ad2994579078aec10ddd -356000 4226d4f7d74316c4f9baf33868b492a72f2a2deabe02b5568ef40606641862be a364b4408c45633b64ca685f42f4be377a4b730fd762f28e0015e2ae6e23b0e8 -356500 f0014d06574914b9215379d2b187dcca46081a5fa27d6a32a38efd382a9e945f 853c10ad51f992a4bf0c46c8471046641edaa972c537c8a92b32cc79ff80b445 -357000 1c78c05a5a6c50b6d0372745b8a3f0ccbd6c4878e5fe2227c81bf36cbe31fede 118150dac00bdc45c95b36d35a57c63379205cabc42f8da5d8cac3f8198df0aa -357500 44900087fce8f2c01a87a2ab15befccc1d9b9e702b17c0184cda90876a07fc86 621888deca43a1398ce69ef2cb1ea7523e563dd552e173c3af45eb3f00667df0 -358000 40d642581118288429f0b72a73930470989ff443944b7215edbddf7ad8596d31 819138d682f96c5be33a73fb51c7b698f347c76086d468a3cec421b5ded9bdef -358500 39f707f88dda6ce8bc39c64bdad9d1fe29f98b517080ed55466a8a221ee19bcc 30d012c4929eb3131b7f50c34986d7e1337b46ce6ae7065a0613ba6ad336d2dc -359000 8a04b19b8f068b14a987511d635cdc70ea66e37b63a5c3750bbf9bb2881439ce 7d053e5b5d919b21a1ca21dcb5d31126f519c76f8c0d2816555816496229c970 -359500 15293eeb7f425f8f041248d3cb15cbedf19eb921389a4425b8a14a30d9f6f08a 5b47bc2a1eaaf8b83461d28c535cb1b6b376826c9b554df7498216cbfbd5e76b -360000 37577d18f84202e74e17eb9fd38e760dd94096b4623917c8fbe4eb8c1fe727b8 985b64f248199de5acb5f6dd54aadfe6b2eec0580ac17701e1a6590b46830cab -360500 2db2b88ab382de78f62fb710454fbe0a9e07dc7c09ba76ef26bf72e4768b8cfd a1f4e7d6f52f1fcc610793c0822a6c9a40e0224deb7e56495d34ead537fe2fb5 -361000 3891670905fc1e7ca588a4b72a30c57749cb7c9c2ed47907ed3a69c7339caef6 164eecf5a84889a1ce42accb7ffcae55c4bf598b13720c34eb403fc849dc5801 -361500 ebe6b83861d092f8eff3579515524a45568c743e7df656feb775c45981251891 ba453dda58aa37da9c4babea1597815a99cc4bfc9aec16fc3f8ba1d85a031574 -362000 8524397d4612f5acd6fe921ca9de4e9338e2f74221d4d1755c3682fdbb2bdada d9de4ba457b0d1ae37a2dcb9c8d921acf206e96673d45346ff85de620fc08334 -362500 244d8c96246dd1772efa9b6dedf90ed9933f9a1fef43a5a61fb9d59e9e19645d fbd24f0a05dad2f8048794e8f0c48aef1d9419e28e125ead88eb1127bef72ed8 -363000 2d0854b709d2c4fd84c1d66a736c4148a3b1001fb083f1acb38aa34416063487 eaaf97d25a09d024b71fb1dbe1935a8cf34bf0d30736df8e9a7b6fcd4fcd63c7 -363500 eb76872dee58ba1a3285a93cf5b257a12a903f9f628828bde4dd320ce44ea11e 2145d5e2136393a6d205af57d6544782db4c701b6a5b3f14a90528f30cded69b -364000 043d7b87efe77f8f2d34833a08544e15838bd8b8e1bcd902d8b1ba9dc30285f9 71ad76919b65882a929954ac642c401dd8f298faebf7208aa01301815df4f32a -364500 10b77b07108cd3c1b5166e51eae74df84f39313508e8093af4fb5a5c8db99c8f 9738d20593ba72b8e0f80a8c960f343846b639d3b5f3ac623ab7d7d0258e8c61 -365000 a88f0052b9b490639e238ed8d2bdae3ac573c598eebc036fecfbe8d0d651cb62 806193a3ff83178e6847129340bc66f087903dc85e8d45d50a3843511625fe4d -365500 07674af4f751c8a09011204107b77df887eb0989580ab710bc28f86e1724b972 a59376d69d1fd2b3601728c2eb2f3f935177f5abec94f9b441a6734b8c9dd57a -366000 e7f0e9b3671c1fd8ac289879d42ff60cb2decb8c9fb8095152e444d183d33d55 f04e0f59196d771ea62c59ac3882474ecd053519d37899e2ce9bb2d1a779b3d1 -366500 28fe13630301f2809e429288503e7a341a536de22c078ba11f5056400837d18d a3a2aa196a595a7effa0e8a3ddf8197fa3837c1a55a392f456bbe2745442d844 -367000 066c5da3bfb95638c9b0c37cf99fe28f31cc4852082933305b1561f8b289ebe2 4d69dc379574aebfb8c507bc6791adee838a066e7de10e2e5d633faa6aaf7927 -367500 ee383e75691d5d76bd0d84fb2edb77a9f3e453fe14e3a0840524d4966eb3bfc7 addae0433c1a0e30adaa6bc21dc08c4c37c7ad6d12109458cc8b9c3deb4fa80c -368000 7718d30ae93a53584971a1aae7c71b99f17332702adfa3ba93ac53faa3131bb3 00d48572249cc7eb9929065f4d8e5a4268b69c425ab521e974066c7a15ba96eb -368500 49160ed17423768caebf15a07b978b51b9a50f88cb934cfcb2ca335db599b313 252c55080a47e986faa7b8e8321239a25b25d5109f3b60cdd66c2d7086c32bed -369000 2a35afabeb4c08f7e0fc8564b016b65792e64b6beba78e5d7c0641af63530170 08264c57b5533fcc49b365920cb2d8b698be6d412ee0693e4d78d847530eecc2 -369500 003a85d64df7bbbe1692464040b072934789d092d6f866338b0e9427e823a83e 7084540c646571d0af1e383b6753e92aec196cf20c88bd913e074ff05dd63502 -370000 434d40143a0e8d8fe2e00984effc5579bd3661fdf33dbd93cca7fd72351dfafc bef78b640aacd4fd8598056dd42dfd6557355ba44f18fa9aba104eba4bad9738 -370500 02cf8d2c1db6faf3e7755a2b3d144a4936dcd9f34214f1c8aa826465cc3918e5 24b38a6971f48836c71e37abbeeff129d21fe5975302103ec2af62a337c33afd -371000 2534f9c4ca46fe2df863db301dea97a3bfc6e5a3645f4080d221e9fc214efc8b 24faf019a5e3c38e1e9c941869b93a6c5bb2b2e3e3c754c37d83bfe009f78c20 -371500 1c3ab21bf75be98963553462f21fc369e7503fb8699d9f6e1f635a952c55db42 8dba0c68d6c580055ce406b81e3262b9c7057ba8cbb8b221130766e667c878a9 -372000 b7d862d978a007b9e4afa1f2f0650bb20c0298b8bbce1666d58b009c07014bed f070560c4db4d96f47694e25dc96746634b3b1f172ae1efc8435b29ab083697f -372500 aa2c34e6c03803e0edee9675926dba87db1bed0c89e605dc40c2213a330e53cf dbad4244855f790740309f5f7e49755213bec4d672cef6491758cba12b5571e6 -373000 c03556ea141010a523c44868eca127684b01e83f0a76090906728aa34e599931 b2d61cc71ab0b18171db2117a6d535128c25e68031c3c44c059c7c7965d05c53 -373500 b61ce82c38d812c1e72a830b062bd3854701409fed42cb8cf89d9c83a68aa4a2 3cb1ca2e543310ff8d22cba4bfa2973e264837d2a4a5052cfccde4de4a4a477b -374000 0a2b671cf0c4e82c857482fd9eae13f8212fabc508c3f6137fd3004038d2fb7f fe35de23fa234b6dae59ea82cfeac3259eef5f8d8878aece906a9e71121ed71a -374500 31b2c402de5e4f0911f5d14b927f38483fec9234b0ef67efa026a3648ffd12a0 63c1e30437b3fd68e0529230da7123339e9b8d2079576d68221897e443be0e3e -375000 1673933d5b2d1584e3c923b45bacbae604b308007ff19e25999f5a1d89afb040 cdf2c192e290686651e7f63bbadc54d0d8f7b1d2f7208a097807de32159451c2 -375500 6b35b7e04b2d788de6e2cc8909ab7fc5470b385905dc0e7b7b8524ff57d7d7d3 ce795b401b8cc3db0def999633c2835436348b032919c9123e1481800aaac88e -376000 9a2ec84dae6c1b6dd358c57205e0858d987b68bc1e029cae1b8239ee5ac181c0 d576e0d718d3f594ef61eb7be25e4083d1ead1201fe8eaabad00c63938144f85 -376500 bca044a02b4bd78ddd32eb668c603f16f14daaf04cf3541d019d3421868a14d6 9abdb75f5d7bccf402e2e02a07b5e6d5205822c4ff20ff5531d29d4a8cae5d4b -377000 1b4b732e1f4b18b744aa40196b7bc5d3e1074fee1beb4efc674e38f16deea7e9 04755ac05c88590c66be5b72ea85735df901ee644ea1f35772b82bf18c2eed13 -377500 a51b1aadb6f280e7c23ad430b8c59c8067f0b8dc10a0be61666d1da71bcfadda d8eb0789d6088438ddd828d02844a644a2102dcda7614b262daf994437be74e1 -378000 82f6ad88db9e44f44c837c7a117802a6bc4379ba9141c4faeb9e7731bec60f35 8c48f7630228d3c0322986552aa96929eba1314f8c62baeb801b95cd3cf400f1 -378500 c2fbdc981504762cd306473faab285e108b27bff83a84a1460bf513839d9ee93 37a18476810b603df1cb7efbad84e3b49a24676073397977eda35fb559e7dca7 -379000 5866ea5d40e02e5c73a1828d3c3bc5ffe23f9702292ba595560908f66b23366b ffd0dffc4b8703364b9885055b427f2bea2336714ad4c5fe567e1efbc8fb7b62 -379500 2519dfa5eccc5f59b59c89bf35ecf2aa0f5f8b43ccb098622def88dda5177b36 56df546c0e7bc87f0ca01ee62f0d0939810749cd5fe68fa4848f6f302052ccc0 -380000 7bfff4292f5f17bc71f6763e2257fa585c6d56470390648079609d8116988255 e5c4c441e3a8f0b5f55bb8f5ad18a9bf4bf04719a558e2b954109e5c47cb9896 -380500 386869e1fc8e3f7d6aa8bf28caac3d5a344330e974a42704885aea3cb459e179 279bf20f5fc0c66f97256a42cecb4597dfbee3eda52cc03c01239d2be7ce0e0f -381000 86cf8da3f13d65311d707cbdc932a563a44fc12e1c43de337583bc0d113a5a03 733b60f69120d3ba845a388871c75cec4b4e2479ffe31d83c0bfe980133460a0 -381500 3ddcf06f6b302ddea992508dc99ce57c1a7922d05a89decd38668c974c0d3d41 145aa998b1e691947f9e9c1f9d7bce235dd64fb3101664f2c310b59479a49954 -382000 5cbf96c1818addd8739c3b0a928605824a71eeae2cff1f520e644096662c6d95 0282ec673961b684b9c2c43f17dc47d7a1c4128a19b4dde559103986abf4ca50 -382500 01447f3299aee987ac9c9294682b89f9643f28bf18123ce8114b3ffdb6a03c5e 8a0e1f6c67098b89b81bb0769c520cb50a87299fff5497a87486417b43efb9f7 -383000 d5efe4b385b101b754b2b30f6f99c2bf3736e9fd0e5a06d0b5ed3064e7641852 245a1712512d17bf19156fd5288ebf706e85ba49278ed03c2d506364e7002e08 -383500 5b88888d1abb320e7d295c00a15bd74041ab35850fa768a8786d2e0cfff0948e adbbab8c600e751c331a054924b778213bef9b5a5e23f3d9ca8c9e3b877d8b30 -384000 def1f25883b2060a7b02f078b184a1fb50ebc9b9ee8190971a6315386382328a 31cf28e8a9ff6242a0e4c9b2ba30c018acdf9279b8326185516851a41a15535f -384500 a08467964a472ee61fb3ed6b622acbcec35b4903251cb99324f14f2b9bba7545 720e5881cab3613d6baeb94449d6695102a1e508f1b456ab03d2fdcc32486ebc -385000 d460b85b1ac270fad347a02c19917b9f38ce22c01d8b88e90d0baf63f011b117 b207a874a45789d7b09e0948eafcef8b76c9184aa370a508a4bafdf9d26ebe29 -385500 abe63c027a3d085071de60832600c63e46d78d244315facbee6f0f3fdbb02912 7d911e4630c29d4daf24ef749a17d8b7276c4c9c3f6194c6b0176b4b5f9271c9 -386000 656989d4c67537591081d194c31766bbd9fe449159aa2d3037afa3fab0f74a82 bb24425f9ada80398f6b1e4505b1f6eb372966389f0805b22f2e2d8607aaa38e -386500 2c055ea6793d46b622e43db2f1d25e05558f77edab26f4b1b200bd5aba514747 17499e0c656152df6a2d6096c5dbc50eadc4f19ed4919a04aa3a5c06668f3acf -387000 b25736d7898a4555b0e257ee1e4cc0a96c1275378dcdc0056234846010c29101 15a65bf7b60e7729a9c9a12883b882eeae58af6b07aa9e1e4b7eab5775de2154 -387500 623ea15901831a8ece8d44b5da072e281b237a693fc3524b523f658fc4ab621c adcaaf4a4184c1719060e828a12933ceaf54184d50afa75118d16df5a67aa578 -388000 91bbcc4c97dbbca8f88c68abad1a68e91c79f337a0bb7e14180bc2ce92eac137 21bc2be4b2c59b991ac29c2266fc1cafdfe59da48e957f3105f8d45fe2284c41 -388500 8b9552c05fef1a291df8a1b47d92229429ba2aa1c3453c274bdbf8d3c7c4fc92 f146203b047b7ecb750434bc317aaa95adc82c1fad15f35b22b879325ba38958 -389000 8e938a51863daea6ed977f9068092e5764c7dc9bb2491ac10291921725be7ef6 ccf2ce60dd83f9dfae647c30e824864a5c208ed5c8837420f30cbbc7caa3638d -389500 7505772f28c062e4751b5653080ccdf943181e5f0419069bc20ee6255c2cdd2d a4080018717b150e0384c0cae9a6500dac7779a57565cad365483cf79ea99a4a -390000 6f4b50c04bbd5aed6b57f287a0e6d90a11ea1571dd3635ca9b6ca6ef541cbdd8 b408a6d6415251b4b6ab6db5ae815ee07d0dfc8a8e9ac22c44470916d7d57ef9 -390500 b8caebe933d7dc40b9648b530bc042f1f93f4a1bf6e1530164682a1397dc1aef 192645f2fce9e3b4a7398c935db6ecbe5b79d25d8557fc5ee13d1a5c95fe790f -391000 0e6e6686e469e5fe43fe99fdfb377dc48f85d7892b9aa70e1ca46fcba1fbc940 face758288797482e69de640daa24de10d7a35e17e3b575fe147d73666fd0b75 -391500 fd1e752770b8e555108d7e32c8f6c7e1f9b8dfcb20502babe4cd541910a03b68 89601e3e196aa20964f326b166a74f7a601174815ac89bd1c385a464cee7a54d -392000 529453ab5db3938d1195a3ef84c286e8103c42b7b1b25362898674a66a48ed5e 892462e851252b9a2ee03c507d1acae80ea67d360514a4c5770d7ce0dd3e1f54 -392500 e3a3fd9781e171e256dbee0afe8373a2be01930182de5bcdf501db3a73a70952 945a626198abde6c92ee9304cec95937cb148057692f8a6c5080e0ae930be61d -393000 01db0c4add701bc81282082aacd1fa1ed032967c1ce44c88a46f22f09a00af6f 7b2b867b0ac1dc90aa91e0b88722f474b7d78a3322ba125ce36d0ac755b2c3f9 -393500 c045647644b0d7daac826a34e5f7cdb1f55a4cb4cb5500c16ba4791a8f46433b 8985e0f86f19a7a72fbe581cab68588d1882b9a4b1c236836aa1e559612692ca -394000 7336f022ef425203978336336066daf7f85850fd1ca5ce2be57119543211b7d6 6f1a7d270bd2cd756c02d24aed1e33fb78042efa052bc7e710cf37a60110bffb -394500 2791b8c33b59179365cb1f1e97a71a0ed8c4f9dcf98105ca35275dbfde1b8213 8b5c24c27b2fe79353caa4f2d7548591db269b31c1c53b5e7664a47ff1646a33 -395000 b68a97351f28549882241171a79cb58a1ae92d93a30e7524f3580dfa69bd70b1 a2d0161bea0620be17038a96a9c21a7c5ef08df89362f1e82ce8de29187735bd -395500 f674116f1af73caf4c6d464f99d55c1152f7529c15b0d28a12f35abc1553f91e 32fd584340a63818498504c5fabc21fdf3feb2a4529a6b5af5d9ad67f3679b20 -396000 ded515c3d960dfe073403b321aae9d66a1dbe4a9565caed08c9314e8f1b1d2df 134fcfe75781458a3899ad3330c143de491b74c09c98b8e95c16f79cac282828 -396500 b6745b3e2a46f458eca58083625f3eeab22ca3256087a45aa6457cdbe9999aa6 4124109f22fdfc42c1343feb20ed8a93ba55cd7f65ac34146c3f5caeee272d94 -397000 c79ef7c45f179c76254995bf3c810a62636c40d7283658c3d35f167f9b4289f7 a6fe1a5721abe2a12fce95bc5f5e12a4185596ce991d6af28ad2cb2972305637 -397500 d36dcc0090a5585951004c7f9dd645a5a2daff1d97b796f2dba60c78a89d5a14 a89cd3b2d93dcf17cdcb0f7badfe7af1077f916d6ad5329adfc38a6e1d25cb5c -398000 2b97743e109f78d910532ee0f342b1c491ae74badc58085ba2a7b9029f9fab5f 7ab0985407419f861b725834b5643d2666cbf5aaef6aa6eb94dc9e35c0f630cc -398500 4df2d83b00fd22751d5fc8b22743c9831701408cb9b788d86bf081c666e389fc 9c545b4c3cac0e1d1f9fecd92ba0f7c61ac3e8a28a8c973ff6026fdcd90c4a43 -399000 6a00c77818429d3ed4b9bd5211a3cca69cf68c9a99a89f9e1f9e5301c08afb03 44e27a5f4e4c32f6698257f5cd63ecf165cf4941a94f7473f3995b1a3a6bfd82 -399500 a6e49cf1def602b4915fbc2b208490f5a84c8a93366582f77ecf5575119e6cab 5100ff78853bcfc8606b12c5c335c772964323d7486d55af0fe315c05715875f -400000 641c6a53eaa3c9b94e924327e70830770397343d7927eb713609f14448ea6228 4252f178c0c42e28cce9ef5c0c40f08bc03e3b631a393de6eeff90e7b4d26d38 -400500 73e034517c9649420d36a641130bf16b8634fd3b2568e58198508e65def1fa37 a13f2b06f4b1b3daff6c10571f25318c3ec8e9f2d42c59f4f19369bcbff62da4 -401000 b249ae5082bc1eb852ce420a2361be80dd17228fd17c709761d0f52e81e8478f 679e41c907f1e82c438671466ce285437ba23fa2c845d8c07b43af0829692b69 -401500 ae40fda2bd776861208459ccc6f1d205b769de518dd00aec84f87811e006098c 2cb9da6c40cfc83129da322498da46fbb48f7509d66d7e5ad53b6ccf2723ab83 -402000 53a37e92887f0f1305b937538e060a4626675b361a28d8ac3cd88ce7c16adede d8bd6aadcc2b327c5d2ebe73f48ff2df81310be0b9c194cde8fa5aca004874d9 -402500 54008c3fb34d324191f2e8790f68e097dab91c9933bb83566e2039abd876818a cd1605e18479c4a48bc76ea463608f2c2475d5b3d603bf9ba7555194f6a77d73 -403000 7ccb2c59698108c6ada2be19fe72a1be124c9650abbad735cdcd1b07fb5888c8 208d179f6a09f352c3ce8c445468340beac166c28398132d642afa58cbb06fbd -403500 4307fac30841a99cdb606d9828cd6a920da0155afbea4e5ec770d2e82da4a850 b6304f7d096028bb882b39de8ab14f625d2ae63e4c597d34fddbaed7c2b9f526 -404000 b7845240f6d8ee0cc32e37d8682c587dbc52d07eef8c1b1fa38f73428b73afa4 326e6eaf313513e4a52cfbdbb0106538065a4ed8fdf3d0e7eb6e00ba46037af1 -404500 73ba4ce92e212342e14471f4d85581e85c402a55671db59282110671ede03341 b2af723149653ceffb01cae05de8860e28208128f215e3bd8bc65c7f2d03de41 -405000 3b3d4f18a6a63daf34505404d27dd936531654047b1dc9d1b1f864c33f7ed996 b6287250e883b8c416c65541fbd8cdb01e7d76f989f3fe3e2c31b762d9c3269a -405500 74fe48ee491e1f7e881a9a5918f1848dbd129b08720f0c9f2dac17dd413454f4 d57fd78c8080fb6739f260c4117e08c2214bd1afa6c4244bc16fdfd04804fa76 -406000 81c002e0fe1d6089bc83dc43cd9d616138fb16db20f8ff9dcb039a2bf54bdbd8 7e37f0088205c718348f6f13211a98b16ad8808ed51c824050c1c3793562197c -406500 20aa6245826270b507ea3aa44b5360d608e2d52b20109dc81a63181f9727dcfc 2d722a96f3605f68e844eaa0d3629408e9e20e8d5d095d33c435ea2427420a9a -407000 51c75ef8115644c138fc20ce9af7b771731a1efd11231c881096fdaf59591660 11b150fec2d433d57eee04489446c967a692ccdd64fb6c90f95b150f6d5ccaa9 -407500 6f24e1c00195775eda44acca48e654190b2a9cb22f2dfca41410ce90a067af16 8b49f54e99a2096f0ab8dcf8f22fe21db789b9bad29e43edd3566f5eb7045b5b -408000 ce3c90abbc8da7ea5c5df3c25ad6fd3a7fda496b1e0f696195bda3e6dbe7919f a5a21a4cbf89271969f43d9c808706c6cdb624daf4e5250d6690d40bfef2e78f -408500 ff9b888f601e151a141d92abe7007d40203e6cdbf107740c78a4c1c715608626 3a6e13fefffab34b8bc11418f83163112c871b7483b6cebaac9f9397b5894976 -409000 7f3914a988816ad71eeabeaa91e918ab92df56753de139ce9170256ea433c610 39c9ca62d51e871cec9c9724f12841ded9e81d1b684ba9bbbd118c4d79675e3d -409500 e3fa8435841942ec88357b1e3e0c33702412a83b07c68589319064dfdffaaf81 beda309cb0d0295f165e7ff4168eeb205c921f202c3c9524960152b7ddfa00d4 -410000 3ae6fd96e35b4a84bd063aaf72cb8ce5eda797e213dfa856008516a88039a94d 58e69a89912f506e6f4ed9e89229f9d81113cdaeb5bbd120ca273136117dc82c -410500 eb2bc9bd04d8c2c4ccfc4096116e390bd407e98f0d81b2a7a1f096ce0e86336b 3a87b4d2e3e1c6c5171edf685bfbd0694f293987197b33680dfd338e3ecb4b98 -411000 a57f32043fdbc1b8eabab9e66fdbb7f40066ea9e92d3b1055e7867faa4b73187 afaf24d67374beb37bf9b1c1f0e231ba901b91abae33f81367d55bdf78e1cf2f -411500 ea48060ae79a850a73fb9da920ff9d38245420ff20fd71ee09f5e1411c53f60d 248238d9ddd8abfa0b502311f3e2b21f3e5c5b75719915069a209beb7a1be710 -412000 aa2691852758d5a285217fe3a9bd1c2d29a6d337a0e350abd60809cecfe3207a 5a3ac34a9dfcdc2b17eb45244fccf0fb4e9a843dec6c6f76355c1a81b16f90f0 -412500 5a0807ca910611b9dc9992060c41491071f17f9b4f71b8934e8fba9cbdf95a69 a904ce16e3399f6e8eca3201ccc7fe5b15344c4bf306f1e63da4ab019e0d9582 -413000 6b93d17d702eef90b2795ba888ba49dd4d0d1545784e5d508bab8f3f3700be79 20028cf3dfdf9af6de78fd6ec4f174f46a617f2d3204ba22c3b487d3cc135be5 -413500 1bf2cd60f8c697785716c23db0c3588c42528d3acd6a8427311ad176e9bd3d71 b6e7e1e76a68c20f6909cdcab53f6e820bfbe896cf25a7e435a52ec6c2c3bb85 -414000 ca3778a71094657cab8c697bb6d36930a875d3c76fba72194abcd69fa5c17703 02c6d73c2091a860215de5aa0741c1396c9fb5334dad2786f1f483add87f1ce0 -414500 97f6a6e7e49a245ff3e2acf4c2882ec0173994a21c619f7a384adb93804bfea7 79845ca1a36820aada03e8c46de2dd19dacd64131d91ea5c102bb90df653cf6e -415000 e68357575afa23d47a2a7fd4077e14d22e51b786c8866042263c42ce2f6fdda4 4cf1d285f03ccf0ef31333c8b6ba0142b54791b826f29ed619266270c725b070 -415500 f975006a0b269a3c5e89fea165ec1821ab21dadd0e95d2f372428339a09b9476 a2e3b1b7b2cedaaf531168cf85aea230e8a27131f3643f15269cd8b7fb55387d -416000 27ac3cca7b525e4bced3bf89072f6df21ab97f85317dd242d9698a9f695b3d29 65b7175c50d753059f0955541a646bb523b47f1fa35f5d3d86ffec0077e5e6ec -416500 c3947b6b74b100c5bfd70c7cf1baf822871046f3ebddf211f20ac0ad00660851 ee1d3925d350a9da5ee86bd63c792406dc6a1c70fc0d286dda655687a0b83b57 -417000 cdd42386e134f3cbe56a5b6ff14b08dc50a1a02b70278f20a6982517868c7613 2f7eb3c08a36c3d1ffd90dafc4ce917e3b44fe62e8f545e581af01a2fec59891 -417500 758c5ed9fa53f6a940eb15078bfc3300f68a45174ad55b6d754de04344db5dc6 9d180ee51efbd082e027e34d85c9002b72233e99014924f3b56955f3dc2ba17e -418000 de38ce06e6f7c0509fb958124422fc1e0711c318d7fd1a0fbadae47352ec0eeb 128c492324c57e30449629f7a9d475ccff48d077ccb61dcc5b7f91d013d89337 -418500 52335906771b9b38787ad4381361b609d5eda9864ca2a7d2d22125faecbbf76e 192a8939e510e4b270a3cdcaf4d5ae7379dd0a20e4addae21c2115d0bcad0d18 -419000 d7718cb6a671d3e323e7f8c85b013f8f46dd89353a6f77672806cbddd9887379 ccdffea8a7310aadb5f103ae277ad075b9daa876c08f3bc4e13ca1fe85a400c2 -419500 311eb00a753d20b8c4c073eca48fbf44066e4c97dead7b0224ea65d24dae43e2 5d4d46ec84c96ba390f8d1ab5cd82fad5d412133341c4ec204f36a47462a1633 -420000 02abe9181281799d247884c1887745c6aa80f60a1ceb12693d328015d28b5a84 c5713fdc696198d00a681a1602a8703b724c13362bf059dee081747db8c31908 -420500 f24e5019cfcf1f0612785511437fb2eb94b0a44ae6207ff537b07113a6deaa5a 4c49208f8e5513b0dd1940c861175e2bf7bba04d6373e734cdac63237fc24f1a -421000 0ebae57f2319ea062c101095eb8c2cde71bb38b0df36fccd23fe6d5e40f968bc 7c50e4dcbe642218c07f3bc8df56974ea197f1107b9b523cc8d984f1903c944c -421500 3a65fa88661cc79145ba391c18d2eb928842a9ee2642c757b3731ef399323e13 2dee8bda6a09ea7ab0349f743da33dee3614c069af8977377a94bd87d072f131 -422000 030b699998f98d4b331ef746f96eda057e7a454f98765a0b695d16fd3e7aa44f 9b2c25f8a003bba7778aa66ea405ca0a7d1b4d1a44ab35c28124d0d147a731cd -422500 44dd126ceb8b88b2d3d942246ec2ff298ff07890fc75156510de8dfa22c121a6 fa987f8cf06191b45925bee07fa035ab558e651c1b94d1d518524db426449e5d -423000 93bc08b4a0ce5ef57f63ee483936125540dffca3d9d6aa1a24ca2f69df2e2100 a02f084ecd89f843bf976fcc5f5c3d7b9a5c2b5f549c12b896f4985f3fb18f82 -423500 4a09df19634b6b11e40263176de979e2aa0b3aca1a95825c3ad7eac2a84bad86 1a2acd078f11b82d5bfc43a088c8ad652ac993c2478fc2469859ee4885da2ef9 -424000 bad4fea158757021f14bfa735be04d0514bc3632f96600b1e4d632efc33c6238 ea4dcf8ad8122d652811cb25f7277c96380f8f3b1c839f63d8085d1aa69f5f89 -424500 bc5a6d616947f853ed4f4d9737fa063959d32b8acdd92b11e27dd47b435b38b7 80e414f560811279931e8906a37b79d64836df3f560e19ad9a9940a2e282ce47 -425000 5b30049913f1ad030235ecd4deb6fc86120b8206e5269d39e56e6c5f1bdef8e8 40b7b38eead88896d0993db8806af19167c6c2dcaf989e571a90cc689568e9a4 -425500 1c8c6b6e080abbbd1aae24639ad147ce9dcfb2836be1a4d5520ebfb3a9af61f1 c6e3bb5149886a4050a284990303b89355967d534894ec988b9b9be1f451edcb -426000 9a644de2cda849b362daeec3da5cc28e71652c6a2bbf37151d8ec938e728f2b3 a38d8a78768bea93a802d40ee5d92753afeae17ec5c625515512f4284d56eb1d -426500 4b3cba7009b8a7e4fca74996822c10f661db865afde3ccf0335607d549db29ea 91b61ada9596f861c6ae77dcb3f1da3ea0f39dd623b58910ffbacb800448a8ca -427000 6c5ce8cfc2031e16ddbc1da1b7854aa2b45d1e3a69f2fb73bb14d74a34c702ca ab6ed27075246d24cad1577e05b7c23f081c1be76318508cc5f08aa692ebad22 -427500 8156e4220e867b6f1f988b354b5a96ad98b7f7e83774dc658aef3cb7113d274b f8874e6dca4d1a2e74d442999c6f47bb74a49892a0d9a1894c81fb7d1c350f40 -428000 8dbc7ef6a382825ff9af8347d23569898d687ffd3743285297278cd90e3cdb13 21978c24fad677e5014f13ed54d547eb96722526cb52969673292324cb188b79 -428500 cd56d45be8fc1eef02a601ff132566ef3537c7a69f67f2d8ca6de2fbcff16bf7 f0b9826043f778014106dd4bc0e5429d0f217fce16e401a42ed252b1d2ea6551 -429000 4aec842c5e392ec18423fe3735e8f9c84203ef54f2b3dc837100e42fba29dd61 5e2a8cf8c42f6cbdcd136ecb5386e02eb993ab5314fd3410354159cb6497943c -429500 24d33bfe6e7a8694630a848958175d99c8c5a5fc092437ca95edb5e8f1aaee5c dc92e71cbf3286ffc80dd237cc7cf5ed769de81324291bb80548a79b6a12e354 -430000 64e5cb5e05477470b8068e35326c7e6779e4cbb740cdab675f60a3048e15fc25 c622476e2285d634a82c4720d0a864b11332b9e00c3379f7001f28608c1c4817 -430500 c7938907c4845919f2ec22dd7ff432e7e3e2429e65118a11ae5f2fdc1f5d9ba4 5b34e827fefc85f603439e3367c5bcbb63d94aef7f5389c54e10bf41c1149d09 -431000 a1f4642fec301e246762ea675616ba729278569d221b83e0fee38459ebb157a0 449b183170ba71bd90a2cf58cf0fa0a61ae8d86fe32075dd4b9e80c0a3d8f365 -431500 012e1de4c57ac640cce243e1577db4193427c285579d43614463815932e6f227 c5e13378fdc635b4f2d4dc61ee5d1c0ed7f60850a9de87de8307c9e7e494cbdf -432000 e530822bbe70b043e108e5101b6a684e9b1d5c47a8d0b2e5ace12e44810097f4 211321ba33cbfd213efb8e3df7e7ea774ea25fb24c82cb757e568b756472ee12 -432500 c40c2a8915c595ad827fc5097518aaeedb71832cfdc7f3336789fd6ec0fe4231 37b6a9e80f2b789d61060f97f6f7b8ce019ff788339de54fccb2101c184b810c -433000 c471b86324fb2df461084f3b3f91364c8e4e54b9c592457044805c9c0b1b1ff0 c3cac09940b2a846d2798df91b2e697dff55fcac233473d159da02f5d2a8865d -433500 7c83482c8fd9e4c57aa0dd75563c991933b314f3f18c7cc821204bc41d4c76d3 4d6ebbf09ef39066a45d9157273466fc6e1b08f246396ad00ca6a533a4d08da5 -434000 7d3607cb242e5daa146bb817da979a8874bbbb9abdffa2cfecc546bef9a2cd26 7bbd1335b9852ee4cb13b1d7285dc11f9c2867fbe267cc4b6c1b1a3dd6a15803 -434500 0534c7881cc8c3745dcac6942291cfab024520de1159d3cd1cd6fd853a52e1c2 b08a60d232a23a137cb4808f3636128335ccd3dd10fdcf766ae5c20b64d8a926 -435000 264a1cbeeed20cb538b71b99c8da4874af707bdf7591cc37e8f2780ed8fda372 f226d8a6d56c761d1f9ebb8f5b06414d1339c17889767ce48317564edbfb337b -435500 410932e8557a564a226ac672c5578f75653ed84c4669f64b6bc29fabcdd90586 a5c68267fd466a48ec4473ff1c904efa8eeed2124b7e4bab8bbf83ee876dc375 -436000 c153195fdfcf3938a5dd5ebb0d5dd0ec59692a8decf1184083679c46569b537a 5d8daaa7bff2de12b5d9b428e84e5ba25ef9001e45ab728ec74d6a22c61b269b -436500 5e3b108e26916d2507a40bc30211948a0bcff8ce4b40117ade096cb5f94d22c4 16754de8c6290ed9a3e8769b8a03375448921fdf847c7f1ed6d627e614b8f6ea -437000 06ad60451a13eb38ac6f9abd2375d50afa00d4d8c5dc1c2806bb5a05727ba523 4960cb8d1571d7c0aaf33b659c0721fb84bdda17daad04f0cc169dfe1a22ee28 -437500 2f14aaa3e58a32d5a3f17562b3ccbf8edc8bd17193a9a09af65052be99225a2b 8709492c2ef726d995e4a2092a2d062a849450a00582ccf51fd7ce3905ffd2c6 -438000 87d16a339b0ffda31c75b16f3fc8f7c45d0c67ed9de0bb27027524661b1f91a7 c21254cce7d2b9df55ce98218ab9d20d9d2afc3a450ad1f3931e9c7802de8f35 -438500 b84fb753cd672d1622e7384382069066410f1c27763902b5ee2c919ba3f20bce 075834fbe8e33fb3add9426e52ca900f7db370b85651ae10ac5079aae540153a -439000 cebe0aac7f629f59ee1b2928d8ce4340b247c0c619e3ff53b369375bfa71abaa 7e5fe6db2171c4040cf71a4bbc598983a4892689b7b8da5e3cd161ed7696a410 -439500 7a70cbc08418eb8b711aa13b0a49ca6cdf063a443a0aace6b8f78aa0c9bdc3d5 c7107988cc60c6c66c2c9fce42c97303bfbe3d3db9ebb17da8416d0b1a918e44 -440000 7649654fe753d823dc09f3ccd2157d9e9849e534962d5ec32f5a71775ba31fff 3670ea77b7e5a8750d63d8d846cc2e676e69539125ca1a3f66c1d1573e47ede3 -440500 9ad49b33c96384a916c19e0b7fceecc324d33aaa8fc45b5e48c661aec09c880e e594489948d159bafb11b9a4151a89280c37b8f5665d6d209766ccda296346a1 -441000 2a3a6ecf5d7defaaee82b14d7073402109769a5a8c940d6ee1fd35f23303bf95 e8520de1202a192e8f8bc825b528d2fd8805efb774b18c4ab2f3dd153063a0dc -441500 72fbb24c48304e9daaec1801004fcd4bb4b6c0c511932821a6d875bf4c9e6bc9 13850c1041b5b257adf6f51551051abcdcf13bf6d674e075c0ea32028011acc5 -442000 d8d9a1091bf2e48609bde3ea3140ec19cfb7a2a14735474c6f9ef6105c46c8f6 8879f9476a6a342e58cb8ba5e4e40a9ff6ed0b605f3cd9b4bd9e6cf5dd2dfff1 -442500 78782ee99be29090c13682ee644a47f85f410c5a24c1976dc047f3249dc1e0e4 b4fd6ca7a0b0a77143c457285ecc982da5b9639a5659c03ba88315432e4881dc -443000 a5d7115bce13dbdf436226400b23c30de09f68f6a5137cba50de278effa35891 cfcc7a433eb789185f88cd600fb249d26b8c945d5e5a5d7e978ae3c1c1118a10 -443500 f73cd58af88e5cc893f5a5981888e792f6a15cc06093c14e0ed91110778f0312 22b5b27df320f33c1856dd087c8537e5837c0686ccb436961189989d593b318b -444000 7c497c96ad4740eb68993e26ae3127c6c9e10b8625f9e759131574b87cd722a3 e5405706b778afbf261e0b4ec0a7fdca861baa26ec3a65f5e970769a8497ac1d -444500 cd52d7101a166f4dea73875c0fa5c494db3419bc3f63d539e57c8e853e96cc6f c874b6d14b66ae740907a7ef12eb55dc0983a4a9ad00b27885902a11c72d8009 -445000 30283438585b2c4d3409d61110cc5d400b0abc0cb8e8b65b9fd8619e54dc387a 3664d9de72ce8aebeaf5f1e844e44f5b3362d0faa80415de24c2cf5fdce153a0 -445500 a4496d3bd4aea3dbe7cf7d2d5a3f0850f5c01b04662dfd38d3dbe6736251e91f 8cfad175dbdfb208dc40cdc2f03d0ebcbd9f3b12847f6d069fac33a5c1ba5173 -446000 7cff0564cc670e8a69315b18b0ee229269682bb0286b5e4b3db25f02ce0c4d2c b5c22f647055dc1204b243da18d999adebc56060e52f1f0c4d35450a9e941c68 -446500 201cc692970eec864c92e5e7af036192a9562a62d2723204366bdbfdb0741fa4 f3abf2331a35c83fb86e4484026fbc40266f5551bc90551b90be2d26b3771e3d -447000 c06f8dfebb81f0cb3f19109f662a7dcaa4a023f1fbf735ed81fdd6bf9fa95023 0799398c8a29c71de6027c446de153b17b1bb364570328bf5aea872fa246ca98 -447500 05185f624dab270906ae111fb2c43e838b70a78e0420e84fcc94bfe4fc911dbe f73e1007bb6e28fa8a5add7dc21539c7545ca68c600ebc62b10ae00382c9a538 -448000 4fc96bd14509bf55922cb5d8ed4cbf372f7ce991646e5be3a086204fea0c368d 0fff78f76cbc925b62ffe927d50cbc02dc83fd9e5405a3a77e232b55a494812d -448500 742e9431b2ac6f0ac24e58cb8e6088ac1de875cda8f16739a78e0f1f7c05ce33 d892c34609acf3eeaeb32a384985fd2da70c4f53f59f8c459eaa5e74b3d61c40 -449000 335341c810fdea9e158ba78a542922754fac2e0fece92c27559d14c5c3ca0267 8d6340cdabfbfcddacf2991913176b17513be28b9472b744e7a64b2f2ca13896 -449500 2b97e9d073d0b8922e73a1b1d6fcb7f8dbcb0e22fea6a707d9faa2afa1cddf8f 52066346f6120422b739d9d1cfd8452a00c55505e0b2b9805351f7721cf253db -450000 a6448ff3de412e8784a4d0590120e0727c3ef1c6e98af7adec4b687e10c22b40 b12232c014cf52f4f8d0fdb4037642bc1ce2a4d709ae37b91d908c9d36830fd2 -450500 32343305ccca111d5b0396816091f1f169314acfb4974629e7beb8680523cd47 36cc9b37d7962e434782de92543635fb826a4d84fb5260ca0161680523f54272 -451000 adcb05f8f053823db604b6278de320da2097890b386fe67c0104721e6cd76954 c63c045a3117df4fef3287be2f66c5691b700b18b42d3ba60509faf162dc9720 -451500 c3f6f574abc62ac6ee2b65eee953b3386808361f721ec77e4df9bad7811b0c13 8ed2df18709fd8580694387f903d9c31fa4a7c5e3bf3845b4fa4e9a701441112 -452000 b47901f63e411758d074dd4181d87fe30acb1b1623d0e69701093d93bc505b4b 227dde0bdd2ce1659265ced176e8c5514aa1d7c9c58c5f92d18534141e157539 -452500 723793ff45924363551d433d63f58d9951d58791f6954a6aa906d8c61f80d535 1a931421c2325c0c2cdea860d128402f6ba18decc20e05279f62f0d0f5940f58 -453000 14a86fdf9716b2225cf80394126c1bcebeba3be4a4f103a3497c8eb079ab11bf c0261d2846f68bee936c5ebfb638d9d4e6bffc53519b76ce72dcefa8f66e948b -453500 4204f92e27edb642343263ee5c8265639a4e4bcfe6743c323e5915af2db0f68f 681663c10b07fae27a187f5512c63f266d4460abd46ec1f464e8744b5ddaef67 -454000 d7173ff752ac555014e60e3928c1a8ba368d9ecfacec9b302cda79a6c6162eb4 c34bd72a990e253a26ffe68a91553b0b771083a569e512c6a46a52e5c7b6a724 -454500 df134eb761013d3ba1bd9ccb38d735427a299f2e275a3a1764ae436ba07f09c2 4d9b5dfb6baf847acb9499ef9cedfabe98dd58150569156e5bd692d1f7434f3f -455000 edf2fdc49b76a90ecdfcf0e238e66d574794b7ebab6a4e7d212e1884a21588d0 c40b528799070a1964e73025da6badbda9f994fe3d83cb4ac5fae95aa2e42963 -455500 0728ecc53f1b1b7be2478f687881eff7e6ba31e9d565619ed628ea9263b67a97 700384e16447d9873213d70063f468f9e4e9b1f780104d9a118d86b09aab9594 -456000 fee4d1a2fb2a99260e941a74ab4dc87e0520c28a115ba86c6382791b2f06f1f6 e0487333ab303a6d155cbc61b33eb1b23a3a9bfc3d466c32d8e6793328b3bd8d -456500 b5f05116bdbe8b51f4c1ffaff1a0e0a445e3a0f0c6c718a72d346162820509bc c7a2de5b71c4c7b338b04adfa8fe16857ba3c926fffbfc97dac86b0b75033978 -457000 b414f29bc13f7cac4f028641c788a54786bc9412ed582f4aedd5df86039a8e00 ce69e9060126b330e010d201b073dfc0e16924a8c11acdaa61c7776f0f2d8021 -457500 c2f18fb64768083a462a48b87b993870ab96a70e325cc1b7ce676a504dbbf4a2 bcf97c78db8bc3b69a377a185a429277aa530aa853c7ea12c2ab06566e837c9d -458000 379e0643c8dab2bdefcc1cedf8118337bc0133f0c938a1553088230052f5cfcb 22e7617308101b51b4ddaebed23dc67e0d1e0b3f84c5074039ed77c466cc83a5 -458500 5b8d6a2de4952aa7aa38b9a1d403fd80e65f6cefb5e824c062d060894d490946 56ff3b66fcc71ae8550fd0630fc358edf11f7afdd551d69a2ec9d4b9fe154bae -459000 426443a695e4615554b95c1070f14391c199178d8be6860807b69cf2d686501f 40015ea68bd905903100db2ed67d0a0e25510796dbcd1bfaa0b8dffec058ec4c -459500 561074bb87ee4d3132bd22b91af78df7d2cdec1c6914b43b12a4004204094a4c 86a908568cbb19be09a1c70b4a92a0b3022e5d0008ad78d6ed536a9bdb08deec -460000 7adb9b6d14e8124ab25bb4696bc8afe6a96cdae5396ac2a5d6d859c47236990b 6ea2894408475e17a8c4476b5084cd76742a3cdb97292eba2e2ba0ad4bb17d87 -460500 5cc330e1e985af39a1a24602603f26535df43ea7e5e164c6b654f292bb359633 69c11c20de0f89ada1a65781a2b7e7a1e235f964341eb70434135888794032c8 -461000 c1c45b5a71cf6ed3c5d9a739c227b68fdd3cb41e8102b7e99c28084776c3d8c9 122728c928e7025fba2e58a3b70cf5dbf448e26389be3606b43f3b014d5f2001 -461500 096479184f5b32532940e42b35c51e50008b8224b2c6d6317dc69478d3d316ac aa693ef567b3b7c4a7091b5bb3d34161b4235e7bb3b573a22e66bab0e622f16e -462000 c78d5a646f9130aacd23a52cc3dfc5a084add7fde9dddbefdd13d5c438e024a2 3242055c63d5e14c1efdba0effc3580106e14c443a3c39c699931a6c4a36c94b -462500 b464f9105311560ac63c29a94f8a0a5f378bcf5c22cbd23d5818ebe2e62550d3 4b91a857ed6803609c0f1d514e5793f3f63ea3dd37f84b345c3c64c7248f8358 -463000 ad7d579916aabacd745a9d48122a64e420ba111b8633119f6110a93125eb6072 ab7a1e347245f8d9ca551cc5e89247e18d130aa0180d375673de0578dffdec36 -463500 9f647ead66c59424ffdba0067d38a93c33cbc5cce95c1fb19483d3138d9a2924 f9be09f0a7ec9832b7d2e238f0f3841a10e99967b378bb93e1e8ed95025791e4 -464000 8239a8c5704697db70720d8227fef8093751df0e79bc792a4583106c5229d97c 56a2bdda4613688231ea85b9d659f05000786ebd53300466da5dcc474f8386f1 -464500 b8500802e87f0a3d08b275296b32aa66211d93ba13dffce95a77f4d2ab6ff8a1 87c4e1ae3a488895890a0dda084969a43703e9abb82fa8a6b0fffda090b1fcb0 -465000 9c5f241c6d7947c078423264cd080eebeb852aca6898b71dec1f2fe0f97f40a4 eef3196b8ab3c6d1e3df1eeed6f857644e50f6a751843e308a86d72e945cc6b6 -465500 714cef624738d796efc3fb3fdae8f42478924d28a0644c225374b1e5f8707262 8d68d66be9f3952f46bcbe5df4829d93eff2f4501bf422582e8594bf3f03730e -466000 760869daabeae89da11828967600ecfc92ff38d5eb79326da9fc526ff88e3dc5 ff631213c2cd21307d635337ecefd200cc2b7767c171ba5913ecb785d6876aca -466500 9699ebe38cd6fed8bad4e96c18eeb8bbfce93fa6be86c0c364ac187c246d47e9 f18cb4eae80510bbccc360228942bbde0144f6c66f378e0b4bd0005ce35debe9 -467000 6de68cf541236c2b20da6bb789be6df085207919a94074f31975a54250c4d918 0c998a0b617d6dbe4454ad981478bc5903ace25595e5f868c6bbab61f80cab09 -467500 34aae978a356d729783acb130e2238fefadba1789ddf82d73b87c79d862d297f a90873e05bcc6a81932e4562242f7ca201a07707b505f5dddb46418cfc26c5dd -468000 96a959479e0159621c8660165d2053878cad8adccc1ea5a4020c4a1f63941b09 ad947d10fe2c2fb1f61572586b941c872bd958499342e2e44b545d4c0faaafc3 -468500 ef36c23495b3e062fd2a92e24164f80a01d74452d2d439a23a38e403e531ffb4 5790fe543b78423f088a1d53daf1692a7051169bbf1e469caaa7d3862d709b2d -469000 e32fb17dab672f159e97ac45ddb12dfe0dc0bf2a2abdc455beccdfaca5e2c69b 56f4d6e427a46b3467c26174b6a4b66e30f5d962450273ebaa598c06aa31975b -469500 3870050849e79e3243d3460ea594ef741a1d6327f5d336f8036fa5e97e0cfbb2 2e0823dd7f7a137a063f473cb6991510a112460ecacfe18aba39094d410c8930 -470000 2aeac4abdc914d4ac3fde31a5882b242aa26f1049c86f703fa5da279edad5a7f db8d47e66737aa4776e8cb857386d346d356ba91d0f6212d8aac34c9ac2e5906 -470500 fdab2f454e5102f44be86a36b7c2a54aea2f5681bcbe811942451827e8106734 cb60e3d4e6620535cbf57bf0f94c5055eabf0ca48052e9728fb28f5ec913e5c9 -471000 afd4b785fe4656f48ec1120a14136d133df7059eedf76f407dc2bddb91ab0ce4 0eca3c26dcc9bd50d78a8322c07b18d59c7609bc6ac97258b56b20ac73187f06 -471500 e633efdf19faa95b16be4cb94f7072dc1238342d624bb4d69609555a927f2522 570bc44f8e51f6dceddce363db3b87fc17d9c8ae51ab9266a3d9248b546df4cc -472000 d4aeba089eca88aca7c2b7cc89e10146158dac72fd7643e4c7dada43c8645757 e49b1d22916fa97893a9f31f31bce50f96d49f6a388ee1c8ec2216aa619d9101 -472500 a1c6bef24a340e81f3212db55e9db0bbe8135334e14f66839123c21fa393ea57 1b5318294e73812e157fd78c84b79a31d076bafd91aeda00fa49055003be7e91 -473000 c2f76403fbff7b3601c0b2bc71cc00963cf0b012e09d6be5d8fcc12a8f78c8e6 be2ae59d51ecc553798bcd9c82f4e747dfd1782ad18021dadc24e4838c2b0666 -473500 5f6ff7d98fff43942ec210bff0555d74768aff3e5fd5ab6e0b546d0bfea79921 b828dfae2a89c1199e2cad79165f815f8d858620d87aefe17630048ec05f0bbe -474000 2c191256f2a1ea617517c81c3133a47d2fa264586885b2ca6a7b782f9c78a8bf 7d0b4169707e36667345fa68284bb9eb0dbbb726b9391ec0b3018c71a343ce0b -474500 50b6c4f4c1da30ee2043c4a18b0dfa1da9aa33000be4525bb07b2462d8cabd2f 097a81a5771e9db71271cc6c0ce12a4053e89f2975e8523b6dde6556c170e5e8 -475000 2c38054fd7a02ffcac28fb8c53ad84b68d50ef30af030e597414e15b59bef269 6faee9c17b651d220534dc8c66c0345d162426661af23bd6be235d1c0eef73ab -475500 8d981411752ee6b44f12860a9975ef23df0c7dcb5b5c621368be19033de81de2 23fd87f81163c7f0580a7eaf5f74b7501a868508ba60f47836488f5b72716608 -476000 27aaae6fc04f000f25a467ff5c2fcf62a6872b3ea96a3ca445e0947bc912d050 061c4b35170cf452518590f1e96624dbc031e5eec8b9de1acc81a477bbaa18a0 -476500 84e8616d4259371a11abc9625c4f7d55ccaf949881e017b663f249d29aaabf70 6e6418118d4d34c06bf73284c95f2e3622c87c42ebd4a8e1380939e6abeca428 -477000 d459f75729583c8259ea66e8dcc7b8e1486b0a30e14864332dd014757bac1f5f 9316f02e5bffa72a4ea6c7809be57001db28415e75048320d33dbf23c3a39e86 -477500 329e7c98cde787901a05bbae8aea2a10fa244630640182eb9fcb80e83ff47cc8 04fabe2b506d1c811471d88cb7986d2a67a988e0e094936d398af0b20dafed91 -478000 8515a758d83284a93a354e91ca1389d0dae0914aabde4c7069180dac0f88ece2 0f9d14354952b22318f9909502aaf188e43c511ea6c627724bcb7f0d14550233 -478500 e0b6428a55906d115c2365630e7a748422b1309a75df0712730a018e138f8ae7 75327db1cbc6d65c203eea4cf697e0e8674ff0cf180ad7730c0f42fac2cb2259 -479000 acdd6bdcb3e05e00631aeac70db0beacb5ff7339f9efffe5d125a748e050cf0a 2f4a8780e4913da0886b73e399430b0a65b84e906eb7b47bb14ef6139699e222 -479500 173ac0f8bef2de4b544b42c3506aa887ddb348e6f719f2b4fe16beb569b6b9a9 550714098a237e5f2a2313711787f7037937081893315ca43450ca64c071c798 -480000 39a37003b75d37e0588e177d5d5566dbd2cf4f1ade343067de439e4e60d401e7 e90cf6f99b06ab2f396192723accafe62f0a7705a8795b39371238dc660881ff -480500 675b1ab9b45350f0db5814692844dedce30a416b0c5a6b04e3ec778de1c54476 0cb43e9d578692ced5b3c43a067a09dc8e582a12e46208e1a26841645ebbccf4 -481000 c49b18c02ab6cdbcbd1380535c394567b0fef261db605ae42584fcfc5657292a e45920a96e78f6ef20be3f24d9a8b1accb6ed9b0a9ace38694eba826aafe2bd5 -481500 e70588e89d0a3a15d7de9bc26e47768a94964a14edaa0355853f5629a500dffa f623feb088592f1cc01e94f8984e5bd7f5469ce71ff7645ed81648dcb25ecebe -482000 bdfa119169d8507d41720ba8fa40f5ecb75267570ad0ba58e342f4351fb74575 f28b44f2e70183e19deb6562a107d204531edc8b46d4f5aac76884d7d3a9e750 -482500 14e2be2612c4290229084f2c1edfefd0e432a91254abb83ef8ddbe8d7bf2e661 aa012dfb4ea0b0d0a565fd8f2f55692135969aeb6a9d3f34cb17b31e32ab22c6 -483000 8cc62d490274477579f93e8af507c07b3816d393200aafdbb6b68755b763c2f8 3bce0766356c52720491791bd9cc5a6584c48a39d620bb185f368eb7dd7db697 -483500 72c78ca3f93bde96a8afdc199714ae18e9c15b92526ff48845c050047343f548 f4c218fc750e8b31e2b4f56ea5bdd7f027227b58920c7d08946d193bd090a366 -484000 ad5719becb74523e16221adb2353a4786de357612d9e2ae86753be7035d1074c f040df388303fff9b7c97bfd38d55a94c1701b82ff4f2d594b1f4637fd8ba964 -484500 a143595d89e542b00901e959c20b1bee243c6b7f2a8bd930401a0a922586308e 1c50e70afe27a5026a6ae968118f5141448e69955b431f74c2b94af7bee31ffe -485000 ca0faa2c4b601116d3e03c898bb6fd6de955e9e083910fcbe93303702522fecb 98250685f5d2fc349e6088d617a7986ea28204843abf4e887ee121b3f89a2b36 -485500 1d2f98bacec2bc91b7ffcd9e760c49bc18183ddf1bfb4aac8145abcfe2f91adf c03ae99bd105f3c8154bed1630bbfc10d56a2aa4e36a85d4a9fb2e629920e285 -486000 3f9896825fb06766d9216cf1004aa6d2541642253b2980c59775fa720e1af9d4 e8ff26003f9db4ca25d4a5e8f22c615b6b376f2aba0b6e3d3ec1fc54bfd3e8c9 -486500 8387046d6d520535e933c40c8e7a9b253dea20d1d4fea49c53cca41d13f87b5e 29e01fc49acda9fd49203e03a86fd7fafff8dba947e907ca41db1b6e2802081c -487000 3ee4cfc2068bfe1472bb2345900fda4ce7d99aef724ce5c35e8dafc97472a163 84ee857e054c6f118f897926d53b546c4fbaa38576d66eee4560d88f90f2ac91 -487500 7802c03efcb4298fbff0c05c7c2a2670e2b5c5c0a912260fca95f5ee401f9fac 9c507f7adb01fdb9fe8edd09d969ea7b12474cd9f317e6e0c8d1047f720cfa01 -488000 6c0026aa2c04a1ab5ab59df72d9ac017f559889453749c95937e01230628ff22 89cd039f94be43a6d229425daa26daef3bee7688fd591dc954ee503ebe2f3573 -488500 ad7a33c68b62d181fe269bb58ad9f00b48b4b19f77cae3c68407ba81af9e29f5 e26367c609049d5cd867041787aac089a459ae2a39e420b791b778f49c4222e6 -489000 dce5e567c4502e3b3344804468bd48900df890568521360b198e5b7e48c4a7cf 497cd478db672eb3f6e975b722a162b26d5f0fffdfeabba6dc28664d4dc76bb2 -489500 326013c6ec37ad623eb9c5a35a51c154447c8e180d4efc381f02a791c8dff517 81c2d130a11e3caf98c5d4af0ae7c05bd5d79099d5c959efabe7766a211c87f6 -490000 b0ddbded4a9bad235b75d2dad597b8fd87b80cb721d2c322bde82e9bb3763d72 5abf2e1aa1273cc9de5eab070f0dcd5b082cf7459de699a96e7b12dae3311265 -490500 40f093e9a8e074fded5c67276c85a0261d15f3e418e492ab1452e340da3c0469 0d79b5359c16640713fd6b885d6327bf67971e99395eb633ec71edf9f67a0649 -491000 42ff56a78710f1d58f555a7f55001a1760c7090441dd2657f959a67b2d8a8289 7a167a1f0656c972aaaf079ba002f35ecb7d47aed4c72a7da645276ee21f9ae5 -491500 38a42670dbea9a526f90e8a824bb52398335afd259b0d89f287687810cb3a268 c4f01d0a2b59e7cedc7957ca4dd510eb692cb5ef4c257a76fce04c3e51487e20 -492000 1aedf52ef4f42d0e049cd6f2b564a1416ff737cf792eef860c4678cf4b1929f6 a6c9e1dee9d08b510553bee2acf0d1b8b2f0bcd202ae4d28110fff8dcedd85c8 -492500 d7c8c52fb1f9138293bdf0c28ac68aa8447efcb1246b8896a1777e5b20800ee5 0d6687cf95402d4df5a9115b6786b1fdd27493c88b0e1fba921bb7b722084a88 -493000 e4265d17c243d4e4dcbe12d216d7dfe7e4e3b7da161226203881b0c007f2936e a6f9daa6f9635dcf4a2cc894a4b459a8aa5dc2ed487d95d733bbfe827aebb0f2 -493500 9c3b415ad45f42001d88e2dd38748048ef9f40223e5c1c62caf5eb7912d78b42 e68eb0e1b1b95dea2fff359dc5444930588ef743a58da356b8d33d8e6a0ee1b7 -494000 e78ce6a76a928e878b6cb5a0ca25c6b9a8cd69d4e2db9a066e702635c11ebe17 ea5640b26510140f3abd04e611f124851c15338caa163bea3a5032fd0d16b160 -494500 cb62ce4407ef63b81d3afec33e7b57b31a6e7c8b3e0888b8db96f17e4d39756a 6600b14d7f4f7bbc0f680587684f9fa7d5a7acd26cf9d103ac31bbedf9d6afed -495000 0e8a7e8cc89426af75740fb8469fc9616a8e75401fc785a8e686d5ec0f4e5732 0a1ce34d16dece7d7bda04e5b9bcce126b08d7e514e0fb37c5c1b0871cff4cda -495500 ba423afca93230eb911c2f4dfbba40b893b938a7365cfc2068e1ecd3bc770b5f 5720feefb7971397896c9a270a6318f2adc667cb20f2cd218b2791778cd50680 -496000 352a1fd91dc52fe0cd78e2de4240e75a785420049e7b95e01adfa3d1ac4ad512 781da1ffa0ccbadf08f451c290221fbef9b440c52b5f7ef5bfa3dfe51562de47 -496500 d0743556e112656c069f2749baef59ef56225b6bbee44b2336ff106773fbe965 ebc3df7a34a4a4e9d8a60151f4a5bdce4f40cc8864851520f5161abf9b9e6d51 -497000 1887117917c8adb81cfbf85bd4950684145a964a12c81ca89a44fa107247c275 e48c07018555f1a8be3ad71f6ec7c31932eab7aedfb414c99bb793715ec36e4a -497500 2ffe736439e02d764f544aa4f86a125b1567ab7d24a9d944313877d2d7c39d14 a2b4732449a3ad1488478233895bd8ba26b72f14bf839a33d5fc0f2934bcdf2a -498000 0bc8b494b42efd68080fb3d3d83cc8156b56439c10fa789814d751d5c4f7d9dc ea1ad23e7f85ec30d138ecdf527a5ec5ac6d925eb888ab061b9ae24e48e60b2b -498500 5440fcfb2e8888508c4fd6920d0e6c7c1f3f1095813d45b691edc3a2a475722a 4c2c9c60a2a43f9786004a9b43275656b60a70c9643d6c676ede104b9f0cec12 -499000 d84c475656720900a0b3765c4ed57ae1f0ba17238d34ac17b1635c6c95064750 236f102f6f2350128916d138401344233a7483a0dcb1eb39730c6a5fa22fed3a -499500 8b9aabf8cb60c29c4b60a942812968ab80ec48cad4053de2624d42372a547756 4fdf0de2a22bbd66bcebdd844beeaa7d5caa353352275953936b6f7839497577 -500000 bb94f21cd879e992217888fa56f0cb57bf585f8a41f845fbb46872fd7ddd4a40 541ce9a7c0f8771a84281db66fba7cc2dc43fa636a39a840fee5bdf987a3348f -500500 d74c1f7510c4307c942906d4c66ce5fc542f2a1944659c1ad37a0eb82be11751 976e8ed703619833f8d78889bb8a3a71a06392e257b093a01f7a1b7036d22fb0 -501000 3383f0c0456774cc529b5b0633a947e0708156bc873180f56fe3c32008c8bdac 69c86425b5c47c2bc3a9fe3669b0a80aeeb72bad8179676a55dae6445b7bdd36 -501500 d076738e554cadcd99a14287f0d0af18fca6f893e6ab519fff1a9c987e3aa7c9 9ceace4059979133e529e2e33930ee2ceeb2058633e06c31efecc7d2112a2437 -502000 03b70f8f87fc995b1f25c5979cab284b112e66ebeec690dd93e6c1f238ab616a 5c4442bcce1ace2848f3bbff98abe5776b58af7da464ea4d8ce5c681ecb99261 -502500 99130d7f62752e1e0a7318ae3a933b638ae37528134af7b76590d477bee107b5 206bd50bea02399a5ad897c4e1190e96ba7c092f83cbad5e0bd65955cc253219 -503000 3eeca5fb5aa1f44a7a86e9c2756add708089ba817e4ebe983da92bd815fd51da fc3643c494c343939f26a8237b3df02c2b96235e034e92e199980834ed4a59b1 -503500 8034c879f7596a3d9846ce1ae028fa596b84c62313f9b43564ada16c3e2f547a fd766d22b34e5e391c7a3e8c1318ae469a763ba6c49b75d55b0f928c83e5f992 -504000 bbc5fdb678ff466da54e09ab29562e16a798ae2a05eaf776d97edfa35c839a85 b6dce69571860fa8d6db1cae19087b3232b06b8282f5b905a6ff462528a1fcc7 -504500 956aea829d066998cf96a8b8edb9a0323dfd018642692dd7daf59d0be1b31ef5 f90a6f0b96ed84327fe33e6edf930a439d1843046154fe1fdcd65c011aafde2b -505000 0a3445456f4807eb2f234e51acf42870aa7b6a2eb96749ac3cf764979d3aeb14 f6977bf4113ff5e28895c0f148fa0ae812a4dfed4ac0483419d08e3493c90e4d -505500 fdf15fb92600803d9d99b54b13c028ebe2a39d0681e7cb751496a155b11a9656 6fdd6b0729448d9a5dbd5b5ec1198c5f89d0a437c9019c94e0cc4b0cff9344f5 -506000 94533d7531d5ab46aa3ad4c03ad71b8a6f78574805a683be4021d3648a56b0b0 7c1f8200acab1aa87ce1ce548b727d3c47239045d9dcb6d80ba58d908af43c99 -506500 0f86a6ffdc4880c047c73dc16aa8d0bf27d1dde7700c2fd77e4cdd7e7d926cd8 e9c9a93746ec3a17feb362c2dce6e9a9c51a0d9f0d9700d21bd8aba906602e95 -507000 431e08381fac05624f905ca38d18e788204823803e0607106e147bbbe8bf688a 4ac228d8c9c41f4e3d3a3c4e320ed04c13be367680f9fdbe8f6e5a7ab2a23f36 -507500 a227a08c0b6d0818ac30280e4cc9f422bbb17cde711c371acb7fc19c8a642276 6dd10139c09a88ed1692aa137b788336a80ccd60753eb237e90687a15ec987cb -508000 ac9eed373dc35d2906cefc9e3ad2c8044253e75789f4d028b84a5acab33f8187 d4fcd4e62b88c4ef4e9609e8e5c85ba44b15b999dafa68a7cd45eea0b9fee193 -508500 82837e772818deb177c58056f9b8eb8c42b42c75053c206ce64d4cb0caa569a0 088031bb4d6c8d50690782746dae3a2894e04749cb8073703758bf84403f65e9 -509000 46d4c946d3305147e565ccd6bcf5049931048ab9fa78fe64a45fcd29df7edeee 0d2fb9af0d18a37f8bd0d90677391033552038c5d24a58db89420c355342bc33 -509500 dd8574ebf8743606a8b2692ca8fe7c406487b6ba9a0eb1194eba2631c7ce67c1 2ff727ddf8cb09ef0622821c1886cb8270d4401658d2249c402f48a6ffbbbcbe -510000 8b496633b233a6ff9deba1fc40f3e1ecff693d91d8abda762bb165b4f10933e9 3a409f0d90719857a525deb2038518acc44e2e710e3f51830c11f3a83c89ec22 -510500 1052dbabe3ecd64ab6a4b0b05f41c6c4131f5beee2028096f688af8da17151c9 0cdd930cbfb6e609de9a22d029c15c5106fbb5603222b8e470a43594d1ee1dd5 -511000 e1718d99ca8b8c0e1f84663aaa6ac9cd8c369e9118bd6ea5919856382019f5b7 8320100810a7678c08ef0003dd4f057369386278d95ac3d9b316a062b1cd119a -511500 df937a1ddd9ab676d6b958c03e97b7789fc0b486d52e1a518f4d4e46d22db830 e5b333e553b5a4bca5ee6f4a3ed9d83ba46d981a3ce30fe8fe0578788a400f42 -512000 38982a86cf02da0b76412cd5bc52aac39854cb1d000c7f24e6b66061c9552820 7b4b3c77c94a5b9de5a7ce479a1c15ae56663e655104b0f0efb5f3adb971cd4a -512500 c668fd92e5ab8abe4fa8c66022eaf0b8387408849349453ba8751194bc9ea391 aebb86a20afe467e4959eb4704849a076a8e02cbc51c2dfe07648562e42f9f5b -513000 fa2042f44dad2c0e4b243fc07a60172d057c7715b7d7f73e9cdab068df241dca 9bf87e1bf1a619c55107e28f3abdabc3bb3267a0b0225855695ccae2be2c8492 -513500 3ada907b4eb50e027c4dce815bc8464aab74eebaa02c3fff63e829fcbcc06790 1504730fea3476e4a5a65059e9e45acf9fde314062f93761273d0d47ef900b5d -514000 b690974d95cf519aa561d59afc9812bf23f8596633d4e43638aefd0a645cfd9a 53527239f3915f67eca6a1f57a5b82564ca7c4c5344668140b960adb23246528 -514500 4efdb833ed17ee35a5c830945a287adb464a23d60f16c1f1d6d3488d628df9cf f6990f581fe79ffb9d1bed01f84a338213c70bc996261e07507624df42c528a7 -515000 f902ef1df4acafde6dfad28852fa03b1961241be620aa057860c9a70a0fffafc f8f7c7f68536f87056eb0a199f0112974f80f4ca443721ec8c1d67c3cbb7fbfb -515500 df363417aed948a08fe0c6aa48dbc5764fd5cfffadbc7945f1a6ae310a9a1d50 d55f6e43fa28f97008367107abdef40ea271780e5d19a561db5f3af215e60ae3 -516000 6af0f998e7b95f5928801133f52c03133ca1d706f044f545812d0e64afa7eb56 79daefaf210fa29d3c633094944a6ea814f73589d3d477a38fb6d68f0380795c -516500 c7174fb637f35bc6822a651eddde06e842534badc1d7a4c2d61090e79510b970 ed427f81415ab5bfc57f4cfaf8461c18a23a2ca0a7ec9b48002d694c70137716 -517000 f4055907d0bc72d6e28eaa1b566ab77904495bcf286d0dd6d7bc297b8fef7a63 74104317e7c69033b643afb089ea06cafe18e13f125bb7a2f381ac88d362eb63 -517500 dfc6759e8ed2c1078dbf08a64b71ddc9ab2a04fff41fbe9a5c82a250cb3ef4a9 5a544c7180a99ca77684597ca3cfb1257ee0e3fccd468e3771c55e4fd9a1152f -518000 3f867c72bf194f1c257f1476aa4cfd18cbe3a5df52e374b1f705e496e06840c5 36fc1c6723e3e48773e1bd8ae04210fdf0a9d22cce523387250deb28c3793a8c -518500 941b4dd50e5124b756a381e83ef95106d15522461c348d5e032c1b61d838e50f ab5d00a5d8df0c54e297611a063ba4357b4686259473accba2b139ee69dc4d8e -519000 2136325d5351d77945e009193f054b04492a8d8f210eef016a51630313a17c3a ceaa807d0b581d95060026f8ff02c392db4fd0ab5007a86053f9e0b93049aae3 -519500 8740a71b16e0335054adba609b5df4dc066d157dcb0511442d8d413c2333d883 216da33354860bd3b2b44d9f217b89d2a203836e5f0c04de39381776c78d43f1 -520000 21557c530c9135898351f2625779248d5c5ad1fa473d8989e8795cd650f3b036 02327cfdef960f127b2a99811b52f651fd5f84d3064dc10b2b8c4c528a362c2b -520500 fdd0b3a9a08562ab9256162fdf1e8aebba6589b585f34ce26ff0ac20f3b35715 cb7b802cfb533b7191e892348f4076176e842e2a598e373e6653c92b62b4d5f9 -521000 4d45b8b34e350a098a5ec1575639465783982db7710d4ad07f7a299a19b860b1 587836bb3390bf2dc472a0b9e20a5e643cb270d85ed4286180f358cc8d0dfe88 -521500 8357476f03fda1bb1f346946484bfa6cc9d80a89b508255c3c4b583c71ead128 2c2d08c950c6437e2f9ff89d0c3b0d0467a7761a0f19d421e0c0846c2792bb62 -522000 a12936a6677badc6d2c8e83d2058abcbd2deb580e5147f1e742e379f0ffbee7d 322277c4d49c9c37e94b84c184e09dccd63cbf0154e61e36b497369c4c7f3fc4 -522500 f0770540ebe64a0de99c169cd1a7d9c8459eae0e67873510f1a8dcf4841131a3 25ae4d82a8a9089095bc4583c9842984d53bb4b0e6a162d369a70802b7f9476f -523000 72d57e281db8b4a79f566fb587e448883bc1d1325c9ffc2931f1100b63e5836c 00fcd8bff8a5e19824f0e98fca489d02ca2d27fa2b4fd9a73e410d935a1b93d1 -523500 97b2d54ba68ed4a14ca1fb4e4b697b2bf8f7d0332272af4531a72c94c35dc932 04d4f8ef5ff03931eb5c0eac18894a9a7ac8ac7f6bc0b34b43420ae9d7802a1b -524000 f5c96b25808ab9cbbcedecfe467e163e3bd9d771a8efbd3cc414c7adf1b7d380 c11e17455d687b0dbee864879ffb41fa6dfefffd54d339fff58dfa99790a78f9 -524500 cc5a17d877467df92ed0b3462d0031003c642f64896f4019da641d1572d693e9 471a8ebde906603f5c054eed0da8b69aee53c35133712be35b22e5b4a8a3435c -525000 1b009804fbb8489d23d5512262d7536375873ef933c154a7058ec1c934f61892 d583cc3f0f7f01c67294d2e98d28e83c81824cee30d1252816a7828c0461f350 -525500 63de360342a1abd256b2f4a3f1a74da8e5bfff409282c8d06cadfea596220f9e 124aca94373c78ba91a8f1c01d89d5bbeded60581199d3b12ac66b76c37c112f -526000 25464aef8a123b8bc5dc4b9f6b83149c84511a88da41f7b5f6ddf4cbd340dd30 ca911108aa51b78a806e58f876767baaf341c9844f31da71959ed4ea2f87d62e -526500 54cfed1a647b8513e845b57381456d983320e1f6dfc26bdcd4e97da73f31bd60 a5639a2ead728587161e02add9b047738a8534d0725a84c5532bdd054e715ee7 -527000 d601736c31be7964de7a76ee1fa2c4771d804dca1c1a268b608f3c77971893b2 1831200e768d735e9bf8b5ddddb9119ec19c43e22b966bd969346814cf454d55 -527500 dbfd9c8fe9edc773e210401cb7341166fda6e1153a1fb47f866b919dbef91d31 5f15be969fa28b64f5250f0787876b05adfcd2c64ee1c2c72eb9724403ed6dee -528000 92d74a8d4df0a8f7510fab8b5d02692442d1fb8bb9046cff981cecbef3353585 b67baa2dd73a4061188c5cbaf13ed1c063e29193fedcac0b5440e042d39a45e2 -528500 b4a034b57dac02980cec5830c0718b0ce4a89bd3ef3f5f36e8b4181c1f42ace7 de92eb4a468c264b4a9ad63eb75ca3702af7c023481c829041f328797d2e3636 -529000 a05c9409ae06d5bc48284e5c624f8d6f6b001cc6f887d459043f442367e5e1e3 dcb56fadb166de779d9d0e4e5e4d30dd558b0ef3fba4f9afc8023ae5715d30df -529500 f62867ba72013c202a9a61da49b6e4eabc05e6d247f2ffd98235b8e4d862e795 915588450e5ec1300605afdbd6dc47954df1fcb45a6a10953db21bb54bba5797 -530000 35c57a8e961f11ffe1cf6712861b43b4e7d3cc3107c28d6d8722de90506a5b54 1c060c7a921b2d8567acb70356957e7aa044d8e37abe1923ec1ccd3f0f7191b2 -530500 0aa4f3b5419e0844a7316ac4b76e00f3230781c8d320cdd62dc1dbe21875dbbd a3bf6f2508bcf7bf8a6fc19b2a75859a8c2d3a68858d6dedca2de5a5c687b94d -531000 b65e6fc5a87f8d30ac2203e13e9e9fa450ada17650d6c639fde4f71d2832062f 6c4e276f9cc20e4111c9c45b760cb529b12e6f6f9d984c6338e47ecf0d1fd5d5 -531500 4fc020cbe21507bbfef6eb1cb30c11359f8ba8ed0fabfd67181b596859a11fee 736ebd1d9d616f4132934784dc13c0ddd6382616a501f11f84071f39bb794a0c -532000 936bf25a71f4f427a32035e860b049c5e0ecf36b0dc007608b31fb9a496b058b 9c412485687232293357f94ea0cf8a76c84e8757046eae59406f5ee225651a55 -532500 51b5d1a338bf32a3273b45d2dcabcc8fde6bfb68f80624624b8a0ccecfacf751 81559753a06dfa90b7ed984962a88154310cefa89233d47edce8438601051981 -533000 d80bd2b8d148cc346bcc49974171c998a30bad85878c6e508d16c728098d5418 cd8c0e674768e8afa69fc6366c3e2aa66ee31b8a10cceba75d3148857442c30d -533500 06cddea66b25e0387bb678836918cca4be53f245e84c01fdd8194ff147377a1a cc77c89ce8bc38a702e21b00df5e4e65f2217fd7e3d330aeaea89e67b2906d7a -534000 0427f67b170428d1d33242707a2a8273c6447a2762ed42e49580526cee35bb3c 66b923b19b1dae626b62a5c76dc9710d396b9436cb8cc549b87a4878f457e561 -534500 de3c914cd38e7fee1888806ccd3d4cd5d39b81cdd22f869cc5c2d5335fa29533 77b2265b37eef1e316d0d480f28bbaeb8faaefee270991fba6bb5680a65f5298 -535000 b4c2ed2b12c9b6ee617058231e9099ceacfbb10e344c8060df631fc42cc276f8 1cef714d86e11d17fccfa377f5550acbdf781a19f272cc8917c3c9886b99414e -535500 9515324744b14c233fe0463842b81e99c1c7bb28d99234d0c2126ecea9a3250c c96091825c57b11639c7eb8ac6f6c76d48c4507af32c1fc95a93fad60e5b1a78 -536000 ba4a67d76d58f76b3cb47b9f89792153db68285c94062df446d924e59ccf7b87 6208b177efeaa145f365051fd3d5f9e82dba8c42f1d0d2b67635c4a908b7dd17 -536500 865528966307aa0504e45931d75610ae56b4c4490c763198c1570a66f75b1f1a 09c2e4d9405d693c07371d2eae527aa1c2311db979f6d2d0abfdc5467b81cb65 -537000 c3355c3c49454bb38156c96fb23c13fe9e5fb73129bfae6c61ba4e6d1e46ef00 29ce20cbec7687f75730f0e4be6c672d1fcf96baa9168eefe3030116e7f06b63 -537500 895be1cd157309627c65fc37e677a72fd82f27d0418e6b43998aba564d205369 d5e4a2bc8d014079e205050f18f390c776f5b45940c5835ed995817dbcfb9da3 -538000 99248aee8ec1681099e7018b3f27ff7d48023639c7a16f846ceba99bfb8b6794 51589b8c95d4c555e3e85904368362e86c1ca65ee73cf4b3a56348352d48187c -538500 8ed90c82d16b675f2e1616b4e6877fea7d223f4c6049c8abe24071ed0cf55cff 0952515dbe216e7f8705998796c926f16186b5d911466f31d36255852c2a1740 -539000 5eee066175978a2e04f8070ec0a1c5e215afe79e6342f882f272e3ab3e5088d3 a8fcd0b0db8bf7fa522a86757bc674077b64491860fe1e1c346d48b5056c3625 -539500 1fc7f87c388bd6e524b114ae6bd9654031d2cede075e50c5070d5f7492238b49 86203c750603c2b64073e488e635049afd299e58642bc90cfc7bd562fa1372db -540000 c7c3d0e72955da1daf3ed29a7f50e39bbc72a97a7a3b9657151e2180b297bfdf d8789c0edcb9150d9cf88b973a2fba35c0e8a13a79e9f5e6fe67eb527f100dda -540500 078244b881a7ea8079cee149a21afb1f3e12513eac743435b26fca944d1f8c0a b0d2681f5339e6747da87fbdc8eea0947f09458e9e121fe715050d97d5380b1c -541000 c1fc5936f601dbe88f86537a73e3082d817270cfc534f985e6aadf1e69017c62 c5025d93f22d3c16cf3f1be03756c8a04da4c330a8779bb156b6d6812b65db25 -541500 f06fc398ee363680986ea85bba8897ca25e7d7398defc7ae5dea8950e5e10b9a 6eb30b839ec9f6b85ba6a68be9a25f4ad0d72cddfcbcf5bd4346e61905e1ce37 -542000 f1133f6d4e5f03eee2ab13868e8a296ecb14fa9a0fb0074e5fc3cc46a1f7f2f9 b1827592124a51a20ae293f4e824c8030eee78ee82ea039c27e427fe4d2da5c6 -542500 7892e32548d849918dd9946be8adab0f8d0842afa1e9f62c066d27924a96153b 421009927f9b4183293a0e7a57882322f87b30137239b6db48168b25d1fc5ede -543000 656da82150e03b0f6920c13ae9f012c768ad1db9da51f3cb36cb08f597c944ef 3fdc935dccb715960e745f505147ea8508aa5ba7c7f2a657a14ee46eec52732e -543500 9c3e877261982dd30c2c1c7bf6604e64b22fcb0ac6f1f31d133ad853e8b2475c 058abb454a8f38b333a57e220049716ddcf596ca81ed33fa28772cbd87968bf2 -544000 1ecd239bf3296b13b04cd7aa240769324beb8a9de6e35f10c193ce60adfcd2b0 7321ab6022acecdd7ec7526d7fd560c768da79151c01e409de85f70e8d9d9bf3 -544500 ab6981fdb795d866908290b102477a670822935da8f8af9c6a32ee740d69bbe7 c1eb309bc65e67917e1c46e7d0f232900974267e048abd48a1b04e1d4a3172f8 -545000 00257b2829d7c11f95de86dee675a7edb80dff9715bd2ab64d7454182f213a0d bf13fcbf0b1247b11accd940ac8772789e081f0bf1cb70b1425d6288c69b1e76 -545500 ea64a39237ad3d242cb2db3a1faebecd3b20c682383b014227a3f230a3345dd2 09c175ccbaa02745d5f72bb6f68a9b32cac259ecc88aa1f49bb30d336d79bf59 -546000 efaebeda777c28c7e35347e84da7681aaa14c502d53698838eea8aba6e55c1a4 79194dc97f5c84f2a55ca245e93b69b5caa44c6bd5e581044e2e26580bcf561e -546500 bffd9b66e5207f5cb60bcdce5dda495ab78fa6206aed6981bfeb3ab4961ed56c 2e133bc3bb1e140288f0abd4ac9fa18fc4e30ba6fa672f75cdea8fedbcf093cf -547000 b7c08bd8cd06070b6b52aafb511d26a3e4dde18e15ef004576de6c06024f2a30 6aa7c21876ee2145c6b97d41d858abf162abee2f179e94e354799664f38be6b9 -547500 77b94303d50c7c640f68812f0dd13cde9cdc2b43c5f6e3fa4c99621be61279a9 31c6dfbadc919ec783b0bdada382c4c3e1204008b245b6455679b08aa7f2a6bc -548000 bf973366b8395a897b56bb1f9160f8144c40ba17934fb14b46d2bdbb32715fe5 a732ddef1fa97dee750cea03675a6eb9557af9ed6314a162f5ebd8ded9407698 -548500 c2f20ed6a252cc714238efd5531084bd5555ab8ec65169a86c9a0ba97b2a7eb5 d029d1bf6706c1b298d9f7ffdd53a26b17704433c42683bc02718ef33d2d70b7 -549000 7e07ebf8ad3697390d81f7381637048377f461e46030c8eb1feb17eea4c9d3dd 1f2183d7618eabf7356a08a0486675b0163aafe13e6b27bb6179fdaa59685fce -549500 7ce04ee7a21eaffbe862646c3a301460da80cecad0e9a66a157bc1d0c335a18c cc27c95b13f1ece38002d33c7f55f371076fc10dfe1b48754e3418a0222248c4 -550000 0b717011e4c14ba25388b6be779ec7a7fa2939c68a49ad5fc8cccb32a3fc96e6 d95f6b2500300308ce3f44e53c38e6f0eda793b3e1d96f698cdfd8d70888e277 -550500 b1388fa70e3a79143b985bbe2587a8a36a3ce7f90dbdf93c312bf375b04204d4 2f81d9add40226b4b3d3f2466a2330e412de80bc31cf3242e0f8e8c1f45f1a88 -551000 b0f768d89c0f0e5929e41afa3e9711a2f6dd04c71519c718ec5a4851f13ae4e4 2b1fb05c01f17b3eb7268d552a99acd306e4dc0107985d6020dfaf4443dadd73 -551500 891da4a1108be080247fbc0089c4cbc2922d25cf2285538261195b41bfb48747 e5f1700d6fa46e80db5586d1f3261b758d374d43adcfbfad70ed5112bb1bf603 -552000 8a4da9058e5aa3a483af0775ddb984048bec5a52dfefe711d620a0d179856ee3 333c9af8ca1f58b6185db26d60b4fbb955176320995ce208f18aaacd277b4f1e -552500 f290fd729e75722394720a4b82e34da44d640af62c995fe6867fdd9167ba8335 e85093bef089d344639461c61bd1ec7819d5105b4f984d423041d035335e24fc -553000 2558178ee645f229d1b39f11e8bc8e423e6665ce3e7491ca195fb72d8a13034f 0a823b23f9e2761e8f32e42f7bd569ebb56869af3a1093d7a170f792605be7dc -553500 001c1d53874f0032ac25fabae2f92deca9235bd409eaac1aebec39bd798830d2 d36b5ccec99827a8a5d775d707a82836c0a10d13bf9199e25a3c31bd17f66370 -554000 e2710db357675cd18df933733e23992517017ab0507fa218fb45bc9f5d812224 786326555bcb406ffe22d8dd499684db1b8b70df508572f1ada7dcd6eeae85d1 -554500 cd244e1a5feb9d4f3a6c51f92f1c9396b8871ac5a20cf587092abb68b4fe2eec e7a78e8e16dc73cdf9064f039df1a67996bb3eaa744f2fc0598bd07519078b24 -555000 1a6ebd86249e3a3837d8a1eff644e240333704c7f9c48515e849578016d8fc8f b5da194a23915c042e044b0d3e5e1856f7640ac8344a013d7a1c459d967d6eb0 -555500 978b357011addba581355b92d3faf71397a7c55689ac4fb0d4a6eebd8409f714 519677a9eca60cabdfcd5e888ecb570d09275bb7e2585e9226a9b664ad0d7fe4 -556000 edc28b6ce373cf5a5d13e86ffea09ac385d8d2bd251ea07617b10abade558e12 7b3f6c61707185443f2565ad2f228bcb006302a1bec5a203f143e730c681a9c2 -556500 95ae0bac1e11d4df7fcb554f665966b3bb2195010c0cddf48d07803743149578 1c9c7ca6f9c8b40134151daca7a7cd1b7cc24deac24aaf2f3a450b34b74730ba -557000 a1cbf8cd746fe3b27616f6515149cfb57408d82b8147c19510ad13806b7845b6 2287f21d56991d98d17edc545f93a85d01b7919fde25d726cc9cff6f62d97461 -557500 1cd1617ae1474529b7b4f322db9442763fcd418410a3c3e918e17f13966491d4 e71635aa05a9aee0ca857b41574d348954419959f8782b6aa3b7a3e0d3b6fb43 -558000 ecca0843b0d748735413e34ca513454ce2497271cf04a9d12455f0bf07c09f22 c3a7537c5ee0d6615a53e3e30cdcc6433a554a120756be6247f3c3b703f023c9 -558500 0bc0b2dc367328ad409219afddf852412ecedb43e048ee73449cdfa5e152159a 64f4cd8ebaf6f492c200b11b080c521f4efe87e777818f9012e969eb2dc0fb57 -559000 ac95a1595559d38fc68c9dc48d9af40b3e31d71c292a83998398af38f09b3fb8 a65b3a0e37cadbb31f367a83edbc4c70d0537633af498c9ece211c681fb9f671 -559500 06afcb286229def7721d7a5bfb22cb59f1b25c6aea819bd26456d5fe0baedf74 b871a3c694108b366de593c52d6a1b3c38af1849b0092e5474275258239e6088 -560000 538bfca7649306c7ad77eefd31a7cce9b81ee7ee9d20d97322e9f785cb555afc e08954b12673a8e87fc4db6f848c2129d39286fe856ab80f3a11480a82772963 -560500 05fe497d72e403e9753264fa5d4a7348843e07afbd260e21fdcb9898d9de63ca b538d81ebe3d0367d4820f155315debd0b078100fe17f3ec6a0c1b1d989fdf8d -561000 b80da09d4fc326223399fac5659ad647dcf37232eb63546212c7b951d429effa 014c43fc1995d966785af2772de5f8d4738b44785a2bd81145d32236931bc978 -561500 998927d54433d0ea4fe19a4ab0eb8e08ae656e8cac608e3a824bb084967a37e4 a7709319ad385d1345ee6171bb57bef2d0a648278e6cf763068496eca01d5315 -562000 a005e7c48077a108e353402f478f0f3cdbadeb95f360f6d4d056ec8aab302f7a ad678ad8a4b421f5211b5953c3080ffde18f2a395f5f77a467a6a3991e155b97 -562500 cf4a618bbd1d4eec4f6ca3993fb2b3ce901592c365c2b7526c9de2d0c98cb74f 05921bea10fcdc426b73459e8ea0ab421c1635c93b60ee8d950cfa0efa91a126 -563000 ffcd676fa825e67eb4832cc72b5767f50fa306f1dd251055ee3f623d9fbf4d6b f3fcba9c0dafd172664da1d0e692cb1f4e898f23eccce5a265104164a5ece2d4 -563500 5f96af414cb11afbbcf48a7fd1738fc1c8ae91dfe58ccfaaa7149264ce34c5d4 54756714dd75d4cbcf87b452238296c5acbece0f991ff2cf3b239d6af4b7f4ee -564000 0345b35925619ae8f774196dbc6ae52b2d065ee4ca6f9ab87aac366307e1512c 7ccabfabcd36f82cc3195d587e6b530f2e303525e253d84376f02b907e1bf611 -564500 478fd153799b8afd93360f4288321ae7e82aa7bb5474f13913274834bd4b1ba9 b73b7af475c03ffe2bd0e9b09f32a966126d650007f991cde96bc8ae208d2844 -565000 4bf82342209df889c321571400c9170621b17c9b88b60b609a7a9a31a4e6879d d33e0ac1f8f8614cfec0768dca67ba99561976ef142a62171bd596ca26265462 -565500 18ef43d2230a09c588644154757d4c3136a0dcebbd1e7169349f280be113ec99 d3cff22fd147792fef86c9d94f7b8553c555a925e7038e738bde608c83ceda53 -566000 178cd3b2773545e457ec933671f4b7e0cfa269454371789d79c4c73d879fa497 776636ace5ca4a51abb4f04c22d5a2a0c51d42368f43b8b776299b087d1bafff -566500 6e70ed03c1ade6968a6f18aed75a42130abe4674a9cb3d6715d5320474a310f0 9e51b370f5e5b6dd65ffe6fc854265dc071b7dddad6a68e25a6082d60a4573e8 -567000 6a0b1d677c5cc0ce3f890ae8495c70403ffae874414fec9e3ec8b3aa73bfbf12 44a2fd59a3f18b4d59d7bcabc842bc21681b3c82613c95038aec10315bfdc050 -567500 aaa507e4d8344e885c748389b8812c28ab49533b13fa635bb345a4495be34850 f0b2d2e0f7477c8703fb6c7ddaf4d22c17da14d6bb1be606d96b4fe23932ff61 -568000 058e126ea94bbb99030e2be4364db58bbe0703c0fb4c3155ee7c386e19efe976 e68dcd0c11aa8d9b09161d9fdb25196b0b02017743235c5e77c83314139abc6a -568500 369e444ff13a9ce379c2c98e70e2e50e18c823b4b43d51e57224f9d7bf7c2a82 e5755456750a9a92ffefb86ebd18fcb6d4f790bd51e47f1dd92d5d0db8c60b7c -569000 50685dcbbd12f30781fbb546d1a4cbc349244a2d6e14ccb1530059e4073fc0d4 5841f99c2648c1075709873b22b8bc25695c01fb146b0e82291b6a0f5cf16fbf -569500 452253574aa43c9f3ecd39f7122789bcb9c83e343843540860b950ff27d673cc 2ab70f1d2aa896e8a8495df628e675c983e45047d719a9e8fa0804f34a8f82e9 -570000 c1b6627d3100900dcf795d2b684e83d11a797d2302a3bc058dab61ba109e5d08 997761e1d03f77cee9256dcf268f308a14899d00386cf1cdcd9df39a57ade810 -570500 7cd59e7583d4c4878b1dc3171dcbab4832d2c4d61512d7f313ab88782a9d9336 0a439cac39577c5f0188a201ff1ed831ed2fbd5d819c6682d7aecb2e4b77b7d8 -571000 6aa099647512a9654c54e730e3f1d4a1fda25ac58387503932ded2817e5b446f a629a59a6420e7edf13f0a7dc05a918f86f9fb337459a1f85b65cdc71b301d92 -571500 a3d2f0b075cf3e735e586c69c3eeaf7a07cf0f391e1a6ecada1327abe8ab8c8e c97c75ac8bd884337edb7011ce4a68f31d1a06f477d821b9e473614f871e059c -572000 154d5a1e996a34d40d3aaaf2244d5df055de5902201bbefdff166b63d440090e 38fafdb36a68381be6d3a3f358ee61f1998c8647949eb6659f8794c5d84646f9 -572500 05d47c51813cee5f42bf7803a627ade017772b7f4e734fdce5a824edbf480359 ce6eeaba07d4a7d43ae137f3f66d7bd2c3ff0b55b973c0e87283011f58f94fc8 -573000 2cc24da51032f6db15842996a46a0f01e17e7c1fa178d34f4d520e57a1dec5f5 814f5511a95d2112e9d6f5ff9147e4af6d2d14c674008901888a59d77adc0127 -573500 5a412746451823e5fe7cf63b331c59b6b1808d176c1f3562631755a1aec62267 a8a55f440729934a987fa7bcc21e4bed9ae4cb4fdda5bba05f328d33c1c93dca -574000 4e71a21262bee73564eed3938de4c2a673ae763450fcb183bab52fc3739e9307 f5fd0fbd347c9146a3356914145926887833b394f0664b2e5d098660848e8b5c -574500 bee3161612969794e4cc7811c35fb9fd844623da6a5b5f2dc38f32d50728ab90 d97f6edfca11c6cdd984f126252ed5c39587feac95f4d412a947fb327ee9f4b9 -575000 0560ddebf2a1fefe36dfcbf14c0b9e2101445b34e79b4d2d2f7c329c1dc5c97a 58a5850806bdc8a70223873c23aa3a5975634c989d8ef4f4f78fc0b71c025a59 -575500 077c9db46dee33b8fed0edbe55dd09ced1c04eb22096d9a7f0a8238b764a9005 a527ce25eff18c724535306c76670e1a44b010183ad970d41e4168c7e47e8ef7 -576000 f9762a0e8b01efc84c09bf94e0eec3168852cac22bf5e0e657957ffbeb857c08 41b866640d3804e09ffd386d7f6b0cfcc5e95c65991fa0b753c875676eec7c37 -576500 fff9ba66ac3dd62ff0931e644ac522896b5e86c2a23e04bb4f2501145dd96b75 def321280e76f1a8aefd6607ded8cb73769de57f19c641b7c6356e60105d89a6 -577000 69c48c7908b7b71bde3ba3aaacc99951cccbbf4ca98fe699367cda9c2101efe1 da1cfb6020117eb45c262bdafdc11ef962f6156c0c95e68cee1bf1a2b7b9a1e5 -577500 9c563371fc767b2343d7f1cf6f23e4cc7b42aabb564e94a5cfa940cd84330cb2 33aaa085f7076d2841dbce57b42bb7c61739c76f041c130becc350efcbcb5138 -578000 e5b36705e126028107e070cd6b748d0ba1820ef3f0b7cdbd8c60a822011afbe3 b2797c8eec34eb94ad7b5de3c93144e6511d79ec389cd2b3037abf705da704c0 -578500 0bb4c3b62c096285827dd7079f91bb367f08fbf323f01cc27257c6ad1b6b09f2 2709c029d1cd3164ac618ca33d9453913f52247ca266755995eba29516fd6693 -579000 62ca69f749191230d6588250d41ff452312e141c30bdc253a4ba473d3736c8fd 9690b50bbb4fae4acf7114beebb9c8f012328638fbafd2f54c18db4983c019fd -579500 ef36ef78010479cc9664a2e7cbbeed19da7b60b990ae1d6ca1c62815b74e4ac7 dedc37c50f5ee81e9697c49243e55aa6ed5c5ba8d1d56305c5120b308600fb6c -580000 439f43597ce36aa161cc2c4cd7c25607edada72003a7fb681be2f6d8b714d14d be5636a23710b20c61b3aa181bd75a4e0992dbfc1d267be7c66a3bb459ad10cd -580500 c6b2c13db62622a7c3ac9e8072840de5d24c34f6337fc3d8f826933501245deb 25eba3116b640e04a77b843ad79a25847d31c2c5eef7da98952ebbb526440eba -581000 4dcd0d20d94245063d630bcf6d8079cbc52dfc522c0e320e39c16ca18853cd6c ee3c988f0ea99a39c2cf69e88ba22aedaa2710f49bbaccd1ea0b2c1ee65648d9 -581500 44b084102871018a5db5f990085f3177856a38a8b727a36b29837c34e4a8ce59 6d6899031aab90e68c34f4bc3c1458960c7debc0e5e88de13bc0d29d9a4f1406 -582000 4fc26f1bccf775fbc7314ca86532fffb93b9be94bc6f1bd75fbcbe688eb9dc1f 07296b68ecad02d38df4dfc0c927b430ce4c978fd42772740cfb185d1f73cf08 -582500 fcdd7ac7dbd7a3ec5bffcf498ca341ea6f45eec4f07fcf5d838805979c154e75 1fdcf21608195ac2f0076e8203f72e8468099613e8edd350440efb4fa495de35 -583000 d32c77f1ee2542c91734ccfbbba36b35dc4b76db17374b52d514ab45e03031bd d7414a5f1b9e801ffdd889f95d91b381486c2b7bfd718907df3e4f3c16f831aa -583500 bf8b25a2a0b19d293bc739d63786a6e5be7cf111d60d6cfea462dc2cc7cab22d c03d273bfa3ebeff31d43a7a1fe34b51a5c968676dab85910f61691ea66cd879 -584000 b3ec434425ed197a317fe360d7f2bdd065a7f167e5c57bc9623cd150df2aa5bf 42bd629da8bdfeaa2aff0cbd4092f1db54db6da4e4487a7460ca7081849b1d01 -584500 f09dc804f47fc9fbd5a391883d0be1d3ccf5b71a69e9c2571ce1ff55b83422df 28cec5b73ebea11f29daf62db2ac9a594a7497ede4087e0932881d39343d15d1 -585000 5874d180e9c48959e292587310dd81134eb03197f0257be1516c7c50248fc3b5 c5e42637b4e90535090b09f2d90d7ab90ce46eb3255ce6abad941ff07ab5e0cf -585500 a6dd4e58143b11d190e168b1dd20fd7da47ba2af0d089f70bdb5ab423c8f47fd 134ef498a9bf87099abd879d68ad7d67ef4dc45b63bc16438aa0f95092e34c8d -586000 5fc5f5de827b01b620304dc74ea53a0fea4f814bb51ec5fe3b6c74ef560a5917 e1d0845de83160f08be85d114882976278106adf7a3c16ce16ff6f08caeeba7b -586500 2d1270ba120a5cf1427736d7f89cb05c42af508e0a0038833c9445dfa9c66fd7 be7998a06e1fa3910cf77a7cb385cbc6933abee919664bc52a52afa5388c5b0f -587000 47ae47f30d7d51e5b874e5ae103aa38208203f2a380b624cbe1ba122d222f9e5 81558ea382a62cc93ccc002e8ba9d88058ebfe683b05be16fac0d84612ad2152 -587500 a558bd54422bc5d0a90c20310f81d9901a9d3956f5d5505a5dc50b6459ecaffe a8994820ef7c6f2fd8d9b6d710a0f83b537ff6fa1368060418cb00ddf642f357 -588000 fe5749f9e8ce47f885f4335cf2b24a6659913ed62e7d5af026ef0470004d4983 87e2b4277260305d5bfbd921b2d4592e180837e092f2acd3896621cffa5228d4 -588500 4c798283eb8cbfca17647b16a919d49b77a999d0bd319fa624ed665b30172e21 a4c43d466e6429ac399cba93e1a594703176f7d1d7f86990936973120554c72e -589000 f8c9ccb89cd751d66c9e2b053cdfa670556f6dafac1e67a12f8bf06790c9fb93 ef76c7bdbce08ea6dc8dfbefec9d64b2bbf3180dc4304ee7e39d8c098ce3602d -589500 0971e83e6a813fcc290f352ada5422a0f48b12e15628f9522d1ce40b2fd01e85 cd5ac7829f9c4de5b606b3a5406383ab2634f09661977f867c47d58f89f16081 -590000 cc8a0c71618970a1cd40ecd78572568e8522faf1c6cdf597def52feaabd15eed ede2c72e45aef2c244f56183b127ef08f9137effd46386eb8013f1435de42f08 -590500 6c876707aa719eef0d5a9534f9961ffceadfdfa16e75a4a8c7f5c7822f8d9945 44d6b98fec0842acf25460f93ac90ce132d3600c752bcfb18d3e4bea90b9e052 -591000 5c5a7be46768f7b29d8912feb8eacabb2c592fac374fd8b1c9d74124a5bde94a b725f0ce70d650d386e7fae730da1d44a308d2517c91e0f6d6fc659316647202 -591500 4df0cd912fb5772a508f9ab6fc5dc26ebcfc8e5fda9026d682cdeee3350f7f99 1a9e6cf241740c2f4f615bf2017473e6eccf52ce14ca3c244609c83411749374 -592000 5a9465ba2bf3034272ebb1a8b742abe5b66607193dd04f838bd9a2e9525081c3 c36756b7c0b4f7577f33bb7a6a2cb06d444e5bfac823242a2208a74dfa4a5264 -592500 8e712cb434a6086e1068c5a36a70ac8382f8bd2df8f3328e869b5f74c4d3e268 1f6f8f8c7b6abb35e1bcc30443a2112a1cf6711f020c6474ea2b987e122e2710 -593000 5d4b59deb55edff702d98ceafe7e74fb2c27a9e82b3b8f38a747c0013210125a 397321c39e0255bbf2f345d8c410a3a75f0cddf11f90b04e1fed22d57313f436 -593500 efab77d82b76d1ba1f130c61a5146828ef22808cabae00e8aaca746c9701756d 5ae3383c918a2d0de41ef7e68ecc81a14448ae6265fec8146377b88c14678583 -594000 2eddcbffecddf8dd19c6183606ed678b8d3c80b3d18a03d1f6c98de436465bbc 313ed4476687d320b09ed8f775c84f848b315ec7051a819b7b5db928b06b10bc -594500 17c2823062fbd036efda8d7a6cf9f02177470df9ab03a1ca6a49a4feceaa813e 967817ffd15c1eb09ae18be9c89af301d4faca27bd1435a4c1b016328efd7452 -595000 0b2d83d89d4bfcf2ba0bb0d6f4f002f83b33532a9c72d204b84c3624b82d1d12 ac1ae8086c27ae5dcb5491883fd2c00dd1936ce5ebb753bb9721795b51ac427e -595500 94e93ae2421b77bdb8eebc5a889e0dbf64bf0af3a9d7d718b92c626186186adc 58b3debd63420f3503c3f813e1fec6e2dc9de31eabbfe6a5517eda797c5a1381 -596000 e556867900ceab6ad0fb7923aaad1331b8a44fb432ed5479bc8255a9f9889db7 5608f70ec745d7dd10b0d6650661ee7db9d15ead665ce8062892cdb60c51b81e -596500 e07b8c8db8312393c02cfe1bc00a1a5ee6166083702d2db0fd24297095202f77 3df091b27bde63d70fc8d0feb4da1e97ee21915b24f6be2a60bf702051c243d7 -597000 8e07ad6645a83dc63b311fb7d39bb583980164e40032a0821d0acb50953b8ef5 96c796666a2f4c215410baa022874914fd9c04a430313d38e98f6c5b743b969d -597500 6681cd271934d16f89af3d71bdd886f5d3d50f6ef9fbe17c4d95eefb6c770974 e7909149c034c8ea84b92f77b39a9331560661cb4c158edda770306a4ed7cc9b -598000 92b359d658152c31b8c2f32c4509f3ccb1cc18b4544745608da9a230327c109e 3f75a2b9ea70de0fdc330ebbc5f83301dd507c4e0fe536200402cdf30fd28a12 -598500 be474d552a4f17ec673478af48534ad3c65eef1752223ed3012534dcc4274db4 9c304d0d24348fa013c7223f1e05fc9092a773e6da14920e628baf05669a0f08 -599000 275ca25666031af015670734cd4fa02ea0e0b099921240991498e684bc234940 83b44eaabc822a3d26f168dabcbb175357e1a37a025813fe30d5e6560418dc4a -599500 f20a2a85028e0a3c65f118e50296794ae25821fb5dc0a59f415305d826a827cb 3dbc1d013d4559da355fea928c27fb17e921124893b7052f2aced8c8ef9c9085 -600000 fde9cb0677887e2f966c3be87d1780db88353977fa2e426249d9b26b01be1db1 74fc8f58d336eaafad2f515f0b5a5eaa679c82160f2dc54f35fed44bb845c395 -600500 ed2fdfc9d3b07cd7e4d4fb46b5cde484b7ea5cbd436608698ba0be6407928d45 78eebaf2d54a3f5ef9c98b58e75325a263d7040a85d2757eaa6fcd9edefa8bfa -601000 3a7b3e53a5c38bb7d0600352a71701c8c7b961a9936d319ec1f39eacbfa317ea ae8e3de2cdfe471244ac6698534f60a82a93e59b36ff22135ad57f5ffa9eddde -601500 9ac84b004712eedc9cb82e4eb4f459e92634ae20ded19ce2a01b5039bc9be041 b1800a6430feb20276c6d1f65b1042d5da3d547a575d7aa8f8515985e793cc8c -602000 e584426ba4821ce97899bedc37ebdc5667d94f796853b5dbfc8597123f61cd93 670512bb3eb55350a01e55a614addd9a1936e220c349b5fdf83ff85d36ee4762 -602500 98c1693b6c94cebd5e17bed36779a7c1498f43d83c3fb9f833ac42eb3b1f148a 4335ab6f363d6556b820a8527702f5b224789aae810a9799c40289f088d876cb -603000 cc90f10fadd0c325018a7f5b2819ef126eeeceb29cfb1abac3aa4d918dec8ce6 c323abc97d8ddde6d935f4c4a3748fd5df141948b855062c0d557814b6c57582 -603500 88a282051002196bd7e47c2d4d05acccc49be9e0a1958c608bc8857b0752d805 4a129ae3447c19b8a4ca1812fe819cc571bae08dcee26b2f312bdb2292e7567c -604000 8423befd6cbd718339237b9fd01a9bbc7de101525a01e45777cecc593795e76d 10125b30e2a5762ca8991b3ee699bc69e552b65457759c8b0a85468f52575c2f -604500 5f07bfc38f07c663a551462ef3fffbbe9a1f01d54e4987727649b2cea7ea3716 f17db8519ba7ab7e3cd0442a008bd05dd5354ddbfc696dc9e2aeb07385929acc -605000 691b12ae780daabc6228123ba85e5d4ce2c48d1f6084a428ed5d310d644ae101 15ecf51f40220aff461a2662902a91b0ff974c6b5dfc6853a37d492ad0e7c507 -605500 52537e09d147a2eaf5a3e843ce45824f3a0db686f36cbbe72f69fca61a2b1c01 ab643490828905c7be3f1c8afe6f7755a27c4cdfaa5c8488fe2441aa6afaa70b -606000 945062759b3b417205cfff5d9b2e1c29d29fdc235efc71971a5c930ef5fac2a6 5cf40892ca34be01dfa549d94b8784051375b2949ba916931a8addf7eb3a9216 -606500 284cfde9bc92fc8a9a75636ed0bb98a68a7d26fa82acfdba09391939c2e9acdf e0d8d1c85bb390ccf48b59af60483c919c08df0f8830de5befe65a43a53a99fb -607000 fabf1c22a50594542dd8cc8e0aeb6ce78992e1fb97dd46f25b1f766392b8c466 c42f95954963685fb338b1ebf0f0de3c8fcbada7fa53dbd4c0472b7cabb75eee -607500 a2af7276cb9398592a0f0d137875baf3d9291a606f583b269540f9ac44a17ce4 b5170fbaafdd9059ecc043f1c4ca714de50133bee7054f8c119e0eed79e20ef1 -608000 6a78949783e00a8ac3d832c24e69a2c6fe028f110e8f1a7d87d652acfd5b6b63 01ef19adaaf1a1d75900879f2c7bd5366ec4a6811ee539db16e81a2b981c192b -608500 1941dfc27e96aee1848d5fc8ba94bad2507ee14f8a24235e4b35af5dc0559f05 559954098665a3b7a698445445daeee8967c092ce38be59cf1fe78ce354d221c -609000 ddb824a17fcc47e7312cbc0b80838b8f4fdc077d1f8cad5b08008aad8a25afdf 528daaece3c6a912cf0859f93018845f781575fa67f27479ccd56480f40b8c10 -609500 3f80a004163aa45d2c9d2a1c8bb238a15b9db4214c8b0ca08effb0f37697c40c e6a2eb1304a43261fa54127676cdee58792115ca1b400c4a08261f1e170f19fc -610000 0362121a825d39875de7eb528be247603e5d93922f21f738f255ad44171f5edf 3b57b352f45dde9c233dae766260ea380cf6114c7682dca95566e656e9be1511 -610500 d39319109dfd619800add37b85ab545fe8832c50036eaf1aea5489348e749f18 14c16bbd895be10be482c66ae8444f39cfd67f9c3c244f86bb3f309f3f38ea3d -611000 274d0b2789a39a2808a69e9c7d4fa6b2b34b7be5ad55d541785f6230103a6110 610d4811e3da6b704ea224ce3cef798b3fb9495609971c09971691d88b714885 -611500 c25930007a1325f971285a32257362f90f6b5da474225d3cdd19b9053a55e6b2 c052c3e6c7b866d2212ecc66d4956d8b3c0a9b97381a822ed203ea796ba58581 -612000 8dc46e21fcf1b95e59d6be6454adf1db9d141d9e78d583c0f4efa47e0b2e38a8 538c9ffcee5485b309bce281d6913a254331647ab43d492250c66318503ada14 -612500 48c70c688ae362b4ce2e19325b0bf5335301f45cd6f0f562ff263d5d57324a2c 06f90f226b98bf0fff455478d39513800ed400dc9dbf41c3a6e498730c883e42 -613000 a05ec2324bead1349845a8000c76ff7705e0ed1f958dfb46c92eaf3180f301f7 4d6d1eefb176cf04b6cc0e9554cd81bcfb00e1f737ffe5e25e752f9eacfb20bd -613500 6d0183915fa23fbe61d2cfa7dc9ba9c54c164b246d9f3ea2bf28c675203896b5 e233a4490b16a593a62853877efc01bff2e03b4e5017027fda754056171236ee -614000 dc4d72e154553d04502271aeea36609af31e967faec981fdb7aa7686b194ef72 a20198e44d09d5a45d18b1b2e20911f6d8840ae7618e39f1805dead4136ff220 -614500 401187c2be8053257741c3c78fd751d5aa80b74239ac1a5fd7c2008623b8056e b3d69a8f679aa779dcfd6b03d44da4318c10241e1a87c8de46dc2067879e7561 -615000 a7edfae28117b555c502b1b0866e70c2e45b2b53095b0b3ec0518f76a3250e96 180c90afe2385b2149b5622d702e1ae33e1908e03fc9ac457f18cc86e3453813 -615500 247cbe6b3a28a410c816bbf3e344fd707f5b98c9fc7ea74a653e55daae43aa7a 675ffec485147855367994e9f3ab4ac5ad7bedfb39a35959ced78034e9a04318 -616000 091e39d1de4719fafc22075635a0ed10d1d8b5636a21927557b2baee8bc453a3 5cd5dc9688dfccc2024c771720a75202758606c6c2b62b3317eaca215338eb9e -616500 245d68d439cb7cc9d17d41d8748be112448c1c3d757746c28c32e3531a23a66c dddbe95e870b48d8e1d3be72da7976def8a5f96e20846bee2ec8d3644de876bf -617000 9a08546acd2859279fbf0a140d792be72040b3b5deccfdfcc3a40d640c60f35c 3fa1b0094367169cfe3c3047b01a8bbe5bd1179ea5252153da7113477dda7bb6 -617500 ec4c7a99f349f9b610a1c2c94f01fd8e37bf98d8feb6a68874517a47b27a199f ada5742a01ae9d78a4aaa0fefcc2542633e90bdd178f540e802a4e5bf96368e8 -618000 30bf0bf59fc693f06b630ff38f55f5788f24b27fec1c171fd5f63b6a75729f83 a4d0bec878322f07128ea1f7318a28c492a27649b4e216332589628ddd9053ae -618500 095af87395d73d93df9f2531ad54c6a486b0c98fff5e59a75d9f468e2317b989 c98bdb9ed3f618281b60f496fad0753ed0610f95899058a5662a45bdc30f2c2c -619000 53c7aaacaaf469764119760051cbb7be6806f80d51f75099d8096831443712aa 8e52bf819476612fc0943a9b56d5027935ca897f9a5dfb686cbedb8dcdd83bc5 -619500 7e55322d59a65d0ff1be11ba083fccc9800550a273a52a77926d5a67c383f429 1cde548b5fd12717415c6f8ab191b0a73aa77acfb6c8db2ab9ef1f374bb8fccb -620000 ce46ee172a243c059752e237dab267c4c95b111745b808bb9ad1f8e99dbe84cd e14873bf1154683503d0b3a1d0180742f3eb790efe5a968845a337a4877f9cc8 -620500 31fca5e075086e3ce312c78e4e67a24a245c48db04b7d07688a46be3efd12560 d5c066fadd66b4053f35e728308e8e1e9594693f9afe8f930e342f89014e1435 -621000 c27deb337c86fa6c1a9c967c1c0e967d66ca91c3a605ee42ca9ecaa3c7801715 4bf8d5ac8c9c275f434ce687e9aa2e5bb0e1c1a8634ad7dc0380ad74e9f2a471 -621500 6d6de5c0c183af66e09203c1f851e005b11ffc3e65821a0b0c53ddcf0577a86b f8e09ce62f6793636184630998b1cdd6e513174a268fedfa3c23d1beedd6f127 -622000 3bb4c331c1c410066bfc9c84fa96f35f008d7ebbb8630f35616b07d3a8f6bf09 2625b34fe7f2c205449f2ff67a4bfe036ef5f479b520c16f0fc16ffc43e5e713 -622500 b69c590df86c64c53eec4355ff7e4525ab0ede7c40da8cb6304556c465708619 ea025a51dbfa831f98ebb1597cb43dc29f34d18f5522b57ac06d7e19bca1ed39 -623000 248e12a541844945c6b91e45f24d7f63db3dfb41016952e628c647bb82562c91 d2dcaa98eed5db5e34581c8bc52808819c5cf98bd564661252e24fb7f98218d4 -623500 0f6332963afce6ea94d654d103c3604c724a5a6bcdf6e32bdf9a708d10de519f 80f5b0685f010693bff7453273d0cbef3d878e9753b19e05a5d2fdb4984f8a0a -624000 3a250bcfa462ff8b750d0a725962879d47832f0c77b46dfcd27e3eb4bf352257 f75082779f75cba11e26f60eb9556caf48daa15221abc2b4a83a1cdfff9368f0 -624500 6a0ceb40f1277b4289334b6cbd593aa5bf593160ea960b4887e40afd2b06d767 54386a3f312db13d8151cdb5ff628ac2e9e13d897287b553d581a6c74cdad388 -625000 c28164fd18e1087787d2e3c7d67b8349aafcadfbf815fd7547fd7ae8da9e7937 319cabe08b33898fc3421e1cfe329711de03a92bdf21828a59594e813e71393f -625500 00c9e51e1237a00f30562f40f8d7696876a62523a7888f3019103f97d27c2afb cc7d1fd4e2d9a95e3a9a7e23f44a96f6840036265a29cac5b4a364ae1ee1b806 -626000 452cd22905dce67c27114fdc0b6ca64f4127abcbaff999b7aed68be214fc9313 c969541e23ade41ed8ab864eb6fba11ab9ba5c6f29374e666af4912c2c076de9 -626500 7a3f9fe36cb72b3529747754309d2fec46a8155a6f297bf5d9998336ca26ed2f 9184cefba7d61de4482fb57cafe1420eaaf58e3f2fe370e9c22f2dc235c26763 -627000 d8f9b2f906265aa50c5eefed906e89c06856dd2c25bfa2df52f402fa029b6c6a 1c5dfbc7bb572903d6eb6a400fa50df3c18c87cedade5b4ac63be7037f050a7a -627500 711651d2f7440f20927ed66e680d833755ffecaa905c0712ed31e1e06a81a4f1 6de06425cf412c7d272841f1b3de2652b15d3300902c0da6b7c1b08bf4e14112 -628000 1f04acc62ae096325174e8ae11579d88e65ab4f435e3bb8c41896a1cdee6e231 c87dd969f7dc7a3a356d7935a69e4c8a4487c72e7c623f49cf0f60cbc438aded -628500 f55649153110900f0fa6b7d2f9dd6c293bc44ed7911a6e4d52ebe5563eb3a4e5 de1bf3695afd590e9ede9881a431abee861f4cac9ab8b42cfdb8c37f0e02e19c -629000 8e7208c5c406f95dae4ffd540aeb30a111696ed10374f03cdc186db66295f054 5a8b55bcbfe3fed8453499ed4c4a51233f65626132aa23ff6acae30dd5cb3800 -629500 30b5177f1554053efca360e8acc003ef0cc4ae26820331715fdfeeb2003daea6 f7e5d1c5ed411c3afd3a51d63abc4f29fed49ee8bc2f810481491c138cf09183 -630000 9bbdcad95ee5cacc45ff51ca8d627ec7a971b1040368ac62a4616f873623cc79 306b7845856f157aa25e14e34165e75ee5abdef7337cfbfb9611f628287b83b2 -630500 cf2b412c6c992847944b1fb396cacf61bcd03aaa460cd810e3f42a2866e8d729 8d2c8d7be61fe16d9f5c0f5ea155eaae7f926fd8011209de27e41cc67055f5a9 -631000 ea5e4b4acfeba1f4a69c63647cbb45147ba1dd101b9fe58843dbc6fb09f7c12a 2ef37567bfb65be1417d9b5914570c55bd88da0bc07f7ef7389e6324cb0b528d -631500 539334450cd6eca49473d63e4917725250afbb6a546a025b57b40e4ced8ce63d 865fdec23689d881dac49ab8fe9a20c5984f42b4be7cdf3e94118a4baf4fdec1 -632000 dfdc58aa41d2ebe7751fe2b3ff90f0496e602cfaef1fa0f1c25181a3be4cebf5 8e3f86b2b753e8f342046b61d84ed4d2e9ce107d7f30a47361e983aac874f448 -632500 54f71b9330b758d881d325e8f3ac9e0f042d8ea1222e52b580a0337a3b4f3fde cc0ff7cff02212ef316bb6fc2a131b018fef8b6dbfac01b9e2eb275c9008c613 -633000 67de40386baf1179b74ea2a750bd20d6de8f6ec3cffe5100aa3307ec81bf3a4c 7d69bc05bf967c291b2156c18c0851caa853110a8ee527bb9872001cd8179b34 -633500 4414265aed7c038b6f7ce24cc86619b0596162ced270a87c70a59ee3089165a5 09970b09ad4958924d24703ec56fcf49a7526a0916cc7f0f841ed9796bff86f0 -634000 a55d577e338fdde481a3cadfea26ee6c1777ddd6e35e66040a4d99455626d9c7 5da3e590cd7190a473f7d61027754e5bc50545fceb8867db96006d3773a2b746 -634500 571d3172a3095d0a34747c18c2e2cbaa4173a09ae3a351736b2b4802752cd9b7 6799dc3c2b9fe39f72a22e6fe27ebf46308c887e31245a5cbcc2a55f1060ab44 -635000 6786a43fee0f379b103bd594943f26eee0f0ab3af9dadd36d6afee547d7ff8b1 60794659a5de639280735ce3ece1864a66e5754bb1608b2aaedb9874a6c34d51 -635500 bc5896373cd6ab14f28a690a7d59366ee57a625cd6291c502d64a3a9a5969a96 cf6d7eb9c0306f24bd7a47fa0660804b633f29fbfb647e79d03a545518d5ba17 -636000 1aec8a1d1f6f5abb68d49597795c24102bfb767822705205486829ba50940cb7 348625a773758822cae41638d27628bed89a118fdff13dbb773ba28471ec914e -636500 cd844ea294ba265e14ea515b603d35c2dd13c9c402a4a1a13628925634e81f23 2c881b78d84e98a3a6dffa6d4e55c347947053f184c22f2a75bf62cd779febe6 -637000 7f0393f05b3ebfd7838740f3030dd915d2125e9546e39f503e288a20b14d29d0 ffcda35e368f4784c75aa0e6a98485a2b84fa1ccba37f7fb5a6b4d4e187a5033 -637500 7453182caa6345472aebc820d839d70e916b8e01527e69d2451e68df9f5fff94 df9418647903ff269234df3583ba76f054c7fefb3237b47206f7e25d9ac118ac -638000 2917816bff7d73f4b4f03a31fdbef162ab7b2bc38e2539952648f7e9b66dfdff c7367a49d181f9e332613c76cba3371c16cff94c10a6bacf504c8ac404358b74 -638500 e10674d6c53842c520040ea608584860418908244a9203ea9e726544ef6dcc6e b67a32293808e06725a391d616889dc4a438c8681893c17646896d19411e1cba -639000 a4629de92adb7ee055af0b7a55a0690efde637a84e9c19fd423aa74389c7ca4c 95ccb5ef5e2720ec5ce9635d8eaec7d000b16b3abe24936fb8daea2def31b681 -639500 dffba976bf5db95ba5845ee2863a8f60f855391a80d3a59cff38762f0992b38a 589744adb3b63b274b63d7c83913c65d121c13dbd8399aa7e0f317d4b37b5155 -640000 d5c3942c19dfae03595dbc0683dc712467c00e5307bfd96609c4a728eff4f586 33aee46df3a2c807e3fb8961929402532d1f1061a5e1df2f28335ab40002096c -640500 2efd0a03b8098ebfb96870e4235206b8bb428b5aa568aab56db36e3124c98c04 e67d6fe1642bd591df2f838f07190f8477622358706dce1a631819c828dc4980 -641000 91beaca7dba7afc17cc193cabc2fa7c34be665d2d367c9f0d17a8385903c5299 b90b505393575a5869ad32b498b2fe7ae026db5e3be2ae066ee4c8a4e50ccd0d -641500 52a2ed25b8afbf07e9bcbee8bab225af6bb0834b500ec30114697924951b9db4 0d30d77943438dfd2b1d85adbfe26de36a3f821303c50717d3a7e55abc59cfd5 -642000 24cc44ed0510958b23b614206b702fab53cb7681905d1aeb12fb532fa850a415 05e56dc42c34c44ae0c67c45985004c753588fe4588a4060444532194840e5a7 -642500 2cacb3c0be5a18667d5972d99182b87eaf485c724ce81cb59f3417691a920977 1d5689874267933eb1b72a5696935202699416f5f064b689e7221d6dd4a2c3c5 -643000 94ce4d9dcf18b532dd9f8a490fe270dab5697c14f49b7326efb3e3f82ddbe7b9 f8466520f91a0a9b5136c8ba589bf7fa7a5ddb292516ea1dcf7820d3ee7c0cbd -643500 e3c751b8fb071c5ef4fd1e7ebc9e902d365b88c3dd5a90ca5386d7cc42813b39 fb799e659716a37ba6e9982fd09e8848d637ef1d85555c61af74dc996e1c6908 -644000 2873489104d5b817e24659b1c91e0b4ed350c388563670846658b452e279a44b bc4bee8a1c8a2b98d32ec490a31632852f7935737bcad951d741e789ef99d15b -644500 2996cff77ae12636ed2da94137e2dbda45f5db09c968e13d9002d9d5e8d1bc8f 1482ea5ca89d761a9b99c8e0a5791d430478b289ecd506b3b1ee803d90be7f94 -645000 db1d293ab843d88849874e33883a8236a8bc4bff1d93b7d9922cf1f7dd3d0803 b13760cc8ccad388e7a35b3fa743b2c07b1e40cd5604c3d4162695d02bf601dc -645500 0c98834ca2fbd0b1f4b7e708c5f9bc9e820370fdc2b1126aa50eca16a46813cf 95b1ca36aee7f85aa247e91eed0bfd17f8ea675c5d9db342d9087017117d73c3 -646000 dea1a9883f1c3af496fd37570580c5c9a1e1ff7e8822d70188737f7aa45df488 ebab9f3327181450b58a388214d86b56c395f2e90be9f7d595ad7ec863e6c1c0 -646500 5cf92252a010e2d62030e5d74d6371e873f7fe6353a010791c21307d8236a3a3 392318738e04bc641e4375f47820bb59664b62c88a0f62a3f1bcc75be023b3d9 -647000 b0a00219234dbf1942eeceb7a31565ed117dd8a8152f1d343277433fb3a19233 8cd4d156025aee385a9cfd46d38594d1c4825f52555a703031c99c005adb1513 -647500 8cff85fb1e3b4a7218a58b6fb2e7d0168fb5a4ce4171bf3f0b7f1e7a5f214d0d 50dd61b46e224a437159c8faa7d18cd9c100d1e3ff75eccd770d8debd7723410 -648000 133d2255f56a3c2737eb94f337c9fac97214a7e1f54e8ca9b4bbfc6e056443cf d10ca77595aabc294483ef2fd07975ec43cd2e0764d0df38786d3ecb5cdb810d -648500 37691423db6098cce3ac61dd2e0ad5202cd08d37e2a810a4b7e259742b50f561 4fc55c6790346c316db4b0f1a35d067052bbaed3932cb8a369f8263791b9e749 -649000 e8f43ecdb6979574c66b478a2d3ad028145349c43ac18f67e089f6948a48812d 7609d55e10c1b40d62adbb39792b58b5c075f1c34c6f8676cbbe39e91a7e504e -649500 18f631309a2acc38dbd4d08322998f0d4fac526eadbb1aa2ef1ccf75173adbdd 83794a76b25f0ee49153d50f9bf6d196d1b78bac25dca55b9d3eece5c8c1c3dd -650000 fffaaa151d0634fdd830e104f884bc05d30160640eefd126e0e01b43bd5db5ef 7ef1c36f637320886b505c0ad5847bf0a345c6abbf4e92432d863b0ff517bb91 -650500 bae09e49248acd64fdbc94cefd831ecb2a957c0d5aed72644a3607a198c77740 f1ca4b8b2e74774fc3d86ff3f2b5e6ea8d59e40a683b993fa638c6770aad547a -651000 5d9f45be4e7d558b3133ab3a7d01a96db73f6a16604f4e348fe04aedab48fc1d 38c0484fb001d8039ac07895bf04765ad79babecb93040f8b45e18629c1fe566 -651500 7e12af704c44d001d842767b49709eba23ffc53c8a20bf96b0cbda7955168521 3e563eb1f016f0b9a83caf023067785be15032588fb1ed9d6dc2e7d47d7df8d9 -652000 6577afda5b1a2535cf30f91faff821b56dc9f969e590d406f644518ae4dff6ab a6aa3534f3f962041d6c88a5c413edb0860aad04ae8068ee31070716e552c03d -652500 f60863237c82f26f35682a510882c8c8b3ddf302e479fd201a5532fe02993d3a 623ee7add095d1a51ccbeacebe34fde662c727a14ec2ce8c856d2da57ebd1537 -653000 6d2f869d3cc7314a06868edf43473c3eb2a4ffc902b6866b2b6d9ed8254aca15 ddd54a91243a02e778e23135881e1a17a5829d6a698410cbc91c9c70047f5463 -653500 32d04fcd783380025ac2f7776d0868e44808c446df33e7790b9eb06edf1a13c2 9dce2c2f0200948be45127d74dfcce50bfe2787f01a1f62cb304cc7644754999 -654000 ad3da7c147ea7020a8854d4768937b46b2e9ddca13d786a2dbcda5fd691aa264 15baaddcb66534aaa738d7370796b82234bd7d1a183081ebd7f452a33254bb3c -654500 b38fc7f77f763e12c55c816230cb83453e513d7ffbc2f71cb18a4b970a30b6dc 8b8acdaea52986089352c0b17b8479def4e4e01d8f797609fce1c737e36f4314 -655000 58642d4240fc44829a1c5fb427e034890ca40c5097aaff77eadcce464be04701 11f24474492b2851fa79a42ff8d8685162e2b4dd1099722f3ce9ec4d5686cbfe -655500 d71e2ed94bdc78741559fb4c58bb944dde0adedc05e7558d7de6ab254c332fbe 7bbb488685c2ca7c84d98149d2383b157d88304c5b34aa7679ac24ad5c85b006 -656000 c1d7426dcfe8733c72b8fae49fbbd127a6e257ccbe4120600f8454287ad26105 2f8f7af5f2ec8a3e0333cfafc069bdfca90b0ad6b99ca970b0f458bafb0dbc3b -656500 c4f911e6a72381235e92a8c58ebf6fc654e35c3f5f4b2851f7f8a9ed3949e047 3d157f3d2c8158bf886bf994e549a6da2db2c092266c7050b831c8888d62b205 -657000 da224ea959041cf5d98fa040a10ddd7a1904725a649ec84f2ca403a8117c7f5b 9b9b9bbc0221a24b8642fadd26c1157ce903d7be532aff91519f431e886f9ebf -657500 61cdb241ff295b25fa6a478eaa78f111e8d7ada328853b0af54bb1b20a2a427a 482b2e9a549491f90026f8e50ca10016dcc78e4c3d2064e9f730b23ca9520a2f -658000 1c4498c323201e26bfb8a8955f29cdeb66cd43d6a2b2befb1da4a6c0647d1c53 931ef1f4868a3c5b54ef4354bfa791c3ffe15c02b3c704a6a281154e2f5be98f -658500 33dce694605303583aeadcaa80db0d8569ff712b588875d48edb395520a43981 6247bcba2c8883551a85e364e30b4104edb0318eee718e0317dc42f2a26c7451 -659000 339aa922137edb48aa37b841e956adee6c9222ae9bec106ed49ce5843b179681 ded7991d424229bf67cbf220dc2a5a5b223b571374f52d14bc9e83df72ea4753 -659500 38dddb9b6e5dad4ec1f95be3a83a156be12c5dd9d5e74a20bedee990b3f511fa 7815a077c5c8a265fd122b282139e3a13ef5951482f6d550a566ad74ec2db369 -660000 5562a936684fa4976fade44cd5eaf6531bcc844027c9ca01e33516c0c87be6e6 0af9d5b94d513c095d2883a381746ff79e47d5179cc95165708ad37dd0615764 -660500 de362a2665571bb51834a5e8cf65cc0b436097d1a640ccb9666fb41ee1694713 b7b39581644d06d7672965e189c645b4396f4d50b223eed99080a122b22c2f1b -661000 7df5c95f34efbe842ac26e4252440f4f315b342bd66e74a3d1bc3c48ca0f3844 0a4f81f5017d079725470dd800ffe7e955bd82df18b6e8abc325165537ead1f7 -661500 dfa40eda9296e76deebe46ab09b9d581445d20814c44c42090766c0015162e53 88b577c05b1a5f27b2aec225732da967a44e30dbb463455bc7ed223bfdc76025 -662000 7cd8f5daa828803f06d2ad8e7899d4993999d0ec37e8a37ec52555d1c64acd8b d0a6e4b8cc44620fbb80e061a949a8fcc371fd1f2a0b05138978d234a99fbc26 -662500 057c9dcdeb7375f51cdedc28740c881bf6ae644ff17c0aeb77ed796e89db8672 c749272ba9509a09bdb7697c6197f132c1de0c58de5130e8c3257288be94da8e -663000 d9ceb13692d03610ff6e97eeb643407840e27d32c389404cd3cdd14733756dcd 05b1659e97dd91ccffdf180d8da3a35f6b2fceb9676091bd997ad363210e2f5b -663500 cfe8d9435ad14423479546bd4d6d1e8dbdcd62a8214ab922402a86838a8fb3f0 cf68cef0e01bc5856468753c4df42bd16f3d33dd68783e012c1b012a3cfddc48 -664000 e18e31c640bf36f6cce981521fd55f42761fda24538dac34285fb02e69c427f2 f237c6c072f16f524d90aae138ec3a9176c2fa8f3049ac9ec009ecbb678e4f77 -664500 2cc31198ec6c3fe6e286f01d98f097e19a5c23d3f478916414e83f201e724e19 1805da29e7f7e8dbb2b5aff1e712b3a447106db48671120732111884e0783b5c -665000 4b332fdeb19f5d2fc8108c233679e861bd40df746262d5412b8a6800f50ec073 b2119ba9b25aa2a5921c7aeba1759395795989824a5d6d204592d0ab6ee8ca12 -665500 3f0705d552dc4294997339d7015a4897e55790353236540c775e330c78cbb34a 9595abcff6a155b8b995057dc725cffc3b283086ca65a6213368073f7f5d2b34 -666000 df535e0c312494f9f1a288cc54b72779ec7ba745bac09f7b952191c5a904c56a a545eb072527dc053c0630dbd820c51a2c3a22510f31a389abf75294dfb34911 -666500 ce6966c65ae25a88bac2a35c95d1943c482febdf7f9c28efb57eacf2dfb9544e 4d6fbf4b0b9c493ac96d63f97dee48afd60c2c847f9aba07110791514b0f4e21 -667000 e7a271b35d3fb008b6938cb618fc6f57032c92aa1e09fc50363cb181ca53e2cd 0f496a3a120f9644e6e3c5d371e6e01de4afc4a85f010306919bbef0aa323942 -667500 783bafc58044919edecb6e3938f0ac69dcc75bfc220bfd8717d419091bd680d2 b22cef79cae030286f2fd4b62c409c6d9a801f65e377d66d455fd814628d5ac0 -668000 beaea7bcbb6c4c3a18e0c9bcf6cee525f9036796157c8b4ce5748819c13c2967 a81cfb88c97c1489d9193801faacea720e98d21981856d121ffd5e75f7ab393b -668500 393c647b49312eece8839452c0874a2e82aff7169a3a7e1e5326b1993a5d1af8 212bf73b67feff4a971dde4a00c12b32fe82859167687a3cfeeb03a93ccdc14e -669000 f24c2d105f11f385c356455d460f8b74d466885118dc0e1ece8bddf624cd5246 d91bbe1649788ea71e0574f15865868289b28651ab7e28455d823a515492ce0a -669500 3dcf0b942af949fb37bdc61645d89efd6f72b13c02fac02a96ccf1375cf3cc21 81fdc3a3d66e72026b4bc01320881275584a05be5b0a5f8edbb2a6f334126024 -670000 e6d5cc2dd441d4b9f08b05a582c291a01927bd1a945f1a43557e3bc70cac59be c82d3be4f90e23836110348e66a9224cfe135ca4408363489f3296dcb8c33f2b -670500 c420986426267474054b56073135491ad4381376c64dbba0c57deab84ef61846 b0c138c7e5b8bf286b3f5b6ad0a83fafa7ba68d499fea78553241e741a05d183 -671000 d21e66d96e08adbb61bbdb75a7e8971ca9bd45a4906f3ce23dbd84c2e5e8d161 ba60c1936b7c35369e31e9fb6be2739cf60fc4685d210a209c4fbcf341d5c9f8 -671500 f7bb538d49e99ee06136105edfbd282e2f370d3f4f4c6d2f20b75938aca43040 9c1b787f1413f483e72003c0ca97831ef1e616b86fc3165423cc84e878d487b0 -672000 8c85db8531cb0e6bde769d488b6c6a639f4839a819abe23ccf88f3756caa6089 598752609771c022cecd036a0b8aab8caf8fa3e64724dc20815a827b750daaa1 -672500 efd3aacdf98aa1fc4fea20a2f4cdd9ea3eba6dbe03a63a149610d842793bc85e 93df0fed7bd2dfd8ca6293601d799ea9a54af7b0d45997c821e4a8a7ab7d1f9d -673000 3109a32670b3c1a796f9c6cdf5f3744848e8ac3ef0ee2ea891fac0eb69223ae2 baa8971d22821acd1fee4649f702edc70cf1b072517f4b69d6bf4060cefa34cc -673500 8064bdf0c36a535d5d7788f901ac0713b627e2f8b80c4b20d26cee0daf02ee6c 5548c9d616e98ed4fcccb300d3e35a78d66e61aa95c6465fc66a98c1e40405c2 -674000 b409ec86b27b1a828acc7f056dcece326a7892314cc5b0d6682d21c06d4e4cc5 a25e0ee6404f9db371913c15348e3aa8a9ad4b3cd99cca3fbf1e8f95b6e152dd -674500 0c8142e02a8e0cc1667a81f4c4d08ab7577102481f73d31b9d8c67589874e970 e615eda6aec462572a43acadcbde8bccd88e07fd0029bd953e04d7022dfeb355 -675000 f200a64f03ed78fdfb3a35be9133cc144cb7621be76f0a470a6cc451d31de7d6 2dec2d8e6cbe5d122786b9c571751d54ba1d597e23dd4aa03ebc50212c68cf8b -675500 44927533602536ec6857a62ddd2e7ca31a05c733cd0699a078c5106620da51f3 989564e602ccbd682fcf993e4ca7691f049bb6adcb099860f9577a83cbe436bf -676000 1349301af96fd291f3f6cac4d6a6a94779a2015ee9d63989d79c813e7bf3ec81 c196991fb4a511513fcdd4300dad73d556daf8eaaea1411a5c4b0d0382e96d45 -676500 7a7071dae50a8ee6f25b289f3e9d15d53661469e5379b56278f391381f2b5ce3 918295a1444f694e137f7f9653f87f1863884241462386fffd0037927c3779c1 -677000 a816938aabe21e8efc9c41ccbe0e7de2188e0bdb3635541e05b9cc8e61ed3dec d59c6134dc9539b3cc6aaff9870b30ba12676fadafe95167bf90bda3f074bdde -677500 d06ed31f2f1a7dee027e76fd419c93a2c80824f31e5b0bf09e85e10362cdfa8e 30baa2fa7e5834e442e8445c81d124018eec1ecaaeea695d4278263ae60ef134 -678000 356bc1b553016f0a17399fc531e9d5a86bb273ef944843e8aca16d16480f1e1c 74c26fdb3397f25f794bb15595b8807b7d4a4500ddc941e7461bb106a69daa62 -678500 e7f83fbb9fef902caa5ad499746100c3422842f793424bb2b17f9431b0a3b6ce 5177927957f3b258bec01be88d817c262ee5a64cee44e04b6d78b5f227e44442 -679000 1ced7af5a996a7028c63fe45238dda8c540295b48d082cc278614f68dae0e249 cbc8a6d5c9ec62bd0d50ddb90e7e1efc4b62dfef8d7aede6279ad95186497f7c -679500 a00fef7924aae620536c387899d8628d4eac6fb45bb1954447e2de6a4fdb2ab9 69b47a27d041a54b0be2406df7be07f3fbecfafc0d58407a7946bbfb0f65cec9 -680000 76831117aae716df313e1e7af8c4c8076e2b7d37bd7239c827962cf903afdb55 0ba660526d75f5b1765967a87119f6bb67d33a496e23b13e58335e960610b38e -680500 17835aef913aa41dfe7a49e91fa7bdd85411356233f5cdda375771706b5a4e5a b88eeb3ef96d4ce4adf49b87f88a5c835bdf4ff88aa3a45bc46d2970a14533fd -681000 86ca3bca8de152e4ddd4ac3171ed463466dc040afc5e2f38eafb7fd0ce49dbdf 55a9a5b5ed90ef00ce658b5fe52373ec23b37e7ae1c477decf0e8a41326cad7f -681500 5b31112aa2d9b190844d109c44f8a4845bcb0f75e567055bc1368bfbae9bd427 9b695ac5b41310d05f09d0e5265f53b4ff475b10d2b0e27928d81543857a1f0b -682000 0f036f94ee9dccdbb0ccfd4dc10663890af3c2b7da67321baf4919f8da0ef388 a9d70e8df288e875c0361d7273ff846b54dbdae0d6d6459831e71ea4a41397fa -682500 18658069c688414684b22ffe62a7e4d9b84b3f27c28351b57c8c5763aee40ac8 c4ec9845b905ddf71c374d400faeaa649ba8b08751f0a5c6b9780d4c7d497fee -683000 ab2a4002ccfc546d80417f9c1c66dca34d8de7df714fbcd4eee134659c6b4261 5bccf1dbe0d677d06768a02a5bb6fadf5deb0075582a97e4524e2128a4fa4363 -683500 5b302ac27ba940456860fa752bdeb27a3c8494c1fec08578c6d204588ae18420 ae3de94a6481c28aca678f115b73c830ecbd163fd2e11a9d85b2c3132911c3cd -684000 15fc8d38546017ea2ae0e0b4387d74bf702a396b52cccfa879bec7c415a164b0 9a6e35b63f814b6837bf67d897103f320a25e5cb15dee8e5524d9961f53368d8 -684500 e40472171e3915e9518f1646a3ca09a46154b226443848605a4d8c78803c90d3 2c7e33f27973f6345dac95862d63006b4b1506d5979f60d8c52fec12b74a1b78 -685000 742e161c4d772ed9ab9b2aa95ab7dd4646e7fa71a7b71d0062120791fff3d538 7854ab499956e6893c2679a3393fb30e450f2cda76cfbf08bb3e77b586b10599 -685500 697224d799e123de9da2b93aaf6a3f00ddd507080eca2357c7cde1ed1ae8f189 1b02e1bbb85f1e71e1a1bd1e58e4eca588997cddc1f545ee293b17267fe5fa50 -686000 7a7fffd9aa90d0d9e7309ccc0e450c7544dde058085bf4bfc9efde0cf8fc7b3c fd10b3c2c0539bc586cda1dbdc454a1597f4acbfc1d9e7e7b472e2d3547c76a3 -686500 3dc10029047449d4411fbefe15a7f25864007511102972f14697dadfb914d5d0 8064a285a9ebb460f864525434c5bfd94ea7c437f67c9eb6268c3f3e4737b798 -687000 2e2c774dfd40cd18616a82d3e5769d4f447a2eb5214bd8783a5084cb8ab38e20 52379664d91e53a60d1b1a4d64ae2005e6549972c45af11ef2ecf2f2faf82ba3 -687500 295e12eaca70c7eaafb7cd25efb6b461f5aca68665832ab9eb652e6fe476d809 43763991b8beebed72f3b7215ee72a2f074daa83a27c8db1decca52bbfca7b15 -688000 88efc791202d8e4a0266dc8114487847252ff2497c022ff4ac237aabc6602406 560346aa44e4afaf2fa9a4e1506534bce8c0e113efe4b19c6aa26804b405bb11 -688500 8bde3d0d7f23d76ffb10e59c43a9a2cd4121c3f5033204c4689fe77b860d616e fbc4d97609351dc9fcc8f4e08b5a0c79624c9e81989b684e219245878ec2fed1 -689000 01a706323f362664abca40cfecb4c6efa65aece3270fb1240e238f1e93ea3ca1 e4672adb018af124ae848405442ca5e255ff9af3909d258bba12d29f3aecfae8 -689500 3d25b5834362be1296b92448e3d2ece79f8017708479f56d7e28d602817c82f8 643b9f9b0a754b768ff504c9941c627627b49aecbe170a72590179536840b843 -690000 0e622f16da74d548cc9e49c20d072a9a8a6bf45dfd793830fd25369adca29bc9 fcc1d77406d58f3e1e5630871011b389449597e41f1df035518c1e25affcdc9c -690500 d96ee19654c250c20011f56dff3850e61b9b01a8c3be009b93c0f53c79d6ad5e d3b6058792062983ed59720fa58ca7cafc890e475e2411a01331a4e3e8ddc580 -691000 0e02a80970060ff139ed4ce0a83bf5221895d80de69da89bccfd720da52793a0 20279d4dcc8aaf7a83a59d70cbfdc4c51e8d034467a956cf012349dc01d875ea -691500 6bbc975ee40102521ac8b041e481797c83174c5f2b5fceaf3090895a6301f42a 4ba322db9723202338d5c0e46427fdcf24c8631f53f3db590489cf5cd74311bf -692000 a36c0ce45bdbfbcd02fe25ec7c199be6e01f6edd8e5095dd745b136e1a1956ed 65fb3e0023b45c838637825b0e95f461b02f90134e875d85ca8f084bd30d3eda -692500 2f8577c57b15cf8c176873a546e1451b379f4e09967643452a37b037b538a0e6 b15ca73e362e6394166b6e104ac474d1f73d4fe671117a77ad3f9786ee35488d -693000 634e96cae2b7253783b3ba6dc65bbf79ad87782a46f07a11ca8c3b2325e2d2aa 08db37defef7bf06dd75f2d8e4f8d1be0f2004d24e816a71ffa4fee43fb5153d -693500 c472b7da4a1d6e9a9728e58dbabfdea31af58c18a17e79e3dcade6d96efdb689 021ef6717375d52d4e02c36bd8757c6c73b77c97bf3bb4d6292cec23afc3c8ec -694000 8d5000ca461da1bf1687fc3ee92e3a1b414a92737d82e301895d6cf41e0e4cf9 e2e6ad6d2a58ee8538e7dd8136587a612c39ac281fc3e6bf609b1c497d9e331e -694500 daf014e18bd15e7a19ac859acd668aa28bae8fac71079e0b8285c25fd28a46d4 9a671a25ba774c600b2f967a1632561ab4ebbfc4b4016979aa9288af8be93065 -695000 f0d64ffc15600b2a53e5b9f09f1a0f981273e1cff39f01bb69a3c27fbe679c71 d5adc8baacd5fc0635fe0ac739a16893fe0c4215655ba111f49e3c709f0d1faa -695500 d784ac30db59c0e5e8906f2211b6405356158cf57af758b047445926e8dc140d 7d0c9248ce3387940358e82c01b7accebe7d3445fe97f6569b0a99a1a4822b61 -696000 16e6034f4089c38e9eb2a11669e4d5b896b4e36e767626bb4c2cb852031099ae 5f54a918561ebc4c21c27b793cee698c347e8dbfa49ce72f4580ad7d3e464a91 -696500 bde4528da57c22025db1123e7fdf3e58f020015b1b500be5d2ea13be8f4f50fd 954600e88d55d507e82333a0b9b36f5bfd5da128e5dfe721ea486a117f196e51 -697000 eea7b9418887e6bfe3a460b03f30f800672d8df94217fab7d1e7a74f437ebd50 a210a2e4efac6617e3df43fd4219eee8e4a9dbf05e4cf103cdc9f39e162d61dd -697500 af96502823fad0e9693d94bc707b04d59d3f42fb27a12134f1aa0a863ca616cd 8cc57e73164f446606d37223429ba5a37d92d1ab52265fef43c81d8f5d9756ff -698000 8a0878bcd828268633df687a5405b2b86051640a122f616231d8d6146d4c2ab2 27a9f143cdcb85bc01f31868f92a964337c451cd1a546f93c29361f245aff07c -698500 afbb603de0da6476915e14cf182c6c785ec6514b17d9ba7bfa74e5a228f6d8e6 f730e6ed2ef1334071ce63f9ac851de557383c98b40a72f8bdfb29c49bb7d571 -699000 4e3bcab244d1ec2528890ed24340027a9add680ccac038c42e9a5b4880368a57 1b7062e806e70df560b7dd19713440125dbf814412ff713c5bafc8776c443a60 -699500 69c03ffa655f439caaa38a36031f45c27f6afa345fd8d380064ac4106a47b9d6 9835287f527b8d7075cb42cd361e6048b9defe40cd855bf186641ac16a40cfa2 -700000 19c87f86c5d859f1d4ba642097f626a5c6cc8420f1b438ef0ddfc52d77b5a7ce e7cef1ed642d40f49563c66d9428c699a66241a86d05aba5cb6fc6d6218317a6 -700500 c22be0aa764d1e0d90432e726ecb95a769d691a7de81ea480c1bb9e74f43bd8b b0c38cfcda8312393e4906e1068c7a323defc33624e99c8c8f918771010a417f -701000 b2505b0ce33e22fc06044bc95bcf1bcea363d91c541451ba7ebbb07079c9b8e6 36066185fdc8a919096d36245786b921b24ea4b9ad0949d3685c7d54fd3faeed -701500 11c69ac149f239f122c309f5c7c8c08ae9ed95e563e6e5ebc0db4d49628972d2 52282de896ddb2f1cc56c22ec74637395d1c2ff49508e903cf4ef1f5c01a1da1 -702000 73e7769b7982c2e9be15c6d3b0156680f7705c802452205d64a5d66187de5008 623290f47a7ec8b202b95f45d5c6408072766e49439c1aed29f023bd79a8e1d0 -702500 cd7f69f08cba82026873f72e8709cffc89a4bfe3c5300231a180fe4e7335e87a 4f1bd226f6b1bc4313e7618f03e4522da41509937f596a3728da2310deecf49c -703000 6253ae1e6bcfdba8257a18760dbd8f42bdfedce3257b9cff76660667e29e5e20 05134bea7f58be79fbc3942bff929fef977a42b5bce28e787bdf2bbc1bc70764 -703500 affc08445fc42e60d11152790408c66118b2a815647640a3eabc3006e0f58f8f 34c74888ee86d1759127612373b099f56c53bdba1b0fbabb0a7ec61eb0f24ef7 -704000 5298b2ba05735ba586e9f6aeaad350fe88b762d00c4551d6b02f6c0b706b0f34 9a36354d1266eb50f84338359401e91aad336d97cbfc39d574a83fbb4aa11d67 -704500 f674bfadd8d412cffe1c8d6fedeb91e9c8914c3280414896f97e1c08e05b53b5 6e593d4f49588dc6a68b5adbf870674cd17037cf7431f34253eb6cde06364421 -705000 d288536328fe3b3301de1ba97c0237dcd740f225f4df07e923bb570f68716604 b918a47fe346fbb9958ebff0e557b9febde26c435ff6320858bdeaa09ed0eb60 -705500 bffd8b226418632ef3a9f71f473093e5592f446776db14fec222f85de068c840 e889bcd01a761d5208221642a51bb1d0afb1f324f74914590242204164287740 -706000 2547d907a333fdebec0140593814d90a1d806ee539598cf0672cc30a1d5c31d6 77323ead475140b2224eb35de6da439d3832a091f1ca17e53a885d0b4d469105 -706500 5625e44c5204f1d9d3cb4b5b55aaa18f13be66ec9f76988159a172713f141fa2 31a50d4821509dd711e9a541a3c54e28aad4bd6c6314526ba82e64857f52f4aa -707000 e15531acfd422b5932479ecfe5dbec51af4e824298c73658bd43c143958a70b6 e9af02a4dbfa950c0a45fe96162bf991f65df101072db521b4631ba7e64ad248 -707500 904129b3e99e06b3a75bb2b903b65b1176d82601355b13c92dfd2551edeea6e3 4e5bdefe9ac9916fa5ba321a6056ec1bc8fa32ce3370587f13bed12c32976b71 -708000 23cd48d83d0bc7e5b80c8a337389801ef9bd5584097667310342d92beafbabe7 e916d2f42c77692bf97058ded798c541ce883f69786596ad94a22108adc17694 -708500 2f58264be757741e695394b348381a9ae8fd583341791a84d68d338cd811ae39 dafed9faf74c750eedfc2e65491b75d4bae7d13b9e082e6fa91376c2d6034da9 -709000 e55588bd39fc8e754f2b272f80ac86b5515bad37eeeac6fc3dc0d1179fd53423 69815269b65b334aa89cfca70ebf71dce7de046cc84b68f0f9c462da718cc469 -709500 e30d4db49a196e4ae4502c992118f37ddd6da696f296413500ce20b4b9838497 4cdf69b6c9515176894db3bb5ead92d5ea1772d53717224656242e8007552228 -710000 6f141473cc79d5def23f888471ff143ab546b5b1d1d5fd1fe51c996674e3018d 5af180a3caf0ca42e0ba20e959495120693f273201de65aec15993cca37cbd2b -710500 10d11c0d1dc7316a7bc8a99b685c0b12c9e2bbec941d3c33781059c7048ab022 541f760b8b3ed77398d5b5193220799c84f36e5cf342256921661f6d6fee0316 -711000 dd068ba9611f623d9e761f5e6a10b0298130c8b25317f047b6a4e79a3360909e 920987e93062ef5eebcfeb0a98ff5b108649f1a092f76cad1c7d09b276469f80 -711500 96778f4ce3094a1c3323e3afd658b20cff90b2aa7f23d886a5f5629704f5726d 9f4d8c3657fbcdf2375c92f6f7e700f8f108a1a5df22468685782c897b15865a -712000 f4414c743e2b4f89177f92e0e11d61e9f3b1669d3ddd6148b3915862dd2b87b0 df705fe65a056478cc8c914ead67c0a9b6023fcecb68dc7d9ec56a8c6ea1b865 -712500 fba950fc02bb67da1c4de9b6805b7bcfc0cf7e2bfff478568be99a70596267ac dc357d74f8f524808f3f41d6604d74a8a96c6bb87f695a15ad835abcc6669be0 -713000 ff4dd851417240d00e594ee5fb5408372e4fd5585bb5ebf3d73a97dce1f4c41f b54673e8a2bd6d75e2218fecd8d20c0bff1b231b80fedc53b3f1deefc7fe4747 -713500 92e49d6caa2cdfde8ec7d8c37ae12d995b9552c76f7c7ba0abacb77b02bdb5c8 4c7b0f7d4f28c7c4d35a29c0a74310b38789decd628308c72a5a270a66ae55ba -714000 dc8dfa5b910afe73d3558be9d077fa57f1b6ac42e058227cd73b1b1cc0c70231 9ccbffeff96630cd9248b3001d7ec7ccc83c9daa5351bafbdefd8a88c03f3224 -714500 e172274b228f5e4f49167f7d36076f71db89acf666b9e519da3a33c548515826 14e35bb2ffc296d0d1f30be89e8a66f0bc7ade63250bd68043acf98dc625c91e -715000 a9b83db90d65b2e1db885b5b708f1d7203019a7073ca3e5310ed4dfe19bb9d61 1e2fea7d862a4b98f558f07e35d23b1d229dcbe2047a58f7bcec840147dae863 -715500 969fa24302ef22b2bea25b3f981fbb756f3de84f841d6f73ad9d6a6bbf463fc0 31872cd93e38c92acd7b1af2ca83b7ddbc9319dd8606725fe0aa2b50026d98aa -716000 e33babb3b3269852ab03a5044a595312e1828dc11169020fa2a05f4ab329ac15 129a208db82ccf3418d94c00f39f3eb81bb7ebbe901f2a698362be4fa1f6e7cc -716500 9c0cd626f57ca90c771b00015658c387466c2f3d462d36d9fd3622abec903b1b 044c3a4459440fa9078eb26f15d114c6ef9d63bc5b8640f84289a1f376b4b85c -717000 77a31d517bfcc769f64d0de88617d62d4d433c1d1a3136962eb07baa5f227a86 e1f060643884a9ede876b52b38690ccca9c9d94140470024d2f825f4307dc918 -717500 546d0c517b9b0c5910d4d7337c366d76c7d99be4b875f673cf3876ca5458cddb 814a3c25d78419214f5645a68ca361b0199b58ba3fd3109817b585cde74503d1 -718000 7e44714aea5af5ac9195904d29c9d53d03fca15e00e0f2c1a071611b6fd03011 38d5d155e5a9992a6e9c1423f0ee621f19173c533e6954a46258e02982b89a02 -718500 dabb2702316c8e8043539190a1581ecb881dfdb7502a517fa183815a012eb344 268c57e30e191d41a2793ad6b70796829bfe2726aacb3864283e82e384eea0df -719000 9db785b29f04f274688856f0858c7c63961a6aec5788a94bc1aeaf483dcbbfa7 8addd23f1cf6b051fc6bcd5558893366fa7a54ed89deba74d79f7a307c5224bc -719500 4615a7726a6b3b00fe5a9cc53fc916af6402871508fdc9b9f6e5799083edf0db 3d3702be96cdabe826e24dd724ecfc426024a693c161889d0b41275cd6130d19 -720000 6b70419e1023a8dd272910d32c30aa0617bef67234063aa6e7447aae5356fe34 55f7d559d3733e4d3d6b5c3c68265e088eeb6d2892671e88e9567f238268925c -720500 473da49304fdf70d4b5adadf6fcab3f0c332ab5ffe82972dffac6b14aa20f23c 3de3c3ceb92f8a7f45fc19ccf72f79f2fb8d3bc61654c534f81df978e905a3a5 -721000 c293a009462b561ea37ba8614559acaa63cb6291673c68082a6e4691ab0eea86 ea34bdfab3e2a7087605df85d858866b54b4ab1acd86619e99f6283a99f7ad67 -721500 a15ef2603cf7a7b0ebec81fe4abbc6035183755a08fa11604e40c95477d61812 6aeba98a3c5083b997eca56cd003e7f0285963bcb8502f73f2994dc04492c35d -722000 39271600011dc5e938c1308fc8f467fa44145f8bbc5335f24719d125dc92f664 bb0387e362d72388584708287f86c92ae50f7ba4330c9857b308837d150906fa -722500 d7f846f9e439702e48044fe02c689990aa0a56613fced844d989816e0317be80 f9308f9c0bb63c44b443473a8a25777e34d9a0e903edcd33598b270f0d7e9036 -723000 6fafd8c865b3d0bb05f18cac70fb93007cff223789fb46958b55a205ffbbc959 cdc9d13b0b9a5fa827d2572e9c3232f498e8b06ed8627199c61db9525469fcdf -723500 6ed55084a271a39809b6f3455a08d082fb7c56ad97427307ec207135c7c16ef3 cd4a3d7e1dc9e293cecbcf14b969480c0c2f277819e9eb2286d1761df7320694 -724000 c1b649d3101d61bfe8b949f443e1035a3d5944310f83e94785592c4cc91552c7 452655726058f019fcf400a89e464688ba4bd0fcf267493e54748b146c7dbe1a -724500 21f5f4bc2fbfbfff183a3eaa110c1e3f826eae2f58d32242919026a8d1ea6206 d15908ddef7626667600c5eedca9119d82e0da5f4cf56bf6616edce895b38d9f -725000 5db006a94bfe731764372f332c2b23f9863f7741c0aacc4d92769f353cb4a4d3 db57165deffffe98c3cfe7b95e119d0253a6e984d11fc2b1894ba4bb3010301b -725500 f313538888a7b2cbf72adfff7c6aac1583c44b477c27810920835e1f36104ec8 c811a4d09b2afb0e9e70bc9416e58aa2c3dfa4955ec4ecf03b3db9b65450e858 -726000 f9f289b08641492431e4ff87acb944092bb1fd4ae405569e0f3f14e433aecc79 5c10e47957ac47afc2bd4fc6daa0c7e30f127f0ebdeb1b52149756d9f996eb76 -726500 769de3f5c47b72bb76aabcd88f8c84595015f6f3f8d78b4d4a0df2be171faf31 12f1f3f363f1cfe762d972b988ba7e0943520065bcafadfeda1cd73aad8c2aec -727000 2d757e0b21cd7f64dc962c5ef6a7268d0e0223814f74e6fff9c81f849e496ded 3ef2c4f48504f065f4efc06814674b635ff6d31e9b667f9b1ad864819804f446 -727500 5b2875cc1b107110464a44d7d9a1835e8c19246cc4d646402fd3bfacd53b7201 48695a64b57a8523e285989dc5bca5360df44847a66d926c154c6929e92608a3 -728000 35fb3c9e4fb0a40ebced7b7d2e9bae928790bac78a8460c311b99e70cb109c9b 758fc72831974d7f37e9307b34f80de04f3ceebebfc97c79eae5e1dabcf2374d -728500 156a06f3bbea42cebe61c148aa7ac4cdfebf95edde5d021c03a90ddaabffd20d 6b170063e91dfa3d05c9d6edf71577d85a9e3f0ef734b7376f757d1bd5a42705 -729000 e8771ec45982e5e9928539d0f4f398b3a35f02b92f44ff6937e6a6a50fdf4100 bba9a535cc36db2ca8af73b8707635e3c12b3125b320df91257a944ea3a6af8d -729500 e17e17e50ead400f5dcb3f3ffec5a1ff95da211a7f6d30f87399cb034b2fed00 0263cf2e76899d4424125c726396ca7c8c3f1830eef290b084bc67aa3dff7ea3 -730000 06ee01124cc2d7e6ef4f764638700ae11ca26a457317564df6e5e7f0d881ba4c f20e5e74a5a07e05fbea7bdbc73ad393bc83a144a7e15d03a096f052d7065eff -730500 2692d795f114318940b89b8aba8a910b6360170048ac824590c5d814f8b01973 9aad48ed4e603ebd7c79c8535c24ec7d2ddf7db6eed92b9d1e83846e9e139a1e -731000 e167080479d38ecc4cbcd16e4fae05c1f87e09d33e4947b6a9813ca63e147d5d ae82cde68df2aab3ef79112d4080a285b806bed3e457aa4215c6ee35a6d73e33 -731500 d8c7e6903152f5f559f108449eead76f647a5c9991f2815eef0d0058c25b6bb0 f786151a72adafd6930fe59a04cad481a49770c191a3f5444eb9b4d49b000779 -732000 7371a17e1393bde477a0beb136f98e89dd30f49ebb28cf59a265dea0f82deb70 67d98bd80facaa69bcac4ddff46661d1dced445c622bc90bbdbe1e7de9a8f768 -732500 921701199569749e2d13f7940e6347ded7a3f1dfee26b7f7bb744d5d3db586dc 41fd3e2f31c4d732326d13c5f31cd850e864c43f1f179d8631ec1aa69c506d88 -733000 d452ca29f9949b714f175c7ca45841a6519857541c44df4e52caa73b4c9b347a 616e3b11378287c338d03dc5e2395c5500915fff6340d6fb48c0123e33f92d51 -733500 4ecb0e1b2273ed4df5bb7db47988c3271e81cb9933d7cf50120e9730db47c82a 6dbe9a6615825d26d58bc5a2c068e9068dc5b4a1402dda75c43ad3810cc55a80 -734000 6ef7723b332f6d1a4791f14a1cf2811870cbb08c2484ece5cededa3f69fb920e de8e532d9596a92249adbea9833ff2022f96bdd3f82b7c734fc3580b4b3cc946 -734500 01d19d29a83d79e38c274b76943e9d5769932a6a7812e3f297620a40a0bc922c ff43eec3f821cef199133f7c5282c9892c1b1546a77f6fac3e9021037481fdb0 -735000 544a5f6ce7a71e13db7335cd2a4e02fb7b5ff98253016f9d7f26956dec908470 662695548e437e31e7687cd4aa3a463d2dbd1b0579df23c6f5daa7e9b3788e66 -735500 997d9b45e87e6f1f1b76c7c212527bef213f348c51d806200bf6541da07b76d1 68e5ed2790eb489379491eeb583227ffaa09afd5b62b9073117e540505058b8d -736000 b371ea1a60567133d86757ae1b12faa8832166726b9c2eb67a643e6878b0f64c f5308b0f2fe00d7b1e1bde602e6028ba5f2ce8849da22ecf2cc07edb069a540a -736500 ce6bfc2ae42b6e0893e4abf6edeab04ee36cae259415004f71811cac250e2abf cf5273f67e35b1bea345758b059f5b4b05ad705469c64e85cd90f392f03db171 -737000 79e359fb34759ed805e4ba17b22b3f64f4e05bff59b0929d5a996038e3e2684a 06fd8eed2bedf16f590dbe5210c4657f8f14142fbd12b823b4972a4062c46476 -737500 3d69d33e4b40ef18a677394e025c74f1ff03807f1cc1a9924301da4af97d40b9 8d5cdd08a8a4db368da7ab6be4a68085fc9b2a156fc5e89b69ed661267bd9d05 -738000 de67c044daf5e82856c70c57c05e0963d2767f721c9a2a3095052d271ff77a21 3f6cace03de90c0a7093e549aaa5862b4d0d4304d20e548c1b77a7022a39722d -738500 9857746dacb79d61819a9a7bed47d4f3f8a8ef2f0a4241e4a26e84eecc388178 b324b1e1ec98f23aad98bd643e12396cb0e6db5b6679f5f197b8c82a74912869 -739000 e760e2ba3fbf67764d9ebb7a9b5684b71d079174bbabdf7de315b7814e6a6d74 74cb6e148688d11254c235898692018c699071730431d7e9f7438c6859e1b140 -739500 f066444b8192b7bb857f79443308595802f67e277d85efca22432c5dd095ca02 91fdef383bf939a8e230f32a00ad0c58452c3bb0847a257a136297dcfd476a6e -740000 8d11e7b07aad1f84d0976806645f5d508acb6aa563e1905bdbfd49f88a83f561 d1fa7be0afdec09bdc631fb8d5a35bdf26f47b479aeee287cee3557ddcc412e2 -740500 54b44786a4b53f25a1ff7dcbe85ba288f6108cafb0abaf193c6fa9fd1bbec690 511fae7de79f3e6aed0645375673168bba00a2d39563ea2596e09e3a0e609840 -741000 6e98421219a255828fe8067f68097ce9d08c9f33886b8a29a22d2ebe6ba1f3e0 ad33286ebbf08385412b7a732c551354dead015e466163e74e7fb5f94f6b1cda -741500 81eb9f3b0f352e0ed1c5935647d526ac71e0b775d8715732e262f50ab6a55963 fa8c84206d369ea634fb6668aff771d4c9d3ca7e687a6f2aabf1b2c80563b955 -742000 540e29303471cd64e05ae80fbd19847c61476ca202848595583e1432e45b6a12 01c47d0edde8e38dbef982a21b7b95e6049dfd3ecdb75763b3ade1cb8b804ac5 -742500 6bdd578f687b5b04d2492b7bebe989d618b7d55802b977c9f1362c022d37b5e0 abaccce8aa24b8424fe18df7490c67e36999e1f44dbcc68ad557c59717da560f -743000 1a56cced54e09d3e03f267054909c5800b30e571a81e21cb8e1960c32fb615ce fceaa34349bdb34a4bd0125a9d5a0d73ac8eabd0da333a665f71613075268854 -743500 2b102f1ce482314a2ffc09c26320f241ed197ef0ad1b0b1b05884d95e98b4832 0d514c31a22d865f9480fb408373139aeb312d750df0441dbba91f6dd74b7c34 -744000 9eb6d3d3bb45887dccff04f8555b7b6ee5c16af80cfc8fd132f2f5d64ef32d85 18c336ab05bde704336b82417e0f8a33d6d70df4bcf3fd3277dbdbac7d285313 -744500 2c894cc985ba39b9d41d6cdffd9225d1137285bb2a9faa355fc04e1c3a503783 fafb7464d1745969dd5edbe08aa6400acd05dcfaaf6d09a135b206eadb2d7a5b -745000 0d3d86df05886717a850b573d540f01159dc4aeb9715260e19da107d8a5768d3 273a426515f6fbbc4d1f505ac48c2be61e47dfddeef2e0725d1d287da3706876 -745500 b614d96445616a551d2ef219bec80a8b104035ae75230819c08c1bb5d40d3eb3 e8a90e0d452a4db19b7703651fd04988b45763240ec6e769e681cff12a9713c4 -746000 32fd2569cffbaa373077a1d958628f5bb59edb4f1123ea22d827e59b58e6128d f0023c390d625e1286ba9aecfc80f28d96109289f7c438379a75c7b08c915f24 -746500 51f9b04af9044618552cc030e88269c4c8b6f6285653003ea31fa0596b3be8ca 21e1a38a259322e17a4fcfc9d45cbfb75c345d2475f7081373a9e8b791e3d906 -747000 ea7dec43ccd90255b703203200c0b71d3aa7332a2bb43549c5b713bb03b77f9c 9cf126abdc8e883dd428ae846e7fa5d694e87f40d1de07f772f916de45db3de2 -747500 1b651b29875be11fbb4fa8ed4c857b030122b7facdc75ec31ddaed88e3623566 66c676aae65eae30d876db4035a19e8e00bdf9a9331361e72f57af17a3da4dcc -748000 55f61b3e6a5434428b1a062ee86523b68f5459e7615c29d83f01eee310ec66bb 4927588d5f0600d0a418298312581aab6d41144ee3bb87a6875d7b11c676704d -748500 cc910d9ef1a087c0c9aadfb77da9051aed5124b7d072b976f4d34dc74f842f14 f1b10cb29bf15f5280b2506a480c07a610de4dd63212ac5fb1a33894c2fc0353 -749000 70c48f09a23f35a244e22e7d43f245a20d1d171bd3958ffe261363536f92a087 5cf7c04ef74572576b5debed4c20f3446db017a0360142b325a330909c904b09 -749500 33d54681aff8149655455f3331792f7a4582c0f0a436b9d3ec0fced7a525ecb6 382f51b24f05dcc78ee7b0e02e1389d1247a30489fbc317e6588238d78cbe478 -750000 8e0b562cbf9f5d9e0539f9964745265261cce019e73e22cd0db86f0dc7049110 03a1b08260d16527973210066d867267be1f3d4692f3bc680afadd2b1653f995 -750500 a85d11029aa82c4dfcad63d3e6e32c4525f9d192fe8ed223ab9f05a3fc4a5d11 1e1aaa3b0c05e04b991026c5a9b6a56228b007a6f936902f7a80f1b8f48eacf7 -751000 bc48dc5090db1a9a8016b89fcef45999f9d6c87c8982dc4ed52e4b583ac2f7bf 94ffd27371d8ad63511d87f728731b0513ca8d8b948d8b777d852ea9aab4804e -751500 c45fd98831ad0acd126e9fc658da6851a2a14a1cb037ffa596da1f2da2fc47cb 82be3962eb66aa5c0fbbababddc65c99ac5c70b372b32aff94aa47392ce6b802 -752000 373e8654d6a04c16dc7ef938fa6db6abc8672283a0f027cc34eecb1ec872ab7d bc163b7e20ee438640c02e74d48ecd1f65a4bd4b16d21248663a48e63eb02616 -752500 5f217d14da39d80fabcaa06ee56ddb41ee0dfef892576c2e100793f03818145d 91a33cc31ca938ce0b222ee141bb4edc500263a0689d0aed50660f8e4581a960 -753000 3e4aa8b1ce5cd84238df7ad4558f411a41a674ebee9fbe087bb41e880936a7c5 7b8530bc78bb832d51460962af3cca2f534cfdc28760d7f5363534e68a72ec9b -753500 23a5236d81db31cd3e174f58fc2f9c1263365c35dcde4a20f315cdb01fc29d65 042dfcbd5f30011ff7476e398e4c4b90f890a9fa4eac0da6b809410c3a9cbba2 -754000 5b4879ebfac928244d38117df31bb10c9d7c9e8e8d2a35c5c2f8a230b4593434 c57c3095308f688759285e35312da7e6da208cba0f9db64180d551affaf107ab -754500 96cc5bb1028f5ad1cd8a33800d9832d85700d037d5746d6cb4e58c1eadc8b119 df2a0abff85d391ea42eda8fb0a1d7a750eefe9d5fe25efa10a9f46fb6110f8b -755000 e7129e48fecdac55aa3944a4bbd19eb16f0d8a73cfadd44a79d641aaa46dfbde 385cb4dea3040a9b4d475877dd9d3cb61e23091f492fc5ad741a5cad2268c6a8 -755500 93174ce679911cf73dee7fb12bc26b02889deb145dbc92d69637a85407812272 5f000b1a76187f1c309f9495dbdabd5001f69bee3f9498316d0277383d861388 -756000 d2cad51c4c7f604a86bd42e5fa0855488394561fd8b8e403c968676dcecf2f9a d24b9c50230b5c1aac5e5937e488ef65f19cc11fd4cb6b97497cea46061d7e44 -756500 2e24a5dff5e90a2bddd7343297d9e1cc5f1e8555a19606314e46c09962ead770 dcd2285a17c2b37a17fa6cd27899af70be173d7a3d5c28c7f3ba6cf4d835c716 -757000 d11e6ed1c335b9cbb3db5e79e9ac728fe2377ec42de299a318dcf31ffc545ae5 748036b1271dd158b39d7de65e91a95fc4e51fc0e9eb3445cf7306f15c0974e7 -757500 0b5f20e382095632dec99c72f66fa419e1ce638a80671b8ba91b9a6d24f51e29 d6181cc28a4fd461f6de97bb298ef188941d1765a5bf650e95d418fa8b7fbd4c -758000 5a2a205c4c51fd035a4f57e79f2d92ca5e3c9af3c8c2beba21a442fb02b2c705 e019ca24e6b67025cf564537c25fc2e6e241b44730988c316eb32aa8afbb6804 -758500 e33c965b4ebb8b924a1fb73c65017199c806b762d4441854b79661f4de03b427 313706df2d3cde7074b2f6849c1f134ede50bb46a297da3884d21a1828ce8072 -759000 31928e69c1bdd6c727eda5662bce3f72e36496d538d9fc1cff1424bfcc24d0b8 98b76d0e9682ac933b75419da77ebdf7ba10f016d35d26638915a5ba5be4db94 -759500 2d322b637e8d92f51372101bf714ba726396d413b0a8e9ba573018ee1023b0c1 caea6763d02b49152bce73655908d1bf489b2918b8514982a2fbfcb1099011e9 -760000 1cd9bc900f95c2e15a802f7eceb33ff51dd12a71718cb4220e466bfaa0f5ffaa 0243b603adce50f296920262a13469d2ac1d0c42c2ecd633feaabea80a4c6100 -760500 4de4cae653ec7611cf7079c4deecd470afc39ac6a083a7b5ebfacd9d789c4394 d3a390c8ac0a632c7565327db3e9a4fcc30aacc43e2ba57377a1477235124baf -761000 6aee8513d50a19fdaf21e0ad49ffd92cea289ed0fae844cb3afa16ad3e60b934 045c6ba4c62d4ae995dced0633d85b8e120542be2533abd9fd1fc8c651f47563 -761500 b1917f5b3a3f1acd43c09e2d975abdf63f4a2c6d0b8ab429b47f467020e5b31f c7f69fc7d9f169a97f9ce25956c25668cb780205eb59dbee76f592718d74503c -762000 5f11eb707b887cdd88dfd5f98203a949824d1fe960c4c85525995a377a39a79d 6a3963332b853b978afeaf71fdf868b0d36ab203773c958a5fe5a427013ad02d -762500 8c3d3c496b6ab6a1e56cd5fceb131d8a9dd8c4fdc938d15e6ed090dab25889c2 e6eb9f858bb451d57926036c80c3c7ac4617b7897b19f67e2cb1952ecab6a24b -763000 6fcef4afba243507e7d54aeeeba6cc7de011b43df9d90f364794e3c59621b980 47461602514b2ae53177fa064e5abfc46da728227988a9388120901fb2dc9a94 -763500 41ed18026f39928e570601d40419b18758312017a7c9568d73d12d4b828a121f c04c199a5b9d12441ed489dcdff90453791925fa29ab6eb6c62b0c4d648e28b8 -764000 67e928458125fe2e3c6970092328b48497a4d26c6b04b01e53cac4de70fea64b 9270bc1fbd0aeda1572f2c2ef56dc700086652533d70be2fc6d13e5bde70f8e3 -764500 015f8999e9b59d173970ac6f7b5b6b460879a56fb254c55fc64c79c2f1ceb2af 0fb0da763fc466bcda98bdb2d28195935e5ed9c8d35fdc877160aacf553a4a3e -765000 9e706cdbb0b6dd01e5fed36ab646fc0a80a850e08f2088de2136388d4db8a219 f307dd0ce42f0f743054ed8236b6e8c44e4370634d9382ba439ef593210f14ca -765500 76b996f89bf12e2d725e1df6b6e1f9fb71a0e4741add4657f8233fa6b1a9cc0d 1c1d390e6e339f40129dd63bf89b9dd34574b6c0e16739449ed1936b023f73a3 -766000 46b8674f0faf71bdc7bf0a656e0e02660d90388ec7c3df894b0b3562d8541ba3 ed993dfee8eda538ad156e46f49e73c96e6abeb40c4e2ce1b34751bcdf4e7bbd -766500 719246e48b8d681ea5869953004219e8e9ad1ae095d9f7005b39316010542a79 7d760e07389497315c4c3b10c43d939fa4e1d43dc29fd4e898911ab78a6943c4 -767000 281b1c63ced6e6a9e548f01039e79b341b4c75980548acc70b0c52d71feb8e6d fc8bd623900af0aecc3fdec5de0a55fc7889c6b3005c4aa8fc3973a221702eaa -767500 d9a20cb9dfca54abe3534dbcf69a04b8f6b43afbe3703e7aebb2bee8cb81f73d 899b241bdd3264be250d3f665e9930a6b2f302e1eb87ef65845be021d856c35f -768000 8360e09883922bda97c55167146f583896798f25e12baf10cbdb39254ab11ba8 fa86336cef4c01ff1afee67169e0f4a3810546750ff4c38cec86e37c27444bb8 -768500 ffb03996ae3de8c5bf73eeb51ca0527f6ebee4b20dd059828efad08e7e6601c2 df22eef90381eb583a9e93e90e0722e0a6210c72da28deed40c27499c7a5ef21 -769000 2103acd9679638073a79876db195d494213d9d6e749faaeaddd6c672cc7e177a cc3a63870c9ff71fe67008397b61d975a8147d03a0d8d35a3565538ed514b4c9 -769500 9336bf1ee4de809e164e98a29bddd7a448333f2e25de891b4ac528d1bd7af785 605f77b3340dd29717f7ba780e9f4ce15fd0fa43f2ed916b9e54cf23aab2863f -770000 6182eaec959caf801de20f3000efc3b9431aa1af594a05d704bf2c53d810fd83 1ff43d1f6b27ee4063f01fd16f49110f0db50d58ee4937c28fef346f0777335b -770500 5405e7303c38724438e124b5e518c9af26a0076596be02cc57348e91a89abb6e a64f6256dfe425b8fb3b98b45dae59bac34213b85fd777b91d08d15a62a25623 -771000 07874de328fb41f73e1aadae9e57705d7679e8e186b8b6a2ac50ed5d1455d1a0 38084368706c2b4c84de621b821faec1466db4cd8334bbb13e4eb6960dda4b5b -771500 caf1cde2dfee0a11872272140e8043b92a33ab604f0b8a8c34d7a7006a11381f eb96afea84eba379a82e30b8366611d133f219dbbc728f99d55419e5494c5b6c -772000 3f8fb7f8de518b519eb102a29f372ffb4627dca2bbe06dc035bf7ebd4e6b733a b6de44e3b4a2a16494b4d6d7e5423e1ca66faf4ec0916a8ac97e4a3a656fde81 -772500 2fe560018de02c9be5e9cb02c0d2abcf8d6efd94390f10d8eb84d9dd3964d53c 631496990ae92715067442cef87711925361593696c1ac62ed053618951f9d76 -773000 53c1e8e472ee4d6bad6411fdc74d9fe4fe2564d0baf1bc5107b9dc4ec6262afe 8d48f77bfb9b49f20dfdb2168f0abb988b8ddcd8e9e62ac35ab0a2968b912986 -773500 2836b1c2239c528ef1ca59823417c6ae51c93040e1a5e3ca11742dd10350d3e6 16f14274772f96d6d2072a33cafd5c8f9cf4bbe37111b3f620e04bfc42392829 -774000 69a397d817d7155b644d650da51d5413ed2c133a3cbe2b54bbab7ae7e5a82914 c50ff677b8441b9a940984cf5ddb46f4b690ffbc9703ced2b163d89b929830b4 -774500 e7569a38cfb85227d2d2189a89c59518b64da01e2fdc89bca8e4759269fad47d 3bc601776ed5afb50fc51058a988d114287afa8fc4ce04c8d09215ad8ee3e9a4 -775000 d62bff072790320b532267e13d16eaa2b6124b12e9dc9704ea8b3472c33a7584 2ccb3c701d5d6730cb7fea0a703c1228f75c58b95dd167e135689d020e686cdc -775500 69206115fd6be6c73b95c85875329472d8550ea98bbcdad27b1fff5f13f1a383 1044c0b51ee23082e8268ea9f57e614ead985939009b2d6595f866bfd407c543 -776000 acae9ada07a40fbcd1abe244a88eea4497d892f56bc6c47c9a3256960c48a674 fa6f6390e5912cac9e116a1dc8ce23ea3acd3a45ab8c372f265c2a813a1d43c6 -776500 c7800bf474c58aeae4052c7de8a9a5be9ec371403659d6ce87f478083814cc61 5801468504c422c927e64b555cbde135e90690036800af540e0a515cde84a6ec -777000 60999146dcce1a4d7c57777fd14c438aa74620575ee304da40f3139145be094e 761c802120daf7dc3d71945a83698a8ec2813efe961ad3ddd5f0e8b05d88824e -777500 55464b5c24a72ca78e577947e5e31095625d4a5453d4ae8e1a628586173696cb 7198361fa24cc1510d0eed076fab9402f8d312924dad53b2cffe4a2634450753 -778000 a96e3ae7c78171f4839888370b8ab6a75527c35181a76170fb0c0048a340efa9 40f745faad08e9ec7fb07610cee6fb0bfdc4b221bfe568e692928cbd556fd0d1 -778500 dd54a9dab8dfd4362d396a50863007b96b150c454397a2b4cc486f8b4436acc4 45f3cb013e25a9a12e1998baf79504649e32d0405bda1b8d6cecb7f51597dac4 -779000 04bc1cac32dcf0121905e3b0f8bf15938de5a5470e130dad3d5e9478e5c04ded dfbf8b41e5cb2498ab9f6c772c18ae3af36f693115fd0b7ca12fc18fe8dc9d6e -779500 acdc4b3a573253149261bf7b8483f07e26febfa36a79b0f85663d0418bf89a87 c4e9858c10b84a43f0d48b59f2aabbb978411667e1e740d26cd90e824e60bbcc -780000 70e69b1c46b39329196e880591e35915ed2ff68cb83f2899e1c8a09885462ddd eddb55e0d58a9e963cc6bd8e74cdea45af4a42783f9b070eac50fd00b10933e8 -780500 44f6b73dd235490b827c83c949f8116d3e794d139ff88688db18a6b45e1473b1 011d86e2b32e548d2143b273ff895d85f132b7ad91a6ada40d29517155de88e7 -781000 afa04315bad0a73e082c417351c846b882f070fb89fbb62f94bf6627355eaba9 83f5ee23a34675c501aaeafbd8589c2173bed116beef5a6c05da3652da34eb4a -781500 daab9fd8e2a04d026d3dc748d775734b92ba9d42af448b88c4e54313458f8e55 edfa9dc118b24ca0b01976fa94551d0e78fb276ab38af92581b336d08ad979eb -782000 71ac38f6202666bef6bd02261cdf9590ddc79b15b1f0fd74a0991f32d7076cd6 d02102ec38f004cd966d4e8d53db021475903f0630404bac02af92fc1ba0f055 -782500 7065d66fe20e800ec4e007a0cd3301a98985fa7f755f0fd904b2a999c45f16fd c68d77bdcd1b1080ab776a210493e4371a1d30e3c73d7fe871e04b9345a0661a -783000 d494fe23c434284aa32d3043e1cc6443fd7bf9b36fe12410f7d2e35f5360b5e5 4ef3f9328e1d2d96c19ca549d1147c2063430601ec62870fc66c5b6e68aab6bc -783500 568a8df7d5669899b02e916c28755a8d1fc4a111f3af3dfd4195298ab257a847 7f752afdb474b41347fb14da6be44561bbd5dc034ad25035718d57ba0e326165 -784000 98aa97184148b247fa71460e2ac43389d0d04b6265546ce0eba7c2be328b6bbe cbb9d6529647174626503265092201bc8ed564798e1244839a9a2f022c5774ad -784500 db38f59e0843aca6f105b25581ed990384b8b6fa6c340cd21be37799ac892e8c bdf27aceb99b7e0386f937d7c1b8a5a8cc92ceb95cb3191e5502b41245ba3465 -785000 ddb1f819bd3e7a89588081208e3dc87ebca46dd381593d402bc80aeede0cd724 814c34edf844fbebab1739243a0a664de608eab49ef2d91c57ef7195bbee80f6 -785500 92f3c145e77f1f518c1decb6e99b826ce6d778c24634b3d6d3340897cb670c63 6d607478b75d072ff0a14c4c23454a04b9a08d3f9c196ebc0b817fc7b9efbd30 -786000 07a5df141fe4feb999505fef56d930e19c684e5e452ca352f0fc49c2d9eea76f 192297c49f950aee2578f0ee3249bdebdbf6955714b4a4e05edb3e8f24aae8c6 -786500 d9b454e9c5a5a6f9d16d22acadb61cf1ce231ca4dae12878d868598425eae775 d47d551d3fde80fb8fc6886f235fb6164cd99133fe9dedc2bdfeaeb10bd45308 -787000 1d5ad94333c42f9cd396bd5a2772973ec2440f1d9f3cedade83af2e4951cbb32 0cddc7f86a6714a3e3d2d2b004d1d3869d5226992f0bdf0f0d3bba94177b6a49 -787500 b454323565de62c5e27b717877037c918e5c046dea15404d0817ed066267fa1a e428f7829407e31e1079ddcac80dab9b56743be59912ddbc0e0691178991b568 -788000 28c337da150a017aca9d5619b15d605cfe5c41838893650f9a8108c4844dc5b8 0d7ed84426c912c0a3d3320009e66302ea92039ebfa4eeed9bce380b2b2df8fd -788500 5f6ec263add108aa8bae692f8381bf9e71a615ff5d4dbbe3785167a10465dfdd 3171b907ce8071d79c40b61ab802f51d8f1ecff22c4cfcf618065e8bdefa3910 -789000 1a1a8318353d2997eb996843165ce0a2879e058d6cc2498ac43fc495f3010874 0832a6b246a8221f36b8cfc3c15c743878842545a3ef3b5ffc0f1cde8246b72b -789500 88387f881fec667c0a2943deb34f9e508a994383c3ac8884d24b1dfc400344e2 866305720d60de682a074333f7b1512e45c63ab0f9090d8791f315e199222519 -790000 1659d12734baca5dc87174dd4ea3020c907031df843af6bdf22cc2ec8dea611e 63e7e3f379c2e361085770ef24c82f250cb47056045bae37c92cd369aff4984c -790500 a01132497c3c4a8622f3c0039f319e7bee99942268a0ef323cda3fddfa11f1f8 aebda06ea6afc6b95cd31185250686bdd815e89025a1b067f47db36dec1fb8c2 -791000 9209e4bff9f2c45a6bf3d2dd4f8960b050fef2a600c1dbafd65dda57bcd909b8 e005838fe0d4d7128702bd61e7be6be96340f3d4538aac8ec8adf6955bfefa94 -791500 facd9b684bce4af3ed32b93fde842ee8d30775ca97b1b3a691ac0f267301b280 df48a7e529861e94604eaff33a4ecdd7e35be502a78ce16aaebc413f4f4ba59e -792000 8439d367ef216677cf50d64e35abd6a55d555260d8a4f53af86560221aa48b07 6b7959d457444a0e8c085d2f366d54460a8e8ea5691d8d0f198275ef79b72ed4 -792500 2200f9ce62b2fbb1b25ba5e05a09301f576ca7606c2eebeab05a7188ff5d714c 2b7504213f6fa99dda613f8e7bca2fc6310930eb40c405a06df793406d146b8d -793000 3c520432d9a47e6e272dcdd99e656b04a1bcabdaafeca135cdb61b105b31d413 6f6b8a462b2d883580b1e2acacb9ce051016c06a12a87219097e5327c39d84b4 -793500 a9ede0aed7bc7639d97fbf8c81203349b1aed926ab534ffd055199c047c427aa 6b6e849eb0227f85c0faf658c06e5b4b75e15431263bc587a0417b801910ed72 -794000 8173afb6ef69b30acaed892e2cb93eb9186a55ec63a8730cf5f23909c13cfa9a 4f340c5f5665cf08ec366e0ffe561908c19c646b9567ab3078ddc99ce216fd32 -794500 debb2e81b7e22fe9f49c42c5d747837344567a5d301f900731c7ec427bc671b7 79a735251474e25bff8fd23b469f0d79eae7b941b45b181f475d7bf8ac2fb842 -795000 a83507c3c3bd71dec9a8b3f471cddb67361e6401767c8c8ad348926ce4830d89 e626138e04de566aa065b5a7106daa670c614de2ab4d326523bfe5d1a4ad4899 -795500 0558ab8c1e1ddaa709688f0fbdbc1413bd8f80362f6e053f20479e9aeeedb4a3 13a40efafdbd6358d9ef9f1b9307a88b458e999100a93b8f4611542996eaebf4 -796000 a141fbfbd754e10fd7e956c10d459834261d3571affa49b8fd90c0c804d0fed0 00fc2ab3f76f3b577f97c348313e9256331ea81a5cfb7d8466fdf144c8e9fbcc -796500 7351e53a275444b95005213efb4a5a1397a7a01d58b750323bd37ac47326c704 57ea2db92ddb3e36ad171b3bacb48f883fb7e8ef74466fb769f7d5553be66c0a -797000 80fcb6e51160ba191312939b815fab48de5a56f4121a3d2cd7b6925918a07af9 96242babb7769751d636828f5fdc2d1a44ca57e399fbe5b0683d09fd66b83da2 -797500 57bf7c33a40e1813c1947efd7412a3977b0d74ebfb6e846097aa45d03eb1fe47 e1250b6f44746881c59360dd6144bf4d2e86f8e31e68b0b820732b2a8bd69d5b -798000 f3370335ede3598caea04a87041fa7c1b51e5c9e1c5e0d50bf2bb136a64cd167 e6e1d946fc72e48f0399f980e5a4f7e544b4eb2997739223c355e3b15af48fed -798500 8f2f93e0248a8d8ded2c5106fe5034916127161f1a554e2ce307c5b6afc3e00c 2db41c24fb6ddfebf0b3bb5d74fbc1cbff4185082e7c22ef66c336467c652180 -799000 5c376ff3e907391741b0ce9601a65e616d6183cff6bf744bdd6597c455b306eb 9b86110172b3879f17995b766972b505bf547f40e1113cdb52533357eecc4ef7 -799500 bd143703c66bf324a5cbf67f9da778755b4f7a598450c328fbb011d1eba4d96c a4c63a77ffa25dcbb59ef8e829106f61ad3875ad2b9485ee6653a83691bc9ef2 -800000 e951054363c21bdb8e2c65154dc8453a7ed6908ecb10ed72fab814899d3cd345 9a0b2888559918507acbb704a78888f3293e34ec18cbc9961ac7842ca297984c -800500 956b9c5b3c055d3ff4ca81de618186166629076e317b2bc429faab8ed5a9bea2 9a80628c0558276ab328fbbff05e76501ccc20593000dc13d57eb3ac4b618838 -801000 3abcc1a5f4b6411fad8b518e4e0266bebf4d74ec36400e0b242e299aab5d8d43 6e72ab4aef323f82c48dcd697cff16bb1f0ecb039a1a892a74c57abaed498d92 -801500 c49350d66b895f226052f92ec5d5f35b70596d37a64fc2f36e386c21cdc224a2 1e1eab3a1d14c473a254babba1a8c9f342cf97b0ef0f60c2946149c72cae6423 -802000 f739f9b985ba0ee82823c7c03d7ef8788d23c01ffa5ab040ab23682d5e1f27f7 45786b2936278a79a8d856f96f53f0d4b09a04056b96a10d5bf71f5ff849cb58 -802500 1bc5ec3d7f952e5f27e9de2f21a30fe9333fb4a53b9627d78567d789cd578098 11b12b1784bf7f779aa53e67753bb6eb9d1fadae56dffeb1b9efb5f1b1ddbebf -803000 06fe520cf2eb81478bc9548d5802a7ca815743a5e541ad64b995af5b177ed245 f2401149fd3855cb680fdbacdb22b368edb2a34f73c59af55099c2d44e79adf4 -803500 2bc1768fa981d73fe4eef0174018988fcc0aaf5316c8597cc1c1eae8618eb055 b1a09ed639e05848794994217faf96d9b66a9e5ea926a08efa7bdfcef312b107 -804000 9d0ce3d35c935bd67f2970d8d3d5b098f99f936e880f9ec87cc5e0b1f837a0d1 4eb8648f841497a4bf8388158844361e138eebcde30aca295e530b9d97bbed6b -804500 87f582951ccb498931e71f194f2bacc2aa593bfd236519e4abd2336136333283 9ba93a57335f44c4bfb962c33fc0698f6846755d94ab393b23a81fa9acf72603 -805000 efa84f401e0f8a68ac402f09bc3988192fd6c85f22fdf239e5b76ce100e3a2df a4a5b65c94cf7ce1d1cfe3c087f63037ba522ee4916dc20051d5953f6d42e067 -805500 c0aa476e7e6452f41dbf4cb5bca05893a93782716c3299f44cf31670079f3190 349733cacd77e399f52831dd1f33884319cabf7934c3705e798fd8add0d90247 -806000 8459d195b63e53f3495da811539f2c883361bbcdd4b0097d0ba214fdc55a8219 9fd38c1f19472a144ec9b8cf57d8d9a85966dbc99cfb05628f5683dbe75501eb -806500 8ca60c34843a452a19d05b38dd13aaaddf0cf602601ab66769801c5443380904 f1a31e6d1b4cf5387c7def82294d179a656a10f438585a643e49dd6372982193 -807000 ca98242c7ff34cee593fe6dad4393698bf5875e9a980928363fb0f2bfc01e0cf 040fc4bf74790e2218abe48b6e53fbc6103ccaded8f389a0957e9008f96c9e2d -807500 39be5b7e38795922ba3653d1310f1579b152e493ea3c8bd6630e0a561465fd7e a88ca5c9790cb9542ef0a64dee1b5c001d56bee7636c09105a95abc859ca5335 -808000 8e9c44d713b7bb2ad9d8cbb9ba3d9aed199b4a70ea1f7288795ca86c966e323d 2c9dbc0b472b7ae26418b1def60df7a4869a35cf9bbf74b9a323d08035aa13aa -808500 dfd89eee02bd3dd16482828c743927801121f67cab61a4335d4eead749876a21 549d7b6c5b66bd74331c6cb6f937c8cbc605dee884796067f42fa1bd04bc6a86 -809000 676d2d9df28b1d4bcc68bbb1606033349d3e3a4c11790eef43f689d5e8d3ba7a 18d4addc8cc3174723f9ce263cf632f3817d015245ef3fb6ecae87aed807b0bd -809500 001261eaa38a49c58facc31b6c7245af90f5ccae8d120be1aa3b23f80e68513e 1489cbc34c82aa22a7de85e615f2039703a23da1494aaf7b9d1c425e4839849a -810000 051b563ee0050d2539bb0f57e3a5b5edc759af06e4dca9ecc9b651122354d828 84359c9f7e1bd44948c4df3a1affb6a4ee05c2761f3b22a192faf696c1c8cfe2 -810500 9ca81889bc6223d0195bb98eaae9b2b81771b202153dbcd4aedeba781063e4e0 9ee6f32bb1bcd2ac2787662019ca595b8a2569bb90a38be9dbdc77fd30e0f541 -811000 e24027de80e7e3cc2e2fb95439a4bc88541b10316eb1b111d107119a154ce444 373b8d3021db012bcd4b8558235d625a2d8eebec48f5c9c8784ce80be7ea459d -811500 2188003a3ac1f51c3147082a9737895235c62f579500ab7207e04c3db272300e 5d5c778748335e1c6a4d7b72e799a84b1128150bc5b782238c222d234b6e916f -812000 8edc7d32936aead671b293ca3c35a4f2cd8da3da8d0a911eab810aae919c671a 67921067e57ccb2692bfb932c9fadfd695208ae63e41c58cbaa2d1ead989b572 -812500 f93429e089b8304c72beec28ab2589d33557ec36f12f1e5c21acf96a1eccbbca bceb1b621ade4000a2e9855c387f4575dc2599df96fff5fbb43a4e934612010d -813000 c50b28d6a65438104f28a3518afc71932e5acfc9cbd3dbb0870dbdf8e175e159 b43d73d2203a216818e42d28b5108016335c606dceac6f6706641e240b065929 -813500 9ea262207c1743a9666200b8f174328d53875437ef4238ac0f7f9f1e841d52cd e915810eb721a46d939812114e3017db4a2fcee9c0d3b6701f070d61260706a7 -814000 7fc202882e511a8dc8b76ba9fd0e5d24578c5c45f51998f83d22e5c54eb72c5b 69feb5f7c9e1eae4dcb884df1bed34f628846110480539f3ad02db9e49c87f59 -814500 946dd535ac1806a838ff7af300006a3b019926e3caef42f04e77cc50453fb597 91645835f2dfa4f7bcd0818c145f349fc912335d0c28bb21f5a6c88833531ef2 -815000 32f06e0d2112aa022953d25a663a77c34fb1f0089091be64755920e082588a50 09503cf3aa4c5c2dcdfed49412a77bea1120ed6741f024f25384f9a2f6865f4d -815500 ac758032ea15073a6e7063dc49bac109b04e84245383dfe4a57d8a2d68e74c5c e8796fee578d7b8c3a1282cdd6106eb5be84df03f16f290b1042788e3cad77a0 -816000 4b0a8e17626d583d00af2d1e0d3d5aaa733b2637c0e7daecdc9ca7d32ef78b16 5513bb0e272bc3c35af92c733ac8e3f54a4f9280dd6305eb3f521c0a798864d8 -816500 7883f443a30cbe6777c45da4c70e650bdbdf7f2296d0eef9580b412d304dd1d0 83b8b3ed3caa544c6827b267919896ad0df9b50b416b4092a81c4a16cac4a2e1 -817000 d13df124f351e01764c49f28bd7bd9d94ec697abb36970435ede31462e245b78 3668760c6bac61282ad6173be88f0ac74108aab7e6b2d5b89bb05be5f7450139 -817500 cd9bec7288443f2289c3e350aa1e2f133d13377ef45051c8ef68f588f0ebfb9b a6dcda37fb4542b47d6358e6f4990494b3889031b7d57270d4581c3c5f5c834a -818000 db2426a8e3f0260a1385c6514a424c1db30e077cd18f25affc301b857899672c 1e887aa787c16fd0a14425d7699a20ce4a184468a4e8ddda982637cd60dd684e -818500 475ceb331fef75bf43194e6ad78493ee5a3132b1366764166bea3f98214c5e02 67e95130d865ef6b96c3c3594993525b0ed740d94de1322bdbdee1ca44c52be8 -819000 8bb061140f8217d2d20fc59542169fd7afa823a911f74040d58b3c86dd366481 226b79c0b56a187130199fa71bb43f0c0c17986b38be4bc953aae9035b3b137f -819500 9fa10df35922528bf712983310840e630f4293f91e9e81ea9a6f416107b4b385 23400d8d0d4f2eca02b0a320b012d9c3874250e3703defd32a742ff3a14161f2 -820000 0b83d657248250c7e9d96015875066e2e5d59b7a0696af84d83b246abf9355ae c7575028b8e2df600f1ba0acc5a101952b47e9660a8a912940a2b548172a05f4 -820500 e0176c1631f2909dcccd2e56971085cc4a435398a3a967945666e2d7b3232d1b 86cbb6afeb7fa1e6ac902b3d28f2aff25971d24b6cff228da7e4c8046b397ad6 -821000 be0584aaa7571f33c631f75d7881d80e2a19f6eaddb91f311547687ab8b6127f f8edec8d65127f3eaefc274cfce29f29c4cd339739f2903ec60759367f283f67 -821500 fd2e812d81cc2da106beaca8ac8e7ec4ef854416f30d7428c83dc72944e01ed4 9bccbcaf94c587dafd152fa579fe7bc4e87734d1840e0f939f494d1d60dcd499 -822000 9054e0ed1b7621397499863a4dfee073b379cbab6d211118e0daba86ec09b239 0f78238858465e4308062dd44ccca1a81e3b1aa830378d63ba37cf340272f04c -822500 c50dafdd9aa14cb0fb01b2d54da426cb862dffeb6369c1ff1f27b86bec6ea28e d7d020758a8d3fd93ce7a603dc710b085d16c3c232f389f2518b96b88d903a68 -823000 6631367fed6a7ca98d2ca58e0ccb8060e9e0309df1bbb5d76ea337c386f3066d 4ef109d1b5fc3ec978f34d66b8d93cd3ba0b278d7ba9c6ddf4fc3d56039e0fec -823500 b924862a40ef19454769b776643bafafdf407500c16dd73a70a61ff7d033519c dc8d2c04b3dc1785a7a76698674830e8aa8371dcb815083d849851ecb47f1805 -824000 d9ff8b7426f57da2db3d9f855572b493eba90e61b0ff3b40beec0b46578679cb 95e502ccf5b34258f239d7a5aa86f16c643e189873979210e0cee9c5acda128d -824500 b668014cbc4e38dbe8870d15c7ece604e8a698dead63136af5954cc403a13921 b634009a41de61587a78dc3ab8aeea26b6d107f5e59df2e927321f31c2751347 -825000 ab26157df7834e458aacbb394f8f6f34fd489cce3c7a1e6251289401acc59062 73352b8b59b8fdbe1d83e82c2da9ed6282c5788802e2eaf3db7e7647e04d83c6 -825500 4447fc4bfa77499510c1f033998de510174732f103eccea27ffe544577472f5b f15ba38703c021fa9419af02b8210ad9a9658b8866f70cfd734e282daf996169 -826000 8b30104ee7551d9d564a9142e2334aade0c93f1fe7846f2d2d21380096a5a1c0 dafdfa617b0bb3f7980b4df7dd4d0159144b7973976db5e60a28308c0e9a2216 -826500 0e2e09768e2c0cf1f39eaab0b5182b1616b40b9a6d931946bfae09c246bff35e 417a26d05c6fe49e0800213efe648fc7fa29040f0f16b4e0f3814ac4087fba79 -827000 9539816f7acbfb9151d30dbd91509b104a83bc0564050ab5f3c3a180d1659bbd b8d3ddccffd24ee4f56c161acf6a739668f48a10fc703233bae30108e8b23f04 -827500 735c35ab86f85b3d7c430b126cda4a4c8e55479a414be9b344ef0749bb2381dd 526c10694250f563eb1f7e7be275d89c14893a95118bb5caa0fa3757d2f1b08c -828000 846213c0f91cc5f47286bda5e74a48dc86d91bed3d5549f2130211dff2210540 195e0a72d1b5934d7b37d8678c6ee6da4713fcfad761e397921573f0c727dcae -828500 033da5a6c02d67fd91df3e6d357de891ba0a8352546be1e4c3c47d6d7a0b8916 3d55e3405532f51149ebf67cc1367c225ffcbe2832a37814c37dbbb324fe8c6d -829000 b64d6b04a7eeb8513608c60f52b3a54a2758808beecc359cf23e5a1c9991e1eb ccd618e28a3217ca7d14e462c4d2df34473438c0e89e68a498b9d236507003bd -829500 31cc80619db75aad85974e5c52755375dba0dc8ce67a17e6e6e4cb29f60dad24 41145f9a5566c0d919937386229a00f302067d3d0dfdc369d866f164c4edce40 -830000 ba6ae9853c6f5efc64e12f9982df9f199587f43ac41c49c56c52a217c42d31fa db3584bd7127b287f20a097fefea21aafe602b6d36287248e5b878d8f59a55c0 -830500 881ba4b6afba166f55baadba4ff7b98076398db48b53f05058e4fcef5931803b f2d61ffdc8eb96d572eeb829ebe227489c2748aabb4e7ae8dd2d4ff04db6135a -831000 a49b5343b0e4fa384c6cdd8a9b79713ddefccf1cf1b9a9b8340a55ec56330684 d5d6f8ddaa5631cc30932ced1cd5151825bedbff4f7c454fcbccc0dedd8822c4 -831500 2325e3f54a404e7bc60ccd0acd9ea77d90a31b18f8368ba2797d9a2f7388b482 09565fb72aad572d7b2fbbf1b0662da7687c7d98db22f55063d753d0e59a9663 -832000 79353ddf61d1fd1c8930b19c8e2abf92382f86b7ec5d3de61a766952b465144d 2cfcfc5a17e8042417128b3e60f6c2f4acb4f980508c3d172e0530ef1322f55e -832500 15c4c20b6d16377134e683d2eb7d561d4276a32d61f2179b1ec4f6461ec4954b 8d2364c10cb39a2c74360fda5585ead678c0325656ee7e2803383cf5c9e94862 -833000 771fb7f8e60a4065f3977ce3397d58a58102e11111312bb8d61399be0774809a bb06d1ca6e8e92d34fa9f31c9e3332ee8b3b31e0a4bc3a1deacc6a9e0a24079b -833500 b9d939f1ccd4ee8a2b769a4b014dd932f2d51d765eb4a4cb45844e726ba26f7e 77a9c4bdc03d8413b3600eece8b0593804b58afc41204063c3ab92b4c70d2478 -834000 c7bf6a274ef1f46d5faec1bb73cea0d5873fd15340b0ed103b0551213bd0b168 89deddbe651ce60767e84fcaf8419a7146cd8128f439436cd9c5edeea0c0262b -834500 614d3beaadffc9dd3765a68108e9f2e01c33a9c440438163970be6883f71b68f b8cc0eca95d7f827ab45bcba1eb5640f883f803c6635d09eefae1ab30558872a -835000 9a9f3c4367e50c24b3210a0650dbcab4ca0762018f41110fd7d45e70a0270e7e d827e1af0280be63e64f467a81e39404d3798234593ed89f03619354cd4dd7a5 -835500 cbbc70202da7cdb4cde6059eda7529609c9781e534661c44a1f61e5fab4de31f 9640b254c6bf22f95f94b10ee1263d475d76ec7ffc8d8813c2a7f73a7ca77a28 -836000 63d55fcaa4b84b7278dc98564a5955756f3ecf915b231cd6f2399ec836537a34 be4ab8603457a5c080f6d4f451702426b19f87ade3869565c41aa9aa1cdb6b16 -836500 a0a1ad507cecde4069df4dcd3ff6b0e44b917e732cded5fb86d50acbae0009eb 09c9ddd16cdd8ee68faa85a59b8547b9d07b19ef08ad42fc9d98f9d85ae7f54a -837000 4236b2466078279f38a8df0df56bbdf71da7a184f750d439aae1b7b9b6a0e217 1b7b95d0f01cc0dda255ea389572d8d66be622054e9913e6471347d83070da7f -837500 975034c8d678099a6afeff9e8e37d1ee524f64a851ce07def65676c0ee189b4b 2dbd86bbab192ae7e44609388bd9036e20d6496962b2ced1b23eb764d4eeb3b4 -838000 05228288f4e87f9283efa2e6547316fb61f8a6c9a1c4b3dd1b919d02c4beff88 8bb8421d901f05fcb5b476b8d5aa66f4c380fb7b00f65833f6b0bdd6ca93f62e -838500 f165d6b92e8b15b8a276e7aa3682e61c44e6729a39111e1883cc8bcc78cf9b30 55e669d31736fed4be07280a142594c8f283e7a427f0630f9ee7f0b06411b948 -839000 e7b73701d281fab70e7279cc3406b961db9c7d89643139882ccc269515bfb8ce 44e7b9087a0f031995a963ba2c3d4d59a2856ddf3e822d0944fa472768990ddf -839500 a0e9976acd9fc6b93cedeaac38938156409b74d9192f1eb4d614d4af4072d67d 774aeb086be488987a9ff3d9d80fe11d7815c1061754431fe3ec2ff387a4e2bd -840000 85f4bef924671af404c377269d655812da734608007a1e43c7e2c974ff1a7f26 a7c27c2f0b37677d61314ca1a510aef72e2a7149c0dfb3e314c47ff151a7589f -840500 9a3f8a90c257352934919ba5678d710e02abeb3f8c9b609f00827147d2f7cf81 c9234118875f5ff26dd4c37d0f498911d1caba96dee4d33a50c7ce378a9a0749 -841000 51b45385204a2bec9cfb32ccd8677bb9fce49c7c5fcb6a53c452e9b36cdb0bde 07ed169f164ef448a9a828d17a6c3455f3a11dd6c2bda1eb38a5100b8817e04c -841500 92f53759b018613ada40999270e66657ae1026e4997862ed0d5e5560b917d6d2 37b8239afbb1d59bb35fd5696404860f47dd31163981e62738867af4d1d13c85 -842000 a1202ffaaa1bef1c9c95e11f9b2f1e1b03e69f535628130df12635ed9a3fc297 ff3835e7e4cb8e4514adddc8fdcce0466170f3062e57d9abd9599da0fd0ae1dc -842500 fcaf836bba0923b8d887f619a0ecd298a94f04a1127f82773a531d8951326582 7fd60c91ddf7611c5d0200f3f5adffda13a651c5bc71929b0724a3ef0c178463 -843000 37827f08056c92edc0a941127d96f9f4f481d70cf2cb6c8c0212bbca042ea04d 863b61ceff5d6d3314fb420c17bb16c00b220833a634f53d24f7fb6c9ec7f7eb -843500 5dae3f790ecdfda5bd46aa1005cdf1170b25daa976dfe3f83f07cddd47747f86 3d352565915c9634066580e57621f6682cc147cc92fa1e7f0112af699a2a09fe -844000 b3b067a2be410c5b04cbc3088bcff2678204f31c734440fa5ce28a43e61f6e20 dd379efdd80ed38f855dc2fed11db6947ffecca2c6d78c3b13d9e42de618eb95 -844500 d8ec90a7f602aa58fe31112ed0917f4597352ffbfb186524253bd4a88a283efe b8684b9b13ead86b6620d8c6cb1b4e3ae9891ad53c74a5ed93bb547b05d1a8df -845000 66ca29da4d604a893f7a56ebd96f365b3853ac2de6b38b71db898ed7226fb49c 2a671d1a790cf390618793e3a9e2995de070c431014e9b1c88c9c587cc12708a -845500 b735fe850f31101901fe04a4207e15ccae72039895ae0f149593dee3e6cf8a47 fde7269beb8e5c3ea60f2b30d1d43ed52319787b1d9363aa67c53e6beb187d6d -846000 b526a9a73f37f20c6ae046ec9b131f6354e90a4596cec60cce1414285c838df4 fd42d265ac2d194a94732500fcdaa7f4f2e629793fb220a871459880c0cd000f -846500 761bbfd7f554b81cd153149a73641b567685b60914402dba0ee171d8dd0237e1 2d9ea683992b346008f860b330b15ba6ea707338daba431103b2a444542f9870 -847000 375dd44f3bb80150df686ae8f3813999d60507c6e9ac4750686b5d182adcec3d e4ad131095150cdc0a23d0d7948bf3c870e01ed0b4a6f9950457ecfbb254b342 -847500 0539f76c06c311da93887c10f65904de31c72a00a2c0ee1bc66a46c50433c0b7 2ce4000e6e36145f7c0711f53a8b20144a69599490a7da79726938926685c5dd -848000 c6e8ae1f92209bde14bb652bc8478d5592d0f6741c3d2f2f232c037494d81f70 b7c0aedb71b645f0501319a9842e1fac4873184f50a0c5b758fd9f2cc2547a1e -848500 d302c73e4d2ce3e318afb5cc773b089956501f00f64de08073bde92b2f3a99f3 0a8901df9a3d00b66ed1bd0b117645237b61fd34c63fc45a0604daf2ac932bea -849000 0ad8844c1a45d6846464c00e9c6853719f80056b6f0fb70821536a133432ba1b 6478dd9c136dd28bbc4a49eacb7909c179abfef94618dc6da67adb4ffe69c6dd -849500 8ddd724ab7ab24e5ce2f5355c2c4bea780fe7a2b4a01fd04d6a0be5bbcf6059f a8ac1fba940445cb8dc5f6eec18d1546f36bc441db187b088b1054ce8236d17b -850000 b5e0c35c2d33ac37932b6d187a8839f1bf846817dbf5f4c58b73418e9a93941e e9f2c9230ca20ec14c17a35fa24d9eecf9119c5a38809c420ef099d9cd4ac61c -850500 7c1ea7bb106ee4a55d64930589f44b2e9fe63ab9846eb3caa545fd3b5597ac0b 9b2b304003bc1746f27de0d9a7cadc9dca7d6c87b6cd5c88da09f45282298480 -851000 78c3131d573b6a70a648b111fa904b99707c622bc56f842297953968e50bb804 9dcd68f3d2c985c324ae53f03582ffce484a70724e2c13602f84099737641cd8 -851500 e470491ea5d0631653c6200effed322f6696614bd98109f9f1c90c2cfc72f211 5dfdf81aae36a8b8aada229a8ddfba138552fb9e101f4faa56bc76d3860e7738 -852000 528590bfc01e4b7f567aa786f0de29c2b7aeb8dc3042114b087f761a5e6b161c a96175b5107c4129f6512d54adc38ebe2f236ed6c3f362f885cd4a96c6651e0d -852500 a286a106373a8e32cbc0b3df7ac65b0720c04cae34a07cf070bbf652474d8c56 205a7977e413da822705095027abd2edbe7c5e34c9afb7225721dd18b700454c -853000 a2d7a0b916cf5aff1d6cd5150b034448c58dbd104c5f88e9b18a692d4a8e98e3 d91fce318de2b273cbff6891c8ab29c769d7dd2f09b302937493a38488ce1446 -853500 794d93de5f3d5c39ad05ee77658de33f094880b037da8d2c124f4257f7360164 3f94598f08e53b436df3517458172624b710f4f9c108c463a39b2b816e511a0b -854000 886b8b0cae2d1c914ab6748d636d5553dde505c655102ccb384a5c9a2b864516 308dae1dc6e58335096c15c90fc276e9cfc6639289c25a9a748ebe226f37604d -854500 78d0ac66bbe4ed7830eb9025fb934514035d9440e2dfa75d4046410185235755 e2976153d1e9c4253528b84741fbf9d8bc73e85089d63a59b29d5c847e336c02 -855000 be6a06e20a33be8f7e0c96318ffc3ad202215dcc9124c06ec678a6a775c8f67c 4ce675eafc85e0f8d54f8281fecef780e98677534b3dbc3b1e9e7f7a529aa3dc -855500 ac409e08616a1e06ddc3e14a2b1f6bd947840932fc6e8b007246de280a6b66bc ebb67251598e38254f9327ff1dc2336da5269cfc209a5476260da523cdfee0ab -856000 62a624ad49bb1908d25d7190f363019b1cb5f1a1dfb849bb50226561b3c60218 ba4fef7924ee2e26f271a49319726894894497685b1c81ea84e0bb62246c24c5 -856500 f02dd187e61db50768a596177bf62878130d15910ced1f4bed2d5aaebcf4960e 8e9e38e2a88d1a24151ea08cd82c2debc7034d5fa21e75f926d9a6c0df18d6ab -857000 b2ea7f0e6a51ea74155d6964d732dcc4fc8a0b71c4e6837d1f17030d026da89c 8ceccd983eb05888198163e6a0ea44261e44876289a9effdcf3d377ccf62ef67 -857500 f99e644cfa949f806ea938b97d5232d9430ca11a51ecb0ed30ded90e6d4f120d fd26d9ef2f463304bb2839e8bdb3b5b0f48592e2cdfd043ad809292e22391623 -858000 9dfed199b5f19ad984111f21fdaad2d5d1779a317ba5982a93e14e37e21a2eb0 3da6db23d0fbcdc02c440eb755828b4a5c02fe77c75b153055eb25362399216d -858500 daf47ce2ce33b9db10011f6bd963bca3abe9b8b27e6101394d5516555e8e7bc2 4fecbb4ea28d764bd3dfdcb6571a7c6400c76c1e7f21a1c1407d057fbc6feb62 -859000 f6cbc9c86ebcd2832f2d0db57e47b611d187189a37f33f7588c7c24e2f2174fe e85af2f0bf8bae60e417cc65de17bcdac486348b40eb55da41a51e98b5c148e9 -859500 11102fd852576a361c4c9a3050eb8d605f317f82ee78200d2a2820d8a3ff76ae e70ce2ca1c2e9b818d276254f46f0d6156003a8421ffa99fa8499a09a982e1dc -860000 b0689ff799ad43c8123c38f815e8a5dfcb4fa2b2cc1d59dd08f6d6e6f260ccbe 60815a438a372d41ec3439f8b21cd8cbea71b090758260b1920dfdba4558f235 -860500 6298a42b99734a2702bcc358dcf100321fca31a1cc547ef0c168fa83a50eb132 2881b992eca478a15c1d505d3b021e2f589d536832e98cbb90831b4d0daff767 -861000 9f8f6446a6df4ac6674a0639bc616fbf8955fbd7c5a6ae8743ae009340acc6cd b9c2b8a675ec2a9f1323f5391a81d5a2bcb83ff02fbfb94e1960eebb50033bfc -861500 c53640e61534d7de4001cc4f6547133d225ebaf607937c6ea99b3a92e0f1b445 7befef633b3eb72ac1897e3628b20540cb0cb51bc447fd69877d178705b165b7 -862000 1bb40c878bbe264e2fad6a6e523345390091bef9bf689f6860bd30fbd27ccece 66bf4703cd800c13edc3e67d0889df0c4694e2f6545c5f71bb0d43d80adaaaf3 -862500 464bf61e9afcf7f9418661d069ebb015bed143a3c53449e9ca98013c624c0d01 b858f8d0afefa1f199f3434b656587228c659429a9b29876139cbcde4a66d36a -863000 0dee780a99a58bfd60c05f95db7ecf49c8ca8380b7a5b8ccb4c7c26229966441 4555335383dd8dc416b36cfdd110d6da87faee63fd0461dbacdb6cf9dc61fd1e -863500 98a57cc44810adfffccb2f42f93455e1124e3297a8dd4e176b6367bcf864fa6c b16bc478ec16263bc8995541eeb0cfc6640074c65853989f7619f1094b48f17e -864000 516c8212c055b610d7295dd1dd14e797a2b4ac025f1fd2aa7b3d26488f260a60 e221eacebb459d180c743666d691c11997995f6f4d75dd21613b75eed2be2425 -864500 2e8ffca67b4cf71272e42d524e1427b794a8e663b437c156cce8f9ad39d28b58 7237d3868b25d2fb9801de887b7c2071cf24952719c6170a6e550773a61a2170 -865000 995bc313381ad5d7799cccbcfbc18876582f5a82e25dc4a6bfd299facb83adba 3ea758c944b2f0be32fa7fb541e18f683734df6197ba711285bedad4f17d1c8f -865500 dc2fb63083a52596b814426dc2577b6eca27f5e80b08b83776c93adb0b913324 007ae746a4a5b901f91e51014eefab59c84dbec3a3e784711d1a16df0aa04ac5 -866000 a1a4a61f9e30b4ac585c2777dcb066e543a3ff03ddc20b67aadb9fe8842080b8 953ff29441259817927e36e3a89db69fafe11d253509c36a2bd00805563ec4a5 -866500 44fff17033fa5e2f48afd1313484e62ecb1bfaeaa0b19b1973514abe18381d2a 1bee0d01001a576776d0e6113954449de228bd3f69feea67a11769f2626176cb -867000 77d6f737b4c7b493657ef08c7f28b5dc43e3a7194b2e3193a37d1a931daca9a9 a9f847fa150f5881ffade66584ad6b5a741f8dcf9310eb808181c9c3e4724a8b -867500 98da2413dbd1bf3e2d3d6254f849e3a971ff9579e78a4bb1ba192f61a1ca1bf7 55a4bc913aa643d798a0d9d29b5c31bd38db0051ccedef30bf4bfb2ae6210159 -868000 1e33271126faa909e8b77bfe4431587ac68d50716e3ddee70f18f4ba56509c98 6b3ceb03adfc3ed05acb7ca6a2c9822e0b183c1359826f2714d26fedcc8b779a -868500 b4bc5ab2d0f52588e8e154a831e92f9bb249bb30c4b6a4e379d529d9c916508f e1810b871f581727fa81164f7ba37242a0376aa7870f897547fa032efef248a1 -869000 9db0fa91a26eb2c05272e50cfff46c7c9faa4d72938f14f03736c7084c4b2d20 e80a050a8dfd6c5d2ecf765f43222b8aec1a85232641c32583487753ab3107ae -869500 ca4ed5b1069fe42bcf42af8fb065aaa98db119b2e98c23c8ee9dc823c46a0bc1 1f45046c69978e3a13a013d995a469a2a6583b18cabe3e48c5735a1bbe88f1f0 -870000 02da00fc2fa6bfb0027e8c85a1b92e919495b84e763dd57afe758df11635956c 8ff1ef73ea14756b421192b3f936ed06cc5a8f016c33a4bb8c3eb94a0a4afb6b -870500 04cc97d0004ba00a8211986f0fa13bad1cb0e7cd17e302242128ba5bc923bbeb d4dce041cd8b2c51cfb7a50864de5d72a627a93ea5f5cc4d837004e9fac80691 -871000 8c46f91d61fa06dc47ef2715dd66a510f1eb909b275c85c0f8f914e8ef0e2ce8 a04657d974398377996f4584c23bf29a55085fd914b88fcc85bcfdee46c1f4cf -871500 285a13a25bf27fd974c9bd32ffda2796ba46e57044b4c282331cdf94ad55ce0a c701e8a240d4dce38b98c91b01c0b306ea6c8e72c345a2fcec704f4af6f880a9 -872000 0f474790eec84e0216b27a41df528a1037767792657a3aa79122dc31caf1e1bb 0774199988a33ae42d91de34cf2c1450aabd65b62e4792acdd67ee92c9d617fe -872500 4192751ee0a2c7b7bebe5e6a7c60dfb98f1527eb6dab97071b5ea89fb851215c 9e36875819fc969d8b5f971bce6d1610be7a012a520b317ce574c1e24f26c0dc -873000 34692e36b62fdc785dd9468d43a0a637aae66ea75c592d5c92e3b79245efe449 e97152bec752a6cda91c4153cf191e6a04135a2d824a6ef8ce6d64f640a97fab -873500 af2ef369df933f912140c7a4ba01d3e33ae803b7b2f4939f8a98405fa4127b90 3e30270cf39cf279ffcf99ad4b0cd55c85872bbf82654d03f6a9a40867ceaead -874000 7f1cd90d997b5a1da4daac3691082770bc7bad48acca998746980f0b57ccf21c d7cba24bf85848378fbc0f655a1795b9baea22b97a29b3bb1b74fcbdc25baec1 -874500 c15fe484c8c031d1327d24f1b563bae0c6ceb1f81b8c0b37c1a3a6d3ea9c12a4 532b3b617b128a1da69a7390fa37d292771bfbe039436bc7f34cc60d51ba1289 -875000 6d606825c8c4902999704cd9839f60f072743c33ef3cc8fe5b075e15ad6f521d 0f98e7eb858a741ea9b7f9260142cd07d98f3ef2fd0f5897f0dd1196506f28af -875500 8102b25248d5cc9fc5e8780fa7782a5f37113d5797ec544bcb6164d922d91ddc 5331a1c3f2f1e95e9acc0acb83ef4cbe04785dc7a319ce069d252cccaaa748b8 -876000 2a6d640eb47cbc93033640e4eece162640b36cf256a1cafb406e2c22f0c10fb0 34f34e19ede327aa5be14240436f18ead4abe6f226c1571429937380247402d4 -876500 61e5fae25c4f18e92e7adf64242dcbf6507a7ce4f1b0de6f2e614b8f1f5b33c9 3f421f95de7e2129353ef06a9f9a206639e0f5be018937dd02e4c39907b75702 -877000 46d077012ece5a31c29ba761425e6ef9d42501740db45016c8c5b7da1d216c7d d06c5c6aa3c05475f8a8649b9b6134e0c92301d47186f2c379e7b159bab2388b -877500 610a50c20c1661286355fad8c8d067e794b5ed61c14087d04976cf0f378e37fe 18141f4f7bed0308bddc68a7b897a035293fa9fdb074b6af3b271c2365a3d1a1 -878000 1742b73fe7c2d014484b21a1604b0a70dc7f12540d52b21ccfdc9f9ea72dc53a 90831e43dd3912ceefc00d3d544c3f26dbf358ff3b5d24041ba1f322be13d9f2 -878500 749fec5fbed9d5446533f22f0aa36c20b63b35116e6005ca519f7fe1ddc76b93 a13ee98f76ebaece600b0723a6ae7f7ebcabbb86e6beb5c4b9e5cf3e8170dd76 -879000 8c578dac00d2b6db2e1972886194a4be70dddbceeb457150cf1b74ff19022532 627f0854e663c40920d22d252b41ecb60a4bff1de055d1789727ff33eee14455 -879500 b31016513fc56e8df0eaa71197462492482734a9dacbb0d85838bf4253b70b30 854e8e0aca0625eda1261e56697d87244c1e386be8d6aa78f15de8de50a76169 -880000 e0764e8169753f7f532973ad4706e5f6a07e64b7ec10f64240c91f0d319f485c 4e1ebede695c7ee95e4442814a5d98539df2ba46757b95d8ba4f0e0e437bb535 -880500 b72623a454e91149046f522d60935871a1e5f098389d9cad4086119732b5e3f6 580082c91f04822d21265dcbbf8c3d3a0866171acf5564e982c8386ae5a3a40d -881000 b94687f79df272c2c5e85e21bff01136c5e99576571bbb8a635353aa9b331c81 8f383eea1f9a3014c27cc3c0a6196b0764c269a1f2f3effd31f4f6b76d2a33a7 -881500 5ed1eceeaeebe16a0c746f796507f6b0dde6da8c53f4e3502cf5a49f4ecdff18 901bbb467df17a499475e767cf7886763681deebd4bbb537a4bfc7f3dfb89774 -882000 bf12ffa015864c59f04c80d0141643c9de99f79b79c2b26ddf9bc398b9d8bf32 2b7b77da53ad2a19f61e3aa54ab5833bef79cb88700e51189ce7b1ecf001a2bc -882500 c8e8deff1d81c65f2b607cde0312982b03523aa76c6562c666c1dddf223e7432 ee0cfaf5a0a284a4e324c4725bc6ed5499cec94d170baff0b955ad6b2a2eb487 -883000 b12011d25c4c08da00b5acef266ab9e451d06c2fe9c65e4f149f7f0bc32b9c44 9b06de94a84c8e550c49947303d058d4a93d898970d50b8be9cea965ca656575 -883500 77b6c306c2410ce6e03c825d016aafeeaea3daa7172111085ebcc5806dcd3bd9 01d7719a498afa8051f872a3e8fc32cda3eba0e4151fc16722c0944d8715a6ee -884000 1fe3f4911ede2f37d7587640a80408092c044904f44900ce1bc41df2e0f887fa 8e9b706cdcdc53e77915c281b532f0589c649a80fb563bcedfa8fea8493d4a67 -884500 22d008aa6022144cf5b7070e91a056b437f105ee9ee3d343c2e1eb485afc55e5 90404898817c93e64a98b4919df62ae8a21e4dcc9bff13fb563a33d544b9a09b -885000 0d39372bb9bdadcd80ce022e52792bd5097a8235cc9a571cffa92805b0d875b5 92306cc62db985c495b43e84e2c4ee4c6310035952d4d52e4a13cbd1af0311b0 diff --git a/confs/BTCD_peers.txt b/confs/BTCD_peers.txt deleted file mode 100644 index 69592171a..000000000 --- a/confs/BTCD_peers.txt +++ /dev/null @@ -1,57 +0,0 @@ -5.9.102.210 -89.248.160.237 -89.248.160.238 -89.248.160.239 -89.248.160.240 -89.248.160.241 -89.248.160.242 -89.248.160.243 -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 diff --git a/confs/BTC_hdrs.txt b/confs/BTC_hdrs.txt deleted file mode 100644 index 374f793ec..000000000 --- a/confs/BTC_hdrs.txt +++ /dev/null @@ -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 diff --git a/confs/BTC_peers.txt b/confs/BTC_peers.txt deleted file mode 100644 index abb52b839..000000000 --- a/confs/BTC_peers.txt +++ /dev/null @@ -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 diff --git a/crypto777/Makefile b/crypto777/Makefile old mode 100644 new mode 100755 diff --git a/crypto777/OS_nonportable.c b/crypto777/OS_nonportable.c index 42cabd876..4c2d3f5c1 100755 --- a/crypto777/OS_nonportable.c +++ b/crypto777/OS_nonportable.c @@ -16,6 +16,7 @@ #include "OS_portable.h" + #ifdef __PNACL int32_t OS_nonportable_syncmap(struct OS_mappedptr *mp,long len) { @@ -34,11 +35,10 @@ void *OS_nonportable_tmpalloc(char *dirname,char *name,struct OS_memspace *mem,l #include #include #include -#include +//#include #include -#include -#include -#include +//#include +//#include #include /* _O_BINARY */ #include #include @@ -47,9 +47,6 @@ void *OS_nonportable_tmpalloc(char *dirname,char *name,struct OS_memspace *mem,l #include #include -#include -#include -#include #include "../win/mman.h" diff --git a/crypto777/OS_portable.c b/crypto777/OS_portable.c index 5c3d879bc..96cc5c371 100755 --- a/crypto777/OS_portable.c +++ b/crypto777/OS_portable.c @@ -14,7 +14,7 @@ ******************************************************************************/ #include "OS_portable.h" -#include +//#include #ifndef MAP_FILE #define MAP_FILE 0 #endif @@ -77,6 +77,19 @@ char *OS_portable_path(char *str) char *OS_nonportable_path(char *str); return(OS_nonportable_path(str)); #else +#ifdef __PNACL + /*int32_t i,n; + if ( str[0] == '/' ) + return(str); + else + { + n = (int32_t)strlen(str); + for (i=n; i>0; i--) + str[i] = str[i-1]; + str[0] = '/'; + str[n+1] = 0; + }*/ +#endif return(str); #endif } @@ -109,6 +122,43 @@ int32_t OS_portable_removefile(char *fname) #else return(remove(fname)); #endif + return(-1); +} + +int32_t OS_portable_rmdir(char *dirname,int32_t diralso) +{ + char cmdstr[1024],tmp[512]; int32_t i; + strcpy(tmp,dirname); + OS_portable_path(tmp); +#ifdef _WIN32 + sprintf(cmdstr,"del %s\*.*",tmp); + if ( system(cmdstr) != 0 ) + printf("error deleting dir.(%s)\n",cmdstr); + else return(1); +#else + if ( diralso != 0 ) + { + sprintf(cmdstr,"rm -rf %s",tmp); + if ( system(cmdstr) != 0 ) + printf("error deleting dir.(%s)\n",cmdstr); + sprintf(cmdstr,"mkdir %s",tmp); + if ( system(cmdstr) != 0 ) + printf("error deleting dir.(%s)\n",cmdstr); + } + else + { + for (i=0; i<=16; i++) + { + if ( i < 16 ) + sprintf(cmdstr,"rm %s/%c*",tmp,i<10?'0'+i:'a'-10+i); + else sprintf(cmdstr,"rm %s/*",tmp); + if ( system(cmdstr) != 0 ) + printf("error deleting dir.(%s)\n",cmdstr); + } + } + return(0); +#endif + return(-1); } void *OS_portable_mapfile(char *fname,long *filesizep,int32_t enablewrite) @@ -148,7 +198,7 @@ void *OS_portable_mapfile(char *fname,long *filesizep,int32_t enablewrite) return(0); } *filesizep = filesize; - //printf("mapped %ld -> %p\n",(long)filesize,ptr); + //printf("mapped rw.%d %ld -> %s\n",enablewrite,(long)filesize,fname); return(ptr); #endif } diff --git a/crypto777/OS_portable.h b/crypto777/OS_portable.h index 7bbb0621d..6e51a5b9f 100755 --- a/crypto777/OS_portable.h +++ b/crypto777/OS_portable.h @@ -27,20 +27,26 @@ #include #include #include -#include +#include #ifdef __MINGW #define sleep(x) Sleep(1000*(x)) #include "../win/mingw.h" #include "../win/mman.h" +//#define EADDRINUSE WSAEADDRINUSE + #else +//#include +#include #include #include #include -#include +//#include +//#include "in.h" #include #include +//#include #define closesocket close #endif #ifndef MIN @@ -58,6 +64,11 @@ #define MAP_FILE 0 #endif +//#define fopen myfopen +//#define fclose myfclose +//FILE *myfopen(char *fname,char *mode); +//int32_t myfclose(FILE *fp); + struct huffstream { uint8_t *ptr,*buf; uint32_t bitoffset,maski,endpos; uint32_t allocsize:31,allocated:1; }; typedef struct huffstream HUFF; @@ -138,7 +149,7 @@ struct taidate { int32_t year,month,day; }; struct taitime { struct taidate date; int32_t hour,minute,second; uint32_t offset; double millis; }; int32_t leapsecs_sub(struct tai *); -struct tai tai_now(); +struct tai tai_now(void); uint32_t tai2utc(struct tai t); struct taidate taidate_frommjd(int32_t day,int32_t *pwday,int32_t *pyday); struct taitime tai2time(struct tai t,int32_t *pwday,int32_t *pyday); @@ -174,6 +185,7 @@ double OS_portable_milliseconds(); void OS_portable_randombytes(unsigned char *x,long xlen); int32_t OS_portable_truncate(char *fname,long filesize); char *OS_portable_path(char *str); +void OS_remove_directory(char *dirname); int32_t OS_portable_renamefile(char *fname,char *newfname); int32_t OS_portable_removefile(char *fname); void *OS_portable_mapfile(char *fname,long *filesizep,int32_t enablewrite); @@ -197,7 +209,7 @@ char *OS_compatible_path(char *str); int32_t OS_renamefile(char *fname,char *newfname); int32_t OS_removefile(char *fname,int32_t scrubflag); void OS_ensure_directory(char *dirname); -uint64_t OS_filesize(char *fname); +int64_t OS_filesize(char *fname); int32_t OS_compare_files(char *fname,char *fname2); int64_t OS_copyfile(char *src,char *dest,int32_t cmpflag); int32_t OS_releasemap(void *ptr,uint64_t filesize); @@ -355,6 +367,8 @@ bits256 bits256_lshift(bits256 x); bits256 bits256_from_compact(uint32_t c); bits256 bits256_conv(char *hexstr); int32_t btc_priv2pub(uint8_t pubkey[33],uint8_t privkey[32]); +void calc_shares(unsigned char *shares,unsigned char *secret,int32_t size,int32_t width,int32_t M,int32_t N,unsigned char *sharenrs); +int32_t OS_portable_rmdir(char *dirname,int32_t diralso); extern char *Iguana_validcommands[]; extern bits256 GENESIS_PUBKEY,GENESIS_PRIVKEY; diff --git a/crypto777/OS_time.c b/crypto777/OS_time.c index 927f640b2..d65f54350 100755 --- a/crypto777/OS_time.c +++ b/crypto777/OS_time.c @@ -31,6 +31,8 @@ uint32_t First_utc; int32_t UTC_ADJUST; #ifdef _WIN32 + + struct tm *gmtime_r(const time_t *timep,struct tm *result) { struct tm *p = gmtime(timep); @@ -47,7 +49,7 @@ struct tm *_gmtime32(const time_t *timep,struct tm *result) { return(gmtime_r(ti time_t _time32(struct tm *tm) { return(time(NULL)); } time_t _localtime32(struct tm *tm) { return(time(NULL)); } -#include +#include #include // portable: uint64_t MSVC: __int64 // MSVC defines this in winsock2.h!? diff --git a/crypto777/bitcoind_RPC.c b/crypto777/bitcoind_RPC.c index d3e69d614..98f58999f 100755 --- a/crypto777/bitcoind_RPC.c +++ b/crypto777/bitcoind_RPC.c @@ -14,12 +14,22 @@ ******************************************************************************/ #include "OS_portable.h" -#include "../includes/cJSON.h" +//#define USE_CURL +#ifdef USE_CURL +#ifdef _WIN32 +#include +#include +#else #include #include +#endif // return data from the server +#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32) +#define CURL_GLOBAL_SSL (1<<0) +#define CURL_GLOBAL_WIN32 (1<<1) + struct return_string { char *ptr; size_t len; @@ -49,7 +59,7 @@ char *post_process_bitcoind_RPC(char *debugstr,char *command,char *rpcstr,char * long i,j,len; char *retstr = 0; cJSON *json,*result,*error; - printf("<<<<<<<<<<< bitcoind_RPC: %s post_process_bitcoind_RPC.%s.[%s]\n",debugstr,command,rpcstr); + //printf("<<<<<<<<<<< bitcoind_RPC: %s post_process_bitcoind_RPC.%s.[%s]\n",debugstr,command,rpcstr); if ( command == 0 || rpcstr == 0 || rpcstr[0] == 0 ) { printf("<<<<<<<<<<< bitcoind_RPC: %s post_process_bitcoind_RPC.%s.[%s]\n",debugstr,command,rpcstr); @@ -189,7 +199,7 @@ try_again: free(s.ptr); return(0); } - else if ( numretries >= 1 ) + else if ( numretries >= 2 ) { printf("Maximum number of retries exceeded!\n"); free(s.ptr); @@ -340,3 +350,15 @@ void curlhandle_free(void *curlhandle) { curl_easy_cleanup(curlhandle); } + +#else +char *bitcoind_RPC(char **retstrp,char *debugstr,char *url,char *userpass,char *command,char *params) +{ + return(clonestr("{\"error\":\"curl is disabled\"}")); +} + +void *curl_post(void **cHandlep,char *url,char *userpass,char *postfields,char *hdr0,char *hdr1,char *hdr2,char *hdr3) +{ + return(clonestr("{\"error\":\"curl is disabled\"}")); +} +#endif diff --git a/crypto777/cJSON.c b/crypto777/cJSON.c index e29e0e3f3..a1d78f8fd 100755 --- a/crypto777/cJSON.c +++ b/crypto777/cJSON.c @@ -26,9 +26,10 @@ #include #include "../includes/cJSON.h" -//#define DEFINES_ONLY -//#include "../common/system777.c" -//#undef DEFINES_ONLY + +#ifndef DBL_EPSILON +#define DBL_EPSILON 2.2204460492503131E-16 +#endif static const char *ep; @@ -129,8 +130,8 @@ static char *print_number(cJSON *item) { char *str; double d = item->valuedouble; - if ( fabs(((double)item->valueint) - d) <= DBL_EPSILON && d >= (1. - DBL_EPSILON) && d < (1LL << 62) )//d <= INT_MAX && d >= INT_MIN ) - { + if ( fabs(((double)item->valueint) - d) <= DBL_EPSILON && d >= (1. - DBL_EPSILON) && d < (1LL << 62) )//d <= INT_MAX && d >= INT_MIN ) + { str = (char *)cJSON_malloc(24); /* 2^64+1 can be represented in 21 chars + sign. */ if ( str != 0 ) sprintf(str,"%lld",(long long)item->valueint); @@ -467,10 +468,20 @@ static char *print_object(cJSON *item,int32_t depth,int32_t fmt) { char **entries=0,**names=0; char *out=0,*ptr,*ret,*str;int32_t len=7,i=0,j; - cJSON *child=item->child; + cJSON *child=item->child,*firstchild; int32_t numentries=0,fail=0; - /* Count the number of entries. */ - while (child) numentries++,child=child->next; + // Count the number of entries + firstchild = child; + while ( child ) + { + numentries++; + child = child->next; + if ( child == firstchild ) + { + printf("cJSON infinite loop detected\n"); + break; + } + } /* Explicitly handle empty object case */ if (!numentries) { @@ -491,12 +502,14 @@ static char *print_object(cJSON *item,int32_t depth,int32_t fmt) /* Collect all the results into our arrays: */ child=item->child;depth++;if (fmt) len+=depth; - while (child) + while ( child ) { names[i]=str=print_string_ptr(child->string); entries[i++]=ret=print_value(child,depth,fmt); if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1; child=child->next; + if ( child == firstchild ) + break; } /* Try to allocate the output string */ @@ -944,6 +957,7 @@ double get_API_float(cJSON *obj) } return(val); } + double jdouble(cJSON *json,char *field) { if ( json != 0 ) diff --git a/crypto777/crypto777.sources b/crypto777/crypto777.sources old mode 100644 new mode 100755 diff --git a/crypto777/hmac/tomcrypt_cfg.h b/crypto777/hmac/tomcrypt_cfg.h index f1e6bc9e3..ac26740a1 100755 --- a/crypto777/hmac/tomcrypt_cfg.h +++ b/crypto777/hmac/tomcrypt_cfg.h @@ -21,6 +21,7 @@ /* certain platforms use macros for these, making the prototypes broken */ #ifndef LTC_NO_PROTOTYPES +#include /* you can change how memory allocation works ... */ LTC_EXPORT void * LTC_CALL XMALLOC(size_t n); diff --git a/crypto777/i b/crypto777/i new file mode 100755 index 000000000..efcd388ca --- /dev/null +++ b/crypto777/i @@ -0,0 +1 @@ +cd ../iguana; ./m_unix; cd ../crypto777; ar rcu ../../bitcoinclassic/src/libiguana.a *.o ../iguana/*.o diff --git a/crypto777/iguana_OS.c b/crypto777/iguana_OS.c index 438ba3386..8c49ccdfa 100755 --- a/crypto777/iguana_OS.c +++ b/crypto777/iguana_OS.c @@ -81,8 +81,8 @@ long myallocated(uint8_t type,long change) Total_allocated += change; if ( Total_allocated > HWM_allocated ) { - printf("HWM allocated %ld %s\n",(long)Total_allocated,mbstr(str,Total_allocated)); HWM_allocated = Total_allocated * 1.5; + printf("HWM allocated %ld %s\n",(long)Total_allocated,mbstr(str,Total_allocated)); } } return(total); @@ -149,6 +149,8 @@ void _myfree(uint8_t type,int32_t origallocsize,void *origptr,int32_t allocsize) else { printf("myfree size error %d vs %d at %p\n",allocsize,origallocsize,origptr); + static int32_t y,z; + printf("div by zero! %d\n",y/z); getchar(); } //portable_mutex_unlock(&MEMmutex); @@ -234,6 +236,7 @@ void queue_enqueue(char *name,queue_t *queue,struct queueitem *origitem,int32_t printf("FATAL type error: queueing empty value\n");//, getchar(); return; } + //fprintf(stderr,"enqueue.(%s) %p offset.%d\n",queue->name,origitem,offsetflag); lock_queue(queue); item = (struct queueitem *)((long)origitem - offsetflag*sizeof(struct queueitem)); DL_APPEND(queue->list,item); @@ -248,8 +251,8 @@ void *queue_dequeue(queue_t *queue,int32_t offsetflag) if ( queue->list != 0 ) { item = queue->list; - DL_DELETE(queue->list,item); //printf("queue_dequeue name.(%s) dequeue.%p list.%p\n",queue->name,item,queue->list); + DL_DELETE(queue->list,item); } portable_mutex_unlock(&queue->mutex); if ( item != 0 && offsetflag != 0 ) @@ -403,6 +406,8 @@ int64_t iguana_memallocated(struct OS_memspace *mem) void *iguana_memalloc(struct OS_memspace *mem,long size,int32_t clearflag) { int32_t modval; void *ptr = 0; + if ( mem->ptr == 0 ) + return(0); //printf("iguana_memalloc.%s size.%ld used.%llu of %llu, numptrs.%d avail.%d %lld\n",mem->name,size,(long long)mem->used,(long long)mem->totalsize,mem->numptrs,mem->availptrs,(long long)iguana_memallocated(mem)); //if ( mem->threadsafe != 0 ) // portable_mutex_lock(&mem->mutex); @@ -434,7 +439,12 @@ void *iguana_memalloc(struct OS_memspace *mem,long size,int32_t clearflag) } #endif //printf(">>>>>>>>> USED.%s alloc %ld used %ld alloc.%ld -> %s %p\n",mem->name,size,(long)mem->used,(long)mem->totalsize,mem->name,ptr); - } else printf("error memalloc mem.%p %s alloc %ld used %ld totalsize.%ld -> %s %p\n",mem,mem->name,size,(long)mem->used,(long)mem->totalsize,mem->name,ptr), getchar();//exit(-1); + } + else + { + printf("error memalloc mem.%p (%s) alloc %ld used %ld totalsize.%ld -> %s %p\n",mem,mem->name,size,(long)mem->used,(long)mem->totalsize,mem->name,ptr); + ptr = calloc(1,size); + } //if ( mem->threadsafe != 0 ) // portable_mutex_unlock(&mem->mutex); return(ptr); @@ -512,10 +522,33 @@ int32_t OS_removefile(char *fname,int32_t scrubflag) return(0); } +void OS_remove_directory(char *dirname) +{ + FILE *fp; char buf[1024]; + sprintf(buf,"%s/.tmpmarker",dirname); + if ( (fp= fopen(OS_compatible_path(buf),"rb")) != 0 ) + OS_removefile(buf,0); + else fclose(fp); + sprintf(buf,"rmdir %s",dirname); + if ( system(buf) != 0 ) + { + //printf("error doing (%s)\n",buf); + sprintf(buf,"rm %s/*",dirname); + if ( system(buf) != 0 ) + printf("error doing (%s)\n",buf); + else + { + sprintf(buf,"rmdir %s",dirname); + if ( system(buf) != 0 ) + printf("second error doing (%s)\n",buf); + } + } +} + void OS_ensure_directory(char *dirname) { FILE *fp; int32_t retval; char fname[512]; - if ( OS_removefile(dirname,0) < 0 ) + if ( 0 && OS_removefile(dirname,0) < 0 ) { sprintf(fname,"tmp/%d",rand()); OS_renamefile(dirname,fname); @@ -530,15 +563,15 @@ void OS_ensure_directory(char *dirname) ,511 #endif ); - printf("mkdir.(%s) retval.%d errno.%d %s\n",dirname,retval,errno,strerror(errno)); - } else fclose(fp), printf("dirname.(%s) exists\n",dirname); + //printf("mkdir.(%s) retval.%d errno.%d %s\n",dirname,retval,errno,strerror(errno)); + } else fclose(fp);//, printf("dirname.(%s) exists\n",dirname); if ( (fp= fopen(fname,"wb")) != 0 ) - fclose(fp), printf("created.(%s)\n",fname); + fclose(fp);//, printf("created.(%s)\n",fname); else printf("cant create.(%s) errno.%d %s\n",fname,errno,strerror(errno)); - } else fclose(fp), printf("%s exists\n",fname); + } else fclose(fp);//, printf("%s exists\n",fname); } -uint64_t OS_filesize(char *fname) +int64_t OS_filesize(char *fname) { FILE *fp; uint64_t fsize = 0; if ( (fp= fopen(fname,"rb")) != 0 ) diff --git a/crypto777/iguana_serdes.c b/crypto777/iguana_serdes.c index 03a9c8e09..f8430ea2e 100755 --- a/crypto777/iguana_serdes.c +++ b/crypto777/iguana_serdes.c @@ -52,24 +52,6 @@ int32_t iguana_rwnum(int32_t rwflag,uint8_t *serialized,int32_t len,void *endian return(len); } -int32_t iguana_validatehdr(char *symbol,struct iguana_msghdr *H) -{ - 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) { int32_t i; @@ -92,15 +74,16 @@ int32_t iguana_sethdr(struct iguana_msghdr *H,const uint8_t netmagic[4],char *co memset(H,0,sizeof(*H)); memcpy(H->netmagic,netmagic,4); strncpy(H->command,command,12); + if ( datalen < 0 || datalen > IGUANA_MAXPACKETSIZE ) + return(-1); iguana_rwnum(1,H->serdatalen,sizeof(int32_t),&datalen); - if ( data != 0 && datalen != 0 ) + if ( data != 0 ) { hash2 = bits256_doublesha256(0,data,datalen); iguana_rwbignum(1,tmp.bytes,sizeof(tmp),hash2.bytes); for (i=0; i<4; i++) H->hash[i] = tmp.bytes[i]; - } - else H->hash[0] = 0x5d, H->hash[1] = 0xf6, H->hash[2] = 0xe0, H->hash[3] = 0xe2; + } else H->hash[0] = 0x5d, H->hash[1] = 0xf6, H->hash[2] = 0xe0, H->hash[3] = 0xe2; return(datalen + sizeof(*H)); } @@ -170,19 +153,19 @@ int32_t iguana_rwvarint(int32_t rwflag,uint8_t *serialized,uint64_t *varint64p) n = *varint64p; if ( n < 0xfd ) *serialized++ = (uint8_t)n; - else if ( n == 0xfd ) + else if ( n <= 0xffff ) { *serialized++ = 0xfd; iguana_varint16(rwflag,serialized,(uint16_t *)varint64p); vlen += 2; } - else if ( n == 0xfe ) + else if ( n <= 0xffffffff ) { *serialized++ = 0xfe; iguana_varint32(rwflag,serialized,(uint16_t *)varint64p); vlen += 4; } - else if ( n == 0xff ) + else { *serialized++ = 0xff; iguana_varint64(rwflag,serialized,(uint32_t *)varint64p); diff --git a/crypto777/iguana_utils.c b/crypto777/iguana_utils.c index 4729b4781..5e9634294 100755 --- a/crypto777/iguana_utils.c +++ b/crypto777/iguana_utils.c @@ -133,9 +133,9 @@ int32_t bitweight(uint64_t x) return(wt); } -void calc_OP_HASH160(char hexstr[41],uint8_t hash160[20],char *pubkey) +void calc_OP_HASH160(char hexstr[41],uint8_t rmd160[20],char *pubkey) { - uint8_t sha256[32],buf[4096]; int32_t len; + uint8_t buf[4096]; int32_t len; len = (int32_t)strlen(pubkey)/2; if ( len > sizeof(buf) ) { @@ -143,17 +143,16 @@ void calc_OP_HASH160(char hexstr[41],uint8_t hash160[20],char *pubkey) return; } decode_hex(buf,len,pubkey); - vcalc_sha256(0,sha256,buf,len); - calc_rmd160(0,hash160,sha256,sizeof(sha256)); + calc_rmd160_sha256(rmd160,buf,len); if ( 0 ) { int i; for (i=0; i<20; i++) - printf("%02x",hash160[i]); + printf("%02x",rmd160[i]); printf("<- (%s)\n",pubkey); } if ( hexstr != 0 ) - init_hexbytes_noT(hexstr,hash160,20); + init_hexbytes_noT(hexstr,rmd160,20); } double _dxblend(double *destp,double val,double decay) @@ -191,8 +190,8 @@ double dxblend(double *destp,double val,double decay) return(slope); } -/*queue_t TerminateQ; int32_t TerminateQ_queued; -void iguana_terminator(void *arg) +int32_t TerminateQ_queued; queue_t TerminateQ; +/*void iguana_terminator(void *arg) { struct iguana_thread *t; uint32_t lastdisp = 0; int32_t terminated = 0; printf("iguana_terminator\n"); @@ -229,11 +228,12 @@ void iguana_launcher(void *ptr) struct iguana_thread *t = ptr; struct iguana_info *coin; coin = t->coin; t->funcp(t->arg); - coin->Terminated[t->type % (sizeof(coin->Terminated)/sizeof(*coin->Terminated))]++; - queue_enqueue("TerminateQ",&coin->TerminateQ,&t->DL,0); + if ( coin != 0 ) + coin->Terminated[t->type % (sizeof(coin->Terminated)/sizeof(*coin->Terminated))]++; + queue_enqueue("TerminateQ",&TerminateQ,&t->DL,0); } -void iguana_terminate(struct iguana_info *coin,struct iguana_thread *t) +void iguana_terminate(struct iguana_thread *t) { int32_t retval; retval = pthread_join(t->handle,NULL); @@ -251,15 +251,16 @@ struct iguana_thread *iguana_launch(struct iguana_info *coin,char *name,iguana_f t->funcp = funcp; t->arg = arg; t->type = (type % (sizeof(coin->Terminated)/sizeof(*coin->Terminated))); - coin->Launched[t->type]++; + if ( coin != 0 ) + coin->Launched[t->type]++; retval = OS_thread_create(&t->handle,NULL,(void *)iguana_launcher,(void *)t); if ( retval != 0 ) printf("error launching %s\n",t->name); - while ( (t= queue_dequeue(&coin->TerminateQ,0)) != 0 ) + while ( (t= queue_dequeue(&TerminateQ,0)) != 0 ) { - if ( (rand() % 100000) == 0 ) + if ( (rand() % 100000) == 0 && coin != 0 ) printf("terminated.%d launched.%d terminate.%p\n",coin->Terminated[t->type],coin->Launched[t->type],t); - iguana_terminate(coin,t); + iguana_terminate(t); } return(t); } @@ -290,10 +291,18 @@ int32_t is_hexstr(char *str,int32_t n) int32_t i; if ( str == 0 || str[0] == 0 ) return(0); - for (i=0; str[i]!=0&&(i 0 && i >= n ) + break; if ( _unhex(str[i]) < 0 ) + { + if ( n == 0 ) + return(i); return(0); - return(1); + } + } + return(n); } int32_t unhex(char c) @@ -324,9 +333,6 @@ int32_t decode_hex(unsigned char *bytes,int32_t n,char *hex) bytes[0] = unhex(hex[0]); printf("decode_hex n.%d hex[0] (%c) -> %d hex.(%s) [n*2+1: %d] [n*2: %d %c] len.%ld\n",n,hex[0],bytes[0],hex,hex[n*2+1],hex[n*2],hex[n*2],(long)strlen(hex)); } -#ifdef __APPLE__ - getchar(); -#endif bytes++; hex++; adjust = 1; @@ -343,7 +349,7 @@ int32_t decode_hex(unsigned char *bytes,int32_t n,char *hex) int32_t init_hexbytes_noT(char *hexbytes,unsigned char *message,long len) { int32_t i; - if ( len == 0 ) + if ( len <= 0 ) { hexbytes[0] = 0; return(1); @@ -394,10 +400,10 @@ char *clonestr(char *str) int32_t safecopy(char *dest,char *src,long len) { int32_t i = -1; - if ( dest != 0 ) - memset(dest,0,len); - if ( src != 0 && dest != 0 ) + if ( src != 0 && dest != 0 && src != dest ) { + if ( dest != 0 ) + memset(dest,0,len); for (i=0; i 0 ) + { + decode_hex((uint8_t *)hexstr,len/2,(char *)msg); + vcalc_sha256(0,sha256,(void *)hexstr,len/2); + calc_rmd160(hexstr,buf,sha256,sizeof(sha256)); + } else vcalc_sha256(0,sha256,(void *)msg,len); calc_rmd160(hexstr,buf,sha256,sizeof(sha256)); } @@ -1059,3 +1070,10 @@ void calc_curve25519_str(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len) x = curve25519(priv,curve25519_basepoint9()); init_hexbytes_noT(hexstr,x.bytes,sizeof(x)); } + +void calc_rmd160_sha256(uint8_t rmd160[20],uint8_t *data,int32_t datalen) +{ + bits256 hash; + vcalc_sha256(0,hash.bytes,data,datalen); + calc_rmd160(0,rmd160,hash.bytes,sizeof(hash)); +} diff --git a/crypto777/inet.c b/crypto777/inet.c index 6c94b2b54..4ca687a67 100755 --- a/crypto777/inet.c +++ b/crypto777/inet.c @@ -19,12 +19,8 @@ #ifndef crypto777_inet_h #define crypto777_inet_h #include "OS_portable.h" -#include #ifdef _WIN32 -#include -#include -#include #define in6_addr sockaddr #define in_addr_t struct sockaddr_storage #define EAFNOSUPPORT WSAEAFNOSUPPORT @@ -37,7 +33,12 @@ struct sockaddr_in6 { u_long sin6_scope_id; }; #endif - +#ifdef _WIN32 +#ifdef AF_INET6 +#undef AF_INET6 +#endif +#define AF_INET6 23 +#endif static int inet_ntop4(unsigned char *src, char *dst, size_t size); static int inet_ntop6(unsigned char *src, char *dst, size_t size); static int inet_pton4(char *src, unsigned char *dst); @@ -225,13 +226,13 @@ static int inet_pton4(char *src, unsigned char *dst) { saw_digit = 0; } else { - printf("inet_pton4 4 error.(%s)\n",savestr); getchar(); + printf("inet_pton4 4 error.(%s)\n",savestr); //getchar(); return EINVAL; } } if (octets < 4) { - printf("inet_pton4 5 error.(%s)\n",savestr); getchar(); + printf("inet_pton4 5 error.(%s)\n",savestr); //getchar(); return EINVAL; } memcpy(dst, tmp, sizeof(struct in_addr)); @@ -388,13 +389,25 @@ void expand_ipbits(char *ipaddr,uint64_t ipbits) uint64_t calc_ipbits(char *ip_port) { - uint64_t ipbits = 0; char ipaddr[64]; + uint64_t ipbits = 0; char ipaddr[64],ipaddr2[64]; int32_t i; if ( ip_port != 0 ) { ipbits = _calc_ipbits(ip_port); expand_ipbits(ipaddr,ipbits); if ( ipbits != 0 && strcmp(ipaddr,ip_port) != 0 ) - printf("calc_ipbits error: (%s) -> %llx -> (%s)\n",ip_port,(long long)ipbits,ipaddr);//, getchar(); + { + for (i=0; i<63; i++) + if ( (ipaddr[i]= ip_port[i]) == ':' || ipaddr[i] == 0 ) + break; + ipaddr[i] = 0; + ipbits = _calc_ipbits(ipaddr); + expand_ipbits(ipaddr2,ipbits); + if ( ipbits != 0 && strcmp(ipaddr,ipaddr2) != 0 ) + { + printf("calc_ipbits error: (%s) -> %llx -> (%s)\n",ip_port,(long long)ipbits,ipaddr);//, getchar(); + ipbits = 0; + } + } } return(ipbits); } diff --git a/crypto777/jpeg/Makefile b/crypto777/jpeg/Makefile old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/cderror.h b/crypto777/jpeg/cderror.h old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/cdjpeg.h b/crypto777/jpeg/cdjpeg.h old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jaricom.c b/crypto777/jpeg/jaricom.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jcapimin.c b/crypto777/jpeg/jcapimin.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jcapistd.c b/crypto777/jpeg/jcapistd.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jcarith.c b/crypto777/jpeg/jcarith.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jccoefct.c b/crypto777/jpeg/jccoefct.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jccolor.c b/crypto777/jpeg/jccolor.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jcdctmgr.c b/crypto777/jpeg/jcdctmgr.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jchuff.c b/crypto777/jpeg/jchuff.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jcinit.c b/crypto777/jpeg/jcinit.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jcmainct.c b/crypto777/jpeg/jcmainct.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jcmarker.c b/crypto777/jpeg/jcmarker.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jcmaster.c b/crypto777/jpeg/jcmaster.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jcomapi.c b/crypto777/jpeg/jcomapi.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jconfig.h b/crypto777/jpeg/jconfig.h old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jcparam.c b/crypto777/jpeg/jcparam.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jcprepct.c b/crypto777/jpeg/jcprepct.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jcsample.c b/crypto777/jpeg/jcsample.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jctrans.c b/crypto777/jpeg/jctrans.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jdapimin.c b/crypto777/jpeg/jdapimin.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jdapistd.c b/crypto777/jpeg/jdapistd.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jdarith.c b/crypto777/jpeg/jdarith.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jdatadst.c b/crypto777/jpeg/jdatadst.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jdatasrc.c b/crypto777/jpeg/jdatasrc.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jdcoefct.c b/crypto777/jpeg/jdcoefct.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jdcolor.c b/crypto777/jpeg/jdcolor.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jdct.h b/crypto777/jpeg/jdct.h old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jddctmgr.c b/crypto777/jpeg/jddctmgr.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jdhuff.c b/crypto777/jpeg/jdhuff.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jdinput.c b/crypto777/jpeg/jdinput.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jdmainct.c b/crypto777/jpeg/jdmainct.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jdmarker.c b/crypto777/jpeg/jdmarker.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jdmaster.c b/crypto777/jpeg/jdmaster.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jdmerge.c b/crypto777/jpeg/jdmerge.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jdpostct.c b/crypto777/jpeg/jdpostct.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jdsample.c b/crypto777/jpeg/jdsample.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jdtrans.c b/crypto777/jpeg/jdtrans.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jerror.c b/crypto777/jpeg/jerror.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jerror.h b/crypto777/jpeg/jerror.h old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jfdctflt.c b/crypto777/jpeg/jfdctflt.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jfdctfst.c b/crypto777/jpeg/jfdctfst.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jfdctint.c b/crypto777/jpeg/jfdctint.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jidctflt.c b/crypto777/jpeg/jidctflt.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jidctfst.c b/crypto777/jpeg/jidctfst.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jidctint.c b/crypto777/jpeg/jidctint.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jinclude.h b/crypto777/jpeg/jinclude.h old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jmemansi.c b/crypto777/jpeg/jmemansi.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jmemmgr.c b/crypto777/jpeg/jmemmgr.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jmemnobs.c b/crypto777/jpeg/jmemnobs.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jmemsys.h b/crypto777/jpeg/jmemsys.h old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jmorecfg.h b/crypto777/jpeg/jmorecfg.h old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jpegint.h b/crypto777/jpeg/jpegint.h old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jpeglib.h b/crypto777/jpeg/jpeglib.h old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jpegtran.c b/crypto777/jpeg/jpegtran.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jquant1.c b/crypto777/jpeg/jquant1.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jquant2.c b/crypto777/jpeg/jquant2.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jutils.c b/crypto777/jpeg/jutils.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jversion.h b/crypto777/jpeg/jversion.h old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/ansi2knr.c b/crypto777/jpeg/misc/ansi2knr.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/cdjpeg.c b/crypto777/jpeg/misc/cdjpeg.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/cjpeg.c b/crypto777/jpeg/misc/cjpeg.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/ckconfig.c b/crypto777/jpeg/misc/ckconfig.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/djpeg.c b/crypto777/jpeg/misc/djpeg.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/example.c b/crypto777/jpeg/misc/example.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/rdbmp.c b/crypto777/jpeg/misc/rdbmp.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/rdcolmap.c b/crypto777/jpeg/misc/rdcolmap.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/rdgif.c b/crypto777/jpeg/misc/rdgif.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/rdjpgcom.c b/crypto777/jpeg/misc/rdjpgcom.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/rdppm.c b/crypto777/jpeg/misc/rdppm.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/rdrle.c b/crypto777/jpeg/misc/rdrle.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/rdswitch.c b/crypto777/jpeg/misc/rdswitch.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/rdtarga.c b/crypto777/jpeg/misc/rdtarga.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/test.c b/crypto777/jpeg/misc/test.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/transupp.c b/crypto777/jpeg/misc/transupp.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/wrbmp.c b/crypto777/jpeg/misc/wrbmp.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/wrgif.c b/crypto777/jpeg/misc/wrgif.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/wrjpgcom.c b/crypto777/jpeg/misc/wrjpgcom.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/wrppm.c b/crypto777/jpeg/misc/wrppm.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/wrrle.c b/crypto777/jpeg/misc/wrrle.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/wrtarga.c b/crypto777/jpeg/misc/wrtarga.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/osx/jmemmac.c b/crypto777/jpeg/osx/jmemmac.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/transupp.h b/crypto777/jpeg/transupp.h old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/unix/jmemname.c b/crypto777/jpeg/unix/jmemname.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/win/jmemdos.c b/crypto777/jpeg/win/jmemdos.c old mode 100644 new mode 100755 diff --git a/crypto777/libgfshare.c b/crypto777/libgfshare.c index 4f2ea6df3..c6bf43e06 100755 --- a/crypto777/libgfshare.c +++ b/crypto777/libgfshare.c @@ -39,10 +39,10 @@ struct _gfshare_ctx { uint32_t sharecount,threshold,size,buffersize; - unsigned char sharenrs[255],buffer[]; + uint8_t sharenrs[255],buffer[]; }; -unsigned char ctx_logs[256] = { +uint8_t ctx_logs[256] = { 0x00, 0x00, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6, 0x03, 0xdf, 0x33, 0xee, 0x1b, 0x68, 0xc7, 0x4b, 0x04, 0x64, 0xe0, 0x0e, 0x34, 0x8d, 0xef, 0x81, @@ -76,7 +76,7 @@ unsigned char ctx_logs[256] = { 0x4f, 0xae, 0xd5, 0xe9, 0xe6, 0xe7, 0xad, 0xe8, 0x74, 0xd6, 0xf4, 0xea, 0xa8, 0x50, 0x58, 0xaf }; -unsigned char ctx_exps[510] = { +uint8_t ctx_exps[510] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1d, 0x3a, 0x74, 0xe8, 0xcd, 0x87, 0x13, 0x26, 0x4c, 0x98, 0x2d, 0x5a, 0xb4, 0x75, 0xea, 0xc9, @@ -142,20 +142,20 @@ unsigned char ctx_exps[510] = { 0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83, 0x1b, 0x36, 0x6c, 0xd8, 0xad, 0x47, 0x8e }; -/*void _gfshare_fill_rand_using_random(unsigned char *buffer,unsigned long long count) +/*void _gfshare_fill_rand_using_random(uint8_t *buffer,unsigned long long count) { uint32_t i; for (i=0; i> 8; // apparently the bottom 8 aren't very random but the middles ones are }*/ -//void randombytes(unsigned char *x,long xlen); +//void randombytes(uint8_t *x,long xlen); //gfshare_rand_func_t gfshare_fill_rand = _gfshare_fill_rand_using_random; -gfshare_rand_func_t gfshare_fill_rand = OS_randombytes; +//gfshare_rand_func_t gfshare_fill_rand = OS_randombytes; // ------------------------------------------------------[ Preparation ]---- -gfshare_ctx *_gfshare_ctx_init_core(unsigned char *sharenrs,uint32_t sharecount,unsigned char threshold,uint32_t size) +gfshare_ctx *_gfshare_ctx_init_core(uint8_t *sharenrs,uint32_t sharecount,uint8_t threshold,uint32_t size) { gfshare_ctx *ctx; ctx = XMALLOC(sizeof(struct _gfshare_ctx) + threshold * size); @@ -170,7 +170,7 @@ gfshare_ctx *_gfshare_ctx_init_core(unsigned char *sharenrs,uint32_t sharecount, } // Initialise a gfshare context for producing shares -gfshare_ctx *gfshare_ctx_init_enc(unsigned char *sharenrs,uint32_t sharecount,unsigned char threshold,uint32_t size) +gfshare_ctx *gfshare_ctx_init_enc(uint8_t *sharenrs,uint32_t sharecount,uint8_t threshold,uint32_t size) { uint32_t i; // can't have x[i] = 0 - that would just be a copy of the secret, in theory @@ -179,6 +179,7 @@ gfshare_ctx *gfshare_ctx_init_enc(unsigned char *sharenrs,uint32_t sharecount,un { if ( sharenrs[i] == 0 ) { + printf("null sharenrs error\n"); errno = EINVAL; return NULL; } @@ -187,7 +188,7 @@ gfshare_ctx *gfshare_ctx_init_enc(unsigned char *sharenrs,uint32_t sharecount,un } // Initialise a gfshare context for recombining shares -gfshare_ctx *gfshare_ctx_init_dec(unsigned char *sharenrs,uint32_t sharecount,uint32_t size) +gfshare_ctx *gfshare_ctx_init_dec(uint8_t *sharenrs,uint32_t sharecount,uint32_t size) { gfshare_ctx *ctx = _gfshare_ctx_init_core(sharenrs,sharecount,sharecount,size); if ( ctx != NULL ) @@ -199,26 +200,28 @@ gfshare_ctx *gfshare_ctx_init_dec(unsigned char *sharenrs,uint32_t sharecount,ui void gfshare_ctx_free(gfshare_ctx *ctx) { long len = sizeof(struct _gfshare_ctx) + ctx->buffersize; - gfshare_fill_rand((unsigned char*)ctx,len); + //gfshare_fill_rand((uint8_t*)ctx,len); + OS_randombytes((uint8_t *)ctx,len); XFREE(ctx); } // --------------------------------------------------------[ Splitting ]---- // Provide a secret to the encoder. (this re-scrambles the coefficients) -void gfshare_ctx_enc_setsecret(gfshare_ctx *ctx,unsigned char *secret) +void gfshare_ctx_enc_setsecret(gfshare_ctx *ctx,uint8_t *secret) { memcpy(ctx->buffer + ((ctx->threshold-1) * ctx->size),secret,ctx->size); - gfshare_fill_rand(ctx->buffer,(ctx->threshold-1) * ctx->size); + //gfshare_fill_rand(ctx->buffer,(ctx->threshold-1) * ctx->size); + OS_randombytes(ctx->buffer,(ctx->threshold-1) * ctx->size); } // Extract a share from the context. 'share' must be preallocated and at least 'size' bytes long. // 'sharenr' is the index into the 'sharenrs' array of the share you want. -void calc_share(unsigned char *buffer,int32_t size,int32_t M,uint32_t ilog,unsigned char *share) +void calc_share(uint8_t *buffer,int32_t size,int32_t M,uint32_t ilog,uint8_t *share) { uint32_t pos,coefficient;//,ilog = ctx_logs[ctx->sharenrs[sharenr]]; - //unsigned char *coefficient_ptr = buffer; - unsigned char *share_ptr,share_byte; + //uint8_t *coefficient_ptr = buffer; + uint8_t *share_ptr,share_byte; for (pos=0; posbuffer,ctx->size,ctx->threshold,ctx_logs[ctx->sharenrs[sharenr]],share); } -void calc_shares(unsigned char *shares,unsigned char *secret,int32_t size,int32_t width,int32_t M,int32_t N,unsigned char *sharenrs) +#ifdef notnow +void calc_shares(uint8_t *shares,uint8_t *secret,int32_t size,int32_t width,int32_t M,int32_t N,uint8_t *sharenrs) { int32_t i; - unsigned char *buffer = calloc(M,width); + uint8_t *buffer = calloc(M,width); memset(shares,0,N*width); memcpy(buffer + ((M - 1) * size),secret,size); - gfshare_fill_rand(buffer,(M - 1) * size); + //gfshare_fill_rand(buffer,(M - 1) * size); + OS_randombytes(buffer,(M - 1) * size); for (i=0; isharenrs,sharenrs,ctx->sharecount); } // Provide a share context with one of the shares. The 'sharenr' is the index into the 'sharenrs' array -void gfshare_ctx_dec_giveshare(gfshare_ctx *ctx,unsigned char sharenr,unsigned char *share) +void gfshare_ctx_dec_giveshare(gfshare_ctx *ctx,uint8_t sharenr,uint8_t *share) { memcpy(ctx->buffer + (sharenr * ctx->size),share,ctx->size); } // Extract the secret by interpolation of the shares. secretbuf must be allocated and at least 'size' bytes long -void gfshare_extract(unsigned char *secretbuf,uint8_t *sharenrs,int32_t N,uint8_t *buffer,int32_t size,int32_t width) +void gfshare_extract(uint8_t *secretbuf,uint8_t *sharenrs,int32_t N,uint8_t *buffer,int32_t size,int32_t width) { - uint32_t i,j,Li_top,Li_bottom; - unsigned char *secret_ptr,*share_ptr,sharei,sharej; + uint32_t i,j,Li_top,Li_bottom; uint8_t *secret_ptr,*share_ptr,sharei,sharej; memset(secretbuf,0,width); for (i=0; isharenrs,ctx->sharecount,ctx->buffer,ctx->size,ctx->size); } -int32_t init_sharenrs(unsigned char sharenrs[255],unsigned char *orig,int32_t m,int32_t n) +int32_t init_sharenrs(uint8_t sharenrs[255],uint8_t *orig,int32_t m,int32_t n) { - unsigned char *randvals,valid[255]; + uint8_t *randvals,valid[255]; int32_t i,j,r,remains,orign; if ( m > n || n >= 0xff ) // reserve 255 for illegal sharei { @@ -324,7 +329,7 @@ int32_t init_sharenrs(unsigned char sharenrs[255],unsigned char *orig,int32_t m, return(-1); } randvals = calloc(1,65536); - gfshare_fill_rand(randvals,65536); + OS_randombytes(randvals,65536); memset(sharenrs,0,n); if ( orig == 0 && n == m ) { @@ -335,10 +340,10 @@ int32_t init_sharenrs(unsigned char sharenrs[255],unsigned char *orig,int32_t m, { r = (randvals[i] % remains); sharenrs[i] = valid[r]; - //printf("%d ",sharenrs[i]); + printf("%d ",sharenrs[i]); valid[r] = valid[--remains]; } - //printf("FULL SET\n"); + printf("FULL SET\n"); } else { @@ -417,7 +422,7 @@ int test_m_of_n(int m,int n,int size,int maxiters) for (i=0; ip_key ); + + ECDH_compute_key( &bytes[ 0 ], 32, p_pub, p_pub_impl->p_key, 0 ); +}*/ + bool bp_sign(EC_KEY *key, const void *data, size_t data_len,void **sig_, size_t *sig_len_) { size_t sig_sz = ECDSA_size(key); @@ -596,7 +604,7 @@ int32_t btc_getpubkey(char pubkeystr[67],uint8_t pubkeybuf[33],struct bp_key *ke return((int32_t)len); } -int32_t btc_convrmd160(char *coinaddr,uint8_t addrtype,uint8_t rmd160[20]) +/*int32_t btc_convrmd160(char *coinaddr,uint8_t addrtype,uint8_t rmd160[20]) { cstring *btc_addr; if ( (btc_addr= base58_encode_check(addrtype,true,rmd160,20)) != 0 ) @@ -606,13 +614,14 @@ int32_t btc_convrmd160(char *coinaddr,uint8_t addrtype,uint8_t rmd160[20]) return(0); } return(-1); -} +}*/ int32_t btc_coinaddr(char *coinaddr,uint8_t addrtype,char *pubkeystr) { uint8_t rmd160[20]; char hashstr[41]; calc_OP_HASH160(hashstr,rmd160,pubkeystr); - return(btc_convrmd160(coinaddr,addrtype,rmd160)); + return(bitcoin_address(coinaddr,addrtype,rmd160,20) != 0); + //return(btc_convrmd160(coinaddr,addrtype,rmd160)); } int32_t btc_convaddr(char *hexaddr,char *addr58) @@ -652,7 +661,7 @@ int32_t btc_priv2wif(char *wifstr,uint8_t privkey[32],uint8_t addrtype) strcpy(wifstr,btc_addr->str); cstr_free(btc_addr,true); } - printf("-> (%s) -> wif.(%s) addrtype.%02x\n",hexstr,wifstr,addrtype); + //printf("-> (%s) -> wif.(%s) addrtype.%02x\n",hexstr,wifstr,addrtype); return(0); } @@ -661,14 +670,19 @@ int32_t btc_wif2priv(uint8_t *addrtypep,uint8_t privkey[32],char *wifstr) cstring *cstr; int32_t len = -1; if ( (cstr= base58_decode_check(addrtypep,(const char *)wifstr)) != 0 ) { - init_hexbytes_noT((void *)privkey,(void *)cstr->str,cstr->len); if ( cstr->str[cstr->len-1] == 0x01 ) cstr->len--; - memcpy(privkey,cstr->str,cstr->len); - len = (int32_t)cstr->len; - char tmp[138]; - btc_priv2wif(tmp,privkey,*addrtypep); - printf("addrtype.%02x wifstr.(%llx) len.%d\n",*addrtypep,*(long long *)privkey,len); + if ( cstr->len == sizeof(bits256) ) + { + memcpy(privkey,cstr->str,cstr->len); + len = (int32_t)cstr->len; + if ( 1 ) + { + char tmp[138]; + btc_priv2wif(tmp,privkey,*addrtypep); + printf("addrtype.%02x wifstr.(%llx) privlen.%d\n",*addrtypep,*(long long *)privkey,len); + } + } cstr_free(cstr,true); } return(len); @@ -797,19 +811,6 @@ int32_t btc_pub65toaddr(char *coinaddr,uint8_t addrtype,char pubkey[131],uint8_t return(retval); } -struct iguana_waddress *iguana_waddresscalc(uint8_t pubtype,uint8_t wiftype,struct iguana_waddress *addr,bits256 privkey) -{ - memset(addr,0,sizeof(*addr)); - addr->privkey = privkey; - if ( btc_priv2pub(addr->pubkey,addr->privkey.bytes) == 0 && btc_priv2wif(addr->wifstr,addr->privkey.bytes,wiftype) == 0 && btc_pub2rmd(addr->rmd160,addr->pubkey) == 0 && btc_convrmd160(addr->coinaddr,pubtype,addr->rmd160) == 0 ) - { - addr->wiftype = wiftype; - addr->type = pubtype; - return(addr); - } - return(0); -} - int32_t iguana_ver(uint8_t *sig,int32_t siglen,uint8_t *data,int32_t datalen,bits256 pub) { struct bp_key key; uint8_t pubkey[33]; @@ -897,18 +898,6 @@ int32_t iguana_sig(uint8_t *sig,int32_t maxsize,uint8_t *data,int32_t datalen,bi return(0); }*/ -char *makekeypair(struct iguana_info *coin) -{ - struct iguana_waddress addr; char str[67]; cJSON *retjson = cJSON_CreateObject(); - if ( iguana_waddresscalc(coin->chain->pubtype,coin->chain->wiftype,&addr,rand256(1)) == 0 ) - { - init_hexbytes_noT(str,addr.pubkey,33); - jaddstr(retjson,"result",str); - jaddstr(retjson,"privkey",bits256_str(str,addr.privkey)); - } else jaddstr(retjson,"error","cant create address"); - return(jprint(retjson,1)); -} - cJSON *iguana_pubkeyjson(struct iguana_info *coin,char *pubkeystr) { cJSON *json = cJSON_CreateObject(); diff --git a/deprecated/m_unix.crypto777 b/deprecated/m_unix.crypto777 new file mode 100755 index 000000000..81891ae19 --- /dev/null +++ b/deprecated/m_unix.crypto777 @@ -0,0 +1,8 @@ +#DNN_DISABLE_GETADDRINFO_A=1 -DNN_USE_LITERAL_IFADDR=1 -DNN_HAVE_STDINT=1 -DNN_HAVE_MSG_CONTROL=1 -DNN_HAVE_SEMAPHORE=1 -DNN_HAVE_POLL=1 -DNN_HAVE_SOCKETPAIR=1 -DNN_USE_POLL=1 +#nanosrc/core/global.c nanosrc/core/ep.c nanosrc/core/epbase.c nanosrc/core/pipe.c nanosrc/core/poll.c nanosrc/core/sock.c nanosrc/core/sockbase.c nanosrc/core/symbol.c nanosrc/devices/device.c nanosrc/devices/tcpmuxd.c nanosrc/aio/ctx.c nanosrc/aio/fsm.c nanosrc/aio/poller.c nanosrc/aio/pool.c nanosrc/aio/timer.c nanosrc/aio/usock.c nanosrc/aio/timerset.c nanosrc/aio/worker.c nanosrc/utils/alloc.c nanosrc/utils/atomic.c nanosrc/utils/chunk.c nanosrc/utils/chunkref.c nanosrc/utils/clock.c nanosrc/utils/closefd.c nanosrc/utils/efd.c nanosrc/utils/err.c nanosrc/utils/glock.c nanosrc/utils/hash.c nanosrc/utils/list.c nanosrc/utils/msg.c nanosrc/utils/mutex.c nanosrc/utils/queue.c nanosrc/utils/random.c nanosrc/utils/sem.c nanosrc/utils/sleep.c nanosrc/utils/stopwatch.c nanosrc/utils/thread.c nanosrc/utils/wire.c nanosrc/protocols/utils/dist.c nanosrc/protocols/utils/excl.c nanosrc/protocols/utils/fq.c nanosrc/protocols/utils/lb.c nanosrc/protocols/utils/priolist.c nanosrc/protocols/bus/bus.c nanosrc/protocols/bus/xbus.c nanosrc/protocols/pipeline/push.c nanosrc/protocols/pipeline/pull.c nanosrc/protocols/pipeline/xpull.c nanosrc/protocols/pipeline/xpush.c nanosrc/protocols/pubsub/pub.c nanosrc/protocols/pubsub/sub.c nanosrc/protocols/pubsub/trie.c nanosrc/protocols/pubsub/xpub.c nanosrc/protocols/pubsub/xsub.c nanosrc/protocols/pair/pair.c nanosrc/protocols/pair/xpair.c nanosrc/protocols/reqrep/req.c nanosrc/protocols/reqrep/rep.c nanosrc/protocols/reqrep/task.c nanosrc/protocols/reqrep/xrep.c nanosrc/protocols/reqrep/xreq.c nanosrc/protocols/survey/respondent.c nanosrc/protocols/survey/surveyor.c nanosrc/protocols/survey/xrespondent.c nanosrc/protocols/survey/xsurveyor.c nanosrc/transports/utils/backoff.c nanosrc/transports/utils/dns.c nanosrc/transports/utils/iface.c nanosrc/transports/utils/literal.c nanosrc/transports/utils/port.c nanosrc/transports/utils/streamhdr.c nanosrc/transports/utils/base64.c nanosrc/transports/ipc/aipc.c nanosrc/transports/ipc/bipc.c nanosrc/transports/ipc/cipc.c nanosrc/transports/ipc/ipc.c nanosrc/transports/ipc/sipc.c nanosrc/transports/tcp/atcp.c nanosrc/transports/tcp/btcp.c nanosrc/transports/tcp/ctcp.c nanosrc/transports/tcp/stcp.c nanosrc/transports/tcp/tcp.c nanosrc/transports/inproc/binproc.c nanosrc/transports/inproc/cinproc.c nanosrc/transports/inproc/inproc.c nanosrc/transports/inproc/ins.c nanosrc/transports/inproc/msgqueue.c nanosrc/transports/inproc/sinproc.c + +#include crypto777.sources +#gcc -c -O2 $(CRYPTO777_SRCS) + +gcc -c -O2 *.c jpeg/*.c jpeg/unix/*.c -I/usr/lib/x86_64-linux-gnu/curl +rm -f ../agents/libcrypto777.a; ar rcu ../agents/libcrypto777.a *.o diff --git a/deprecated/obsolete.h b/deprecated/obsolete.h old mode 100644 new mode 100755 index e9ecf4aa2..2c667ebc2 --- a/deprecated/obsolete.h +++ b/deprecated/obsolete.h @@ -8440,48 +8440,7 @@ void iguana_dedicatedrecv(void *arg) } return(0); } - - struct iguana_txblock *iguana_peertxdata(struct iguana_info *coin,int32_t *bundleip,char *fname,struct iguana_memspace *mem,uint32_t ipbits,bits256 hash2) - { - int32_t bundlei,datalen,checki,hdrsi,fpos; char str[65],str2[65]; FILE *fp; - bits256 checkhash2; struct iguana_txblock *txdata = 0; - if ( (bundlei= iguana_peerfname(coin,&hdrsi,fname,ipbits,hash2)) >= 0 ) - { - if ( (fp= fopen(fname,"rb")) != 0 ) - { - fseek(fp,bundlei * sizeof(bundlei),SEEK_SET); - fread(&fpos,1,sizeof(fpos),fp); - fseek(fp,fpos,SEEK_SET); - fread(&checki,1,sizeof(checki),fp); - if ( ftell(fp)-sizeof(checki) == fpos && bundlei == checki ) - { - fread(&checkhash2,1,sizeof(checkhash2),fp); - if ( memcmp(hash2.bytes,checkhash2.bytes,sizeof(hash2)) == 0 ) - { - fread(&datalen,1,sizeof(datalen),fp); - if ( datalen < (mem->totalsize - mem->used - 4) ) - { - if ( (txdata= iguana_memalloc(mem,datalen,0)) != 0 ) - { - fread(txdata,1,datalen,fp); - if ( txdata->datalen != datalen || txdata->block.bundlei != bundlei ) - { - printf("%s peertxdata txdata->datalen.%d != %d bundlei.%d vs %d\n",bits256_str(str,txdata->block.hash2),txdata->datalen,datalen,txdata->block.bundlei,bundlei); - getchar(); - txdata = 0; - iguana_memreset(mem); - } //else printf("SUCCESS txdata.%s bundlei.%d fpos.%d T.%d U.%d S.%d P.%d\n",bits256_str(str,txdata->block.hash2),bundlei,fpos,txdata->numtxids,txdata->numunspents,txdata->numspends,txdata->numpkinds); - } else printf("peertxdata error allocating txdata\n"); - } else printf("mismatch peertxdata datalen %d vs %ld totalsize %ld\n",datalen,mem->totalsize - mem->used - 4,(long)mem->totalsize); - } else printf("peertxdata hash mismatch %s != %s\n",bits256_str(str,hash2),bits256_str(str2,checkhash2)); - } else printf("peertxdata bundlei.%d != checki.%d, fpos.%d ftell.%ld\n",bundlei,checki,fpos,ftell(fp)); - fclose(fp); - } else printf("cant find file.(%s)\n",fname); - } //else printf("bundlei.%d\n",bundlei); - *bundleip = bundlei; - return(txdata); - } - + /*if ( (n= ramchain->data->numtxids) > 0 ) { for (ramchain->txidind=ramchain->data->firsti; ramchain->txidindtxidind++) @@ -13318,5 +13277,3173 @@ len = 0; nextcmdstr = message = ""; */ - + if ( A->orderid != orderid ) + { + printf("orderid mismatch %llu vs %llu\n",(long long)orderid,(long long)A->orderid); + return(clonestr("{\"error\":\"instantdex_BTCswap orderid mismatch\"}")); + } + if ( senderaddr == 0 || strcmp(A->A.base,base) != 0 || strcmp(A->A.rel,"BTC") != 0 ) + { + printf("senderaddr.%p base.(%s vs %s) rel.(%s vs %s)\n",senderaddr,A->A.base,base,A->A.rel,"BTC"); + return(clonestr("{\"error\":\"instantdex_BTCswap base or rel mismatch\"}")); + } + { + printf("satoshis mismatch %llu vs %llu\n",(long long)satoshis,(long long)instantdex_relsatoshis(A->A.price64,A->A.basevolume64)); + return(clonestr("{\"error\":\"instantdex_BTCswap satoshis mismatch\"}")); + } + if ( othersatoshis != A->A.basevolume64 ) + { + printf("othersatoshis mismatch %llu vs %llu\n",(long long)satoshis,(long long)A->A.basevolume64); + return(clonestr("{\"error\":\"instantdex_BTCswap satoshis mismatch\"}")); + } + + /*TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,BTCoffer,othercoin,otherassetid,maxprice,othervolume) + { + if ( remoteaddr == 0 ) + return(instantdex_btcoffer(myinfo,exchanges777_find("bitcoin"),othercoin[0] != 0 ? othercoin : otherassetid,othervolume,maxprice)); + else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}")); + } + + STRING_AND_TWO_DOUBLES(InstantDEX,ALToffer,basecoin,minprice,basevolume) + { + int32_t hops = INSTANTDEX_HOPS; cJSON *argjson; char *str; struct instantdex_accept A; + if ( remoteaddr == 0 ) + { + if ( iguana_coinfind(basecoin) == 0 ) + return(clonestr("{\"error\":\"InstantDEX basecoin is not active, need to addcoin\"}")); + instantdex_acceptset(&A,basecoin,"BTC",INSTANTDEX_OFFERDURATION,0,1,minprice,basevolume,myinfo->myaddr.nxt64bits); + argjson = instantdex_acceptsendjson(&A); + if ( minprice > 0. ) + { + if ( (str= InstantDEX_minaccept(IGUANA_CALLARGS,basecoin,"BTC",minprice,basevolume)) != 0 ) + free(str); + } + return(instantdex_sendcmd(myinfo,argjson,"ALToffer",myinfo->ipaddr,hops)); + } else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}")); + } + + STRING_AND_TWO_DOUBLES(InstantDEX,NXToffer,assetid,minprice,basevolume) + { + int32_t hops = INSTANTDEX_HOPS; cJSON *argjson; char *base,*str; struct instantdex_accept A; + if ( remoteaddr == 0 ) + { + if ( assetid == 0 || assetid[0] == 0 || strcmp(assetid,"0") == 0 || strcmp(assetid,"NXT") == 0 || strcmp(assetid,"nxt") == 0 ) + base = "NXT"; + else if ( is_decimalstr(assetid) <= 0 ) + return(clonestr("{\"error\":\"InstantDEX NXToffer illegal assetid\"}")); + else base = assetid; + instantdex_acceptset(&A,base,"BTC",INSTANTDEX_OFFERDURATION,0,1,minprice,basevolume,myinfo->myaddr.nxt64bits); + argjson = instantdex_acceptsendjson(&A); + if ( minprice > 0. ) + { + if ( (str= InstantDEX_minaccept(IGUANA_CALLARGS,base,"BTC",minprice,basevolume)) != 0 ) + free(str); + } + return(instantdex_sendcmd(myinfo,argjson,"NXToffer",myinfo->ipaddr,hops)); + } else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}")); + } + */ + if ( sendprivs != 0 ) + { + printf("sendprivs.%d\n",sendprivs); + if ( swap->otherschoosei < 0 ) + printf("instantdex_newjson otherschoosei < 0 when sendprivs != 0\n"); + else + { + if ( privs == 0 && (privs= calloc(1,sizeof(*swap->privkeys))) == 0 ) + printf("instantdex_newjson couldnt allocate hex\n"); + else if ( hexstr == 0 && (hexstr= malloc(sizeof(*swap->privkeys) * 2 + 1)) == 0 ) + printf("instantdex_newjson couldnt allocate hexstr\n"); + else + { + memcpy(privs,swap->privkeys,sizeof(*swap->privkeys)); + memset(privs[swap->otherschoosei].bytes,0,sizeof(*privs)); + for (i=0; iprivkeys)/sizeof(*swap->privkeys); i++) + { + iguana_rwbignum(1,serialized,sizeof(privs[i]),privs[i].bytes); + memcpy(privs[i].bytes,serialized,sizeof(privs[i])); + } + } + } + } + + /*cJSON *instantdex_acceptsendjson(struct instantdex_accept *ap) + { + cJSON *json = cJSON_CreateObject(); + jaddstr(json,"b",ap->offer.base); + jaddstr(json,"r",ap->offer.rel); + jaddnum(json,"n",ap->offer.nonce); + jaddnum(json,"e",ap->offer.expiration); + jaddnum(json,"s",ap->offer.myside); + jaddnum(json,"d",ap->offer.acceptdir); + jadd64bits(json,"p",ap->offer.price64); + jadd64bits(json,"v",ap->offer.basevolume64); + jadd64bits(json,"o",ap->offer.offer64); + jadd64bits(json,"id",ap->orderid); + return(json); + }*/ + if ( A->offer.price64 != 0 ) + { + if ( (ap= instantdex_offerfind(myinfo,exchange,0,0,A->orderid,"*","*",1)) != 0 ) + { + swap->state++; + A->info = swap; + printf(">>>>>>>>>> PENDING ORDER %llu\n",(long long)A->orderid); + } + } + if ( ap == 0 ) + { + printf("couldnt find accept?? dir.%d orderid.%llu\n",ap->offer.acceptdir,(long long)A->orderid); + free(swap); + return(clonestr("{\"error\":\"couldnt find order just created\"}")); + } + if ( strncmp(cmdstr,"BTC",3) == 0 ) + else if ( strncmp(cmdstr,"NXT",3) == 0 ) + retstr = instantdex_NXTswap(myinfo,exchange,&A,cmdstr+3,msg,argjson,remoteaddr,signerbits,serdata,datalen); + else if ( strncmp(cmdstr,"ALT",3) == 0 ) + retstr = instantdex_ALTswap(myinfo,exchange,&A,cmdstr+3,msg,argjson,remoteaddr,signerbits,serdata,datalen); + else if ( strncmp(cmdstr,"PAX",3) == 0 ) + retstr = instantdex_PAXswap(myinfo,exchanges777_find("PAX"),&A,cmdstr+3,msg,argjson,remoteaddr,signerbits,serdata,datalen); + else return(clonestr("{\"error\":\"unrecognized atomic swap family\"}")); + if ( ap != 0 ) + { + ap->info = A.info; + ap->pendingvolume64 = A.pendingvolume64; + } + //printf("after swap ap.%p (%s)\n",ap,retstr); + return(retstr); + + char *instantdex_BTCswap(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,char *cmdstr,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *serdata,int32_t serdatalen) // receiving side + { + uint64_t satoshis[2]; int32_t offerdir = 0; double minperc; uint64_t insurance,relsatoshis; + struct instantdex_accept *ap; struct bitcoin_swapinfo *swap = 0; bits256 orderhash,traderpub; + struct iguana_info *coinbtc,*altcoin; cJSON *newjson=0; char *retstr=0; + relsatoshis = instantdex_relsatoshis(A->offer.price64,A->offer.basevolume64); + traderpub = jbits256(argjson,"traderpub"); + if ( (minperc= jdouble(argjson,"p")) < INSTANTDEX_MINPERC ) + minperc = INSTANTDEX_MINPERC; + coinbtc = iguana_coinfind("BTC"); + insurance = (satoshis[1] * INSTANTDEX_INSURANCERATE + coinbtc->chain->txfee); // txfee prevents papercut attack + offerdir = instantdex_bidaskdir(A); + vcalc_sha256(0,orderhash.bytes,(void *)&A->offer,sizeof(ap->offer)); + swap = A->info; + if ( bits256_cmp(traderpub,myinfo->myaddr.persistent) == 0 ) + { + printf("got my own packet\n"); + return(clonestr("{\"result\":\"got my own packet\"}")); + } + printf("T.%d [%s] got %s.(%s/%s) %.8f vol %.8f %llu offerside.%d offerdir.%d swap.%p decksize.%ld/datalen.%d\n",bits256_cmp(traderpub,myinfo->myaddr.persistent),swap!=0?swap->nextstate:"",cmdstr,A->offer.base,A->offer.rel,dstr(A->offer.price64),dstr(A->offer.basevolume64),(long long)A->orderid,A->offer.myside,A->offer.acceptdir,A->info,sizeof(swap->deck),serdatalen); + if ( exchange == 0 ) + return(clonestr("{\"error\":\"instantdex_BTCswap null exchange ptr\"}")); + if ( (altcoin= iguana_coinfind(A->offer.base)) == 0 || coinbtc == 0 ) + { + printf("other.%p coinbtc.%p (%s/%s)\n",altcoin,coinbtc,A->offer.base,A->offer.rel); + return(clonestr("{\"error\":\"instantdex_BTCswap cant find btc or other coin info\"}")); + } + if ( strcmp(A->offer.rel,"BTC") != 0 ) + return(clonestr("{\"error\":\"instantdex_BTCswap offer non BTC rel\"}")); + if ( orderhash.txid != A->orderid ) + return(clonestr("{\"error\":\"txid mismatches orderid\"}")); + if ( strcmp(cmdstr,"offer") == 0 ) // receiver is networkwide + { + if ( A->offer.expiration < (time(NULL) + INSTANTDEX_DURATION) ) + return(clonestr("{\"error\":\"instantdex_BTCswap offer too close to expiration\"}")); + if ( (ap= instantdex_acceptable(myinfo,exchange,A,acct777_nxt64bits(traderpub),minperc)) != 0 ) + { + if ( A->info == 0 ) + { + swap = calloc(1,sizeof(struct bitcoin_swapinfo)); + swap->choosei = swap->otherschoosei = -1; + swap->othertrader = traderpub; + if ( offerdir > 0 ) + swap->bidid = A->orderid; + else swap->askid = A->orderid; + swap->isbob = (A->offer.myside ^ 1); + printf("%p SET ISBOB.%d orderid.%llu\n",ap,swap->isbob,(long long)A->orderid); + } + char str[65]; printf("GOT OFFER! %p (%s/%s) other.%s myside.%d next.%s\n",A->info,A->offer.base,A->offer.rel,bits256_str(str,traderpub),swap->isbob,swap->nextstate); + if ( (A->info= swap) != 0 ) + { + ap->info = swap; + if ( (newjson= instantdex_newjson(myinfo,swap,argjson,orderhash,A,1)) == 0 ) + return(clonestr("{\"error\":\"instantdex_BTCswap offer null newjson\"}")); + else + { + // verify feetx + instantdex_pendingnotice(myinfo,exchange,ap,A->offer.basevolume64); + if ( (retstr= instantdex_choosei(swap,newjson,argjson,serdata,serdatalen)) != 0 ) + { + return(retstr); + } + else + { + // generate feetx to send + if ( swap->isbob != 0 ) + strcpy(swap->nextstate,"step2"); + else strcpy(swap->nextstate,"step3"); + return(instantdex_sendcmd(myinfo,&A->offer,newjson,"BTCstep1",traderpub,INSTANTDEX_HOPS,swap->deck,sizeof(swap->deck))); + } + } + } else return(clonestr("{\"error\":\"couldnt allocate swap info\"}")); + } + else + { + printf("no matching trade for %llu -> InstantDEX_minaccept isbob.%d\n",(long long)A->orderid,A->offer.myside); + if ( instantdex_offerfind(myinfo,exchange,0,0,A->orderid,"*","*",1) == 0 ) + { + ap = calloc(1,sizeof(*ap)); + *ap = *A; + queue_enqueue("acceptableQ",&exchange->acceptableQ,&ap->DL,0); + return(clonestr("{\"result\":\"added new order to orderbook\"}")); + } else return(clonestr("{\"result\":\"order was already in orderbook\"}")); + } + } + else if ( swap == 0 ) + return(clonestr("{\"error\":\"no swap info\"}")); + if ( offerdir > 0 ) + swap->bidid = A->orderid; + else swap->askid = A->orderid; + if ( bits256_nonz(swap->othertrader) == 0 ) + swap->othertrader = traderpub; + else if ( bits256_cmp(traderpub,swap->othertrader) != 0 ) + { + printf("competing offer received for (%s/%s) %.8f %.8f\n",A->offer.base,A->offer.rel,dstr(A->offer.price64),dstr(A->offer.basevolume64)); + return(clonestr("{\"error\":\"no competing offers for now\"}")); + } + if ( bits256_nonz(swap->orderhash) == 0 ) + swap->orderhash = orderhash; + else if ( bits256_cmp(orderhash,swap->orderhash) != 0 ) + { + printf("orderhash %llx mismatch %llx\n",(long long)swap->orderhash.txid,(long long)orderhash.txid); + return(clonestr("{\"error\":\"orderhash mismatch???\"}")); + } + swap->satoshis[0] = A->offer.basevolume64; + swap->satoshis[1] = relsatoshis; + swap->insurance = (relsatoshis * INSTANTDEX_INSURANCERATE + coinbtc->chain->txfee); // txfee + if ( swap->minperc < minperc ) + swap->minperc = minperc; + return(instantdex_statemachine(myinfo,exchange,A,cmdstr,swap,argjson,serdata,serdatalen,altcoin,coinbtc)); + } + +#ifdef xxx + if ( strcmp(cmdstr,"step1") == 0 && strcmp(swap->nextstate,cmdstr) == 0 ) // either + { + printf("%s got step1, should have other's choosei\n",swap->isbob!=0?"BOB":"alice"); + if ( (newjson= instantdex_newjson(myinfo,swap,argjson,swap->orderhash,A,0)) == 0 ) + return(clonestr("{\"error\":\"instantdex_BTCswap step1 null newjson\"}")); + else if ( swap->otherschoosei < 0 ) + return(clonestr("{\"error\":\"instantdex_BTCswap step1, no didnt choosei\"}")); + else + { + printf("%s chose.%d\n",swap->isbob==0?"BOB":"alice",swap->otherschoosei); + if ( swap->isbob == 0 ) + swap->privAm = swap->privkeys[swap->otherschoosei]; + else swap->privBn = swap->privkeys[swap->otherschoosei]; + memset(&swap->privkeys[swap->otherschoosei],0,sizeof(swap->privkeys[swap->otherschoosei])); + if ( (retstr= instantdex_choosei(swap,newjson,argjson,serdata,serdatalen)) != 0 ) + return(retstr); + /*if ( swap->isbob == 0 ) + { + if ( (swap->feetx= instantdex_bobtx(myinfo,coinbtc,&swap->ftxid,swap->otherpubs[0],swap->mypubs[0],swap->privkeys[swap->otherschoosei],reftime,swap->insurance,1)) != 0 ) + { + jaddstr(newjson,"feetx",swap->feetx); + jaddbits256(newjson,"ftxid",swap->ftxid); + // broadcast to network + } + }*/ + if ( swap->isbob != 0 ) + { + strcpy(swap->nextstate,"step4"); + printf("BOB sends (%s), next.(%s)\n","BTCstep3",swap->nextstate); + } + else + { + strcpy(swap->nextstate,"step3"); + printf("Alice sends (%s), next.(%s)\n","BTCstep2",swap->nextstate); + } + return(instantdex_sendcmd(myinfo,&A->offer,newjson,swap->isbob != 0 ? "BTCstep3" : "BTCstep2",swap->othertrader,INSTANTDEX_HOPS,swap->privkeys,sizeof(swap->privkeys))); + } + } + else if ( strcmp(cmdstr,"step2") == 0 && strcmp(swap->nextstate,"cmdstr") == 0 ) // bob + { + printf("%s got step2, should have other's privkeys\n",swap->isbob!=0?"BOB":"alice"); + if ( (newjson= instantdex_newjson(myinfo,swap,argjson,swap->orderhash,A,0)) == 0 ) + return(clonestr("{\"error\":\"instantdex_BTCswap step2 null newjson\"}")); + else + { + instantdex_privkeysextract(myinfo,swap,serdata,serdatalen); + if ( swap->cutverified == 0 || swap->otherverifiedcut == 0 ) + return(clonestr("{\"error\":\"instantdex_BTCswap step2, both sides didnt validate\"}")); + else + { + if ( (swap->deposit= instantdex_bobtx(myinfo,coinbtc,&swap->dtxid,swap->otherpubs[0],swap->mypubs[0],swap->privkeys[swap->otherschoosei],reftime,swap->satoshis[swap->isbob],1)) != 0 ) + { + jaddstr(newjson,"deposit",swap->deposit); + jaddbits256(newjson,"dtxid",swap->dtxid); + //jaddbits256(newjson,"pubBn",bitcoin_pubkey33(pubkey,swap->pubBn)); + // broadcast to network + strcpy(swap->nextstate,"step4"); + printf("BOB sends (%s), next.(%s)\n","BTCstep3",swap->nextstate); + return(instantdex_sendcmd(myinfo,&A->offer,newjson,"BTCstep3",swap->othertrader,INSTANTDEX_HOPS,0,0)); + } else return(clonestr("{\"error\":\"instantdex_BTCswap Bob step2, cant create deposit\"}")); + } + } //else return(clonestr("{\"error\":\"instantdex_BTCswap step2 invalid fee\"}")); + } + else if ( strcmp(cmdstr,"step3") == 0 && strcmp(swap->nextstate,"cmdstr") == 0 ) // alice + { + printf("Alice got step3 should have Bob's choosei\n"); + if ( (newjson= instantdex_newjson(myinfo,swap,argjson,swap->orderhash,A,0)) == 0 ) + return(clonestr("{\"error\":\"instantdex_BTCswap Alice step3 null newjson\"}")); + else + { + instantdex_privkeysextract(myinfo,swap,serdata,serdatalen); + if ( swap->cutverified == 0 || swap->otherverifiedcut == 0 || bits256_nonz(swap->pubBn) == 0 ) + return(clonestr("{\"error\":\"instantdex_BTCswap step3, both sides didnt validate\"}")); + else if ( instantdex_paymentverify(myinfo,coinbtc,swap,A,argjson,1) == 0 ) + { + //swap->pubAm = bitcoin_pubkey33(pubkey,swap->privkeys[swap->otherschoosei]); + if ( (swap->altpayment= instantdex_alicetx(myinfo,altcoin,swap->altmsigaddr,&swap->aptxid,swap->pubAm,swap->pubBn,swap->satoshis[swap->isbob])) != 0 ) + { + jaddstr(newjson,"altpayment",swap->altpayment); + jaddstr(newjson,"altmsigaddr",swap->altmsigaddr); + jaddbits256(newjson,"aptxid",swap->aptxid); + jaddbits256(newjson,"pubAm",swap->pubAm); + // broadcast to network + strcpy(swap->nextstate,"step5"); + printf("Alice sends (%s), next.(%s)\n","BTCstep4",swap->nextstate); + return(instantdex_sendcmd(myinfo,&A->offer,newjson,"BTCstep4",swap->othertrader,INSTANTDEX_HOPS,0,0)); + } else return(clonestr("{\"error\":\"instantdex_BTCswap Alice step3, error making altpay\"}")); + } else return(clonestr("{\"error\":\"instantdex_BTCswap Alice step3, invalid deposit\"}")); + } + } + else if ( strcmp(cmdstr,"step4") == 0 && strcmp(swap->nextstate,"cmdstr") == 0 ) // bob + { + printf("Bob got step4 should have Alice's altpayment\n"); + if ( (newjson= instantdex_newjson(myinfo,swap,argjson,swap->orderhash,A,0)) == 0 ) + return(clonestr("{\"error\":\"instantdex_BTCswap Bob step4 null newjson\"}")); + else if ( bits256_nonz(swap->pubAm) == 0 ) + return(clonestr("{\"error\":\"instantdex_BTCswap step4, no pubAm\"}")); + else if ( instantdex_altpaymentverify(myinfo,altcoin,swap,A,argjson) == 0 ) + { + if ( (swap->deposit= instantdex_bobtx(myinfo,coinbtc,&swap->ptxid,swap->mypubs[1],swap->otherpubs[0],swap->privkeys[swap->otherschoosei],reftime,swap->satoshis[swap->isbob],0)) != 0 ) + { + jaddstr(newjson,"payment",swap->payment); + jaddbits256(newjson,"ptxid",swap->ptxid); + // broadcast to network + strcpy(swap->nextstate,"step6"); + return(instantdex_sendcmd(myinfo,&A->offer,newjson,"BTCstep5",swap->othertrader,INSTANTDEX_HOPS,0,0)); + } else return(clonestr("{\"error\":\"instantdex_BTCswap Bob step4, cant create payment\"}")); + } else return(clonestr("{\"error\":\"instantdex_BTCswap Alice step3, invalid deposit\"}")); + } + else if ( strcmp(cmdstr,"step5") == 0 && strcmp(swap->nextstate,"cmdstr") == 0 ) // alice + { + printf("Alice got step5 should have Bob's payment\n"); + if ( (newjson= instantdex_newjson(myinfo,swap,argjson,swap->orderhash,A,0)) == 0 ) + return(clonestr("{\"error\":\"instantdex_BTCswap Alice step5 null newjson\"}")); + else if ( instantdex_paymentverify(myinfo,coinbtc,swap,A,argjson,0) == 0 ) + { + strcpy(swap->nextstate,"step7"); + /*if ( (swap->spendtx= instantdex_spendpayment(myinfo,coinbtc,&swap->stxid,swap,argjson,newjson)) != 0 ) + { + // broadcast to network + return(instantdex_sendcmd(myinfo,&A->A,newjson,"BTCstep6",swap->othertrader,INSTANTDEX_HOPS)); + } else return(clonestr("{\"error\":\"instantdex_BTCswap Alice step5, cant spend payment\"}"));*/ + } else return(clonestr("{\"error\":\"instantdex_BTCswap Bob step6, invalid payment\"}")); + } + else if ( strcmp(cmdstr,"step6") == 0 && strcmp(swap->nextstate,"cmdstr") == 0 ) // bob + { + printf("Bob got step6 should have Alice's privkey\n"); + if ( (newjson= instantdex_newjson(myinfo,swap,argjson,swap->orderhash,A,0)) == 0 ) + return(clonestr("{\"error\":\"instantdex_BTCswap Bob step6 null newjson\"}")); + strcpy(swap->nextstate,"step7"); + /*else if ( instantdex_spendverify(myinfo,coinbtc,swap,A,argjson,0) == 0 ) + { + if ( (swap->altspend= instantdex_spendaltpayment(myinfo,altcoin,&swap->astxid,swap,argjson,newjson)) != 0 ) + { + jaddstr(newjson,"altspend",swap->altspend); + jaddbits256(newjson,"astxid",swap->astxid); + // broadcast to network + return(clonestr("{\"result\":\"Bob finished atomic swap\"}")); + } else return(clonestr("{\"error\":\"instantdex_BTCswap Bob step6, cant spend altpayment\"}")); + } else return(clonestr("{\"error\":\"instantdex_BTCswap Bob step6, invalid spend\"}"));*/ + } + else if ( strcmp(cmdstr,"step7") == 0 && strcmp(swap->nextstate,"cmdstr") == 0 ) // both + { + // update status, goto refund if thresholds exceeded + retstr = clonestr("{\"result\":\"BTC swap updated state\"}"); + } + else retstr = clonestr("{\"error\":\"BTC swap got unrecognized command\"}"); + if ( retstr == 0 ) + retstr = clonestr("{\"error\":\"BTC swap null retstr\"}"); + if ( swap != 0 ) + printf("BTCSWAP next.(%s) (%s) isbob.%d nextstate.%s verified.(%d %d)\n",swap->nextstate,cmdstr,swap->isbob,swap->nextstate,swap->cutverified,swap->otherverifiedcut); + else printf("BTCSWAP.(%s)\n",retstr); + return(retstr); +#endif + else if ( strcmp(cmdstr,"BTCdeckC") == 0 ) + { + if ( ap->info == 0 ) + { + printf("A (%s) null swap for orderid.%llu p.%p\n",cmdstr,(long long)ap->orderid,ap); + return(clonestr("{\"error\":\"no swap for orderid\"}")); + } + else + { + if ( ap->otherorderid == 0 ) + { + ap->otherorderid = ap->orderid; + ap->otheroffer = ap->offer; + ap->offer = A.offer; + ap->orderid = A.orderid; + ((struct bitcoin_swapinfo *)ap->info)->feetag64 = ap->orderid; + } + printf("add to statemachine\n"); + queue_enqueue("statemachineQ",&exchange->statemachineQ,&ap->DL,0); + newjson = instantdex_parseargjson(myinfo,exchange,ap,argjson,0); + if ( (retstr= instantdex_addfeetx(myinfo,newjson,ap,ap->info,"BOB_sentoffer","ALICE_sentoffer")) == 0 ) + { + return(instantdex_statemachine(BTC_states,BTC_numstates,myinfo,exchange,ap,cmdstr,argjson,newjson,serdata,serdatalen)); + } else return(clonestr("{\"error\":\"couldnt add fee\"}")); + } + /* + for (iter=0; iter<2; iter++) + { + while ( (m= category_gethexmsg(myinfo,instantdexhash,iter == 0 ? GENESIS_PUBKEY : myinfo->myaddr.persistent)) != 0 ) + { + //printf("gothexmsg len.%d\n",m->len); + pm = (struct instantdex_msghdr *)m->msg; + if ( m->remoteipbits != 0 ) + expand_ipbits(remote,m->remoteipbits); + else remote[0] = 0; + if ( (str= InstantDEX_hexmsg(myinfo,pm,m->len,remote)) != 0 ) + free(str); + free(m); + } + }*/ + + /* uint64_t satoshis[2]; int32_t offerdir = 0; double minperc; uint64_t insurance,relsatoshis; + bits256 orderhash,traderpub; struct iguana_info *coinbtc; + if ( (swap= ap->info) == 0 ) + return(clonestr("{\"error\":\"no swapinfo set\"}")); + relsatoshis = instantdex_BTCsatoshis(ap->offer.price64,ap->offer.basevolume64); + if ( (minperc= jdouble(argjson,"m")) < INSTANTDEX_MINPERC ) + minperc = INSTANTDEX_MINPERC; + offerdir = instantdex_bidaskdir(&ap->offer); + if ( 0 ) + { + int32_t i; + for (i=0; ioffer); i++) + printf("%02x ",((uint8_t *)&ap->offer)[i]); + printf("swapset.%llu\n",(long long)ap->orderid); + } + if ( offerdir > 0 ) + { + swap->bidid = ap->orderid; + swap->askid = ap->otherorderid; + } + else + { + swap->askid = ap->orderid; + swap->bidid = ap->otherorderid; + } + if ( bits256_nonz(swap->othertrader) == 0 ) + swap->othertrader = traderpub; + else if ( bits256_cmp(traderpub,swap->othertrader) != 0 ) + { + printf("competing offer received for (%s/%s) %.8f %.8f\n",ap->offer.base,ap->offer.rel,dstr(ap->offer.price64),dstr(ap->offer.basevolume64)); + return(clonestr("{\"error\":\"no competing offers for now\"}")); + } + if ( bits256_nonz(swap->orderhash) == 0 ) + swap->orderhash = orderhash; + else if ( bits256_cmp(orderhash,swap->orderhash) != 0 ) + { + printf("orderhash %llx mismatch %llx\n",(long long)swap->orderhash.txid,(long long)orderhash.txid); + return(clonestr("{\"error\":\"orderhash mismatch???\"}")); + } + swap->satoshis[0] = ap->offer.basevolume64; + swap->satoshis[1] = relsatoshis; + swap->insurance = (relsatoshis * INSTANTDEX_INSURANCERATE + coinbtc->chain->txfee); // txfee + /* if ( ap->info == 0 ) + //printf("gotoffer SETSWAP for orderid.%llu (%s)\n",(long long)ap->orderid,jprint(argjson,0)); + swap->choosei = swap->otherschoosei = -1; + if ( (retstr= instantdex_swapset(myinfo,ap,argjson)) != 0 ) + return(retstr); + swap->feetag64 = ap->orderid;*/ + + /*char *instantdex_swapset(struct supernet_info *myinfo,struct instantdex_accept *ap,cJSON *argjson) + { + uint64_t satoshis[2]; int32_t offerdir = 0; double minperc; uint64_t insurance,relsatoshis; + struct bitcoin_swapinfo *swap; bits256 orderhash,traderpub; struct iguana_info *coinbtc; + if ( (swap= ap->info) == 0 ) + return(clonestr("{\"error\":\"no swapinfo set\"}")); + relsatoshis = instantdex_BTCsatoshis(ap->offer.price64,ap->offer.basevolume64); + traderpub = jbits256(argjson,"traderpub"); + if ( (minperc= jdouble(argjson,"m")) < INSTANTDEX_MINPERC ) + minperc = INSTANTDEX_MINPERC; + if ( (coinbtc= iguana_coinfind("BTC")) == 0 ) + return(clonestr("{\"error\":\"no BTC found\"}")); + insurance = (satoshis[1] * INSTANTDEX_INSURANCERATE + coinbtc->chain->txfee); + offerdir = instantdex_bidaskdir(&ap->offer); + vcalc_sha256(0,orderhash.bytes,(void *)&ap->offer,sizeof(ap->offer)); + if ( 0 ) + { + int32_t i; + for (i=0; ioffer); i++) + printf("%02x ",((uint8_t *)&ap->offer)[i]); + printf("swapset.%llu\n",(long long)ap->orderid); + } + if ( offerdir > 0 ) + { + swap->bidid = ap->orderid; + swap->askid = ap->otherorderid; + } + else + { + swap->askid = ap->orderid; + swap->bidid = ap->otherorderid; + } + if ( bits256_nonz(swap->othertrader) == 0 ) + swap->othertrader = traderpub; + else if ( bits256_cmp(traderpub,swap->othertrader) != 0 ) + { + printf("competing offer received for (%s/%s) %.8f %.8f\n",ap->offer.base,ap->offer.rel,dstr(ap->offer.price64),dstr(ap->offer.basevolume64)); + return(clonestr("{\"error\":\"no competing offers for now\"}")); + } + if ( bits256_nonz(swap->orderhash) == 0 ) + swap->orderhash = orderhash; + else if ( bits256_cmp(orderhash,swap->orderhash) != 0 ) + { + printf("orderhash %llx mismatch %llx\n",(long long)swap->orderhash.txid,(long long)orderhash.txid); + return(clonestr("{\"error\":\"orderhash mismatch???\"}")); + } + swap->satoshis[0] = ap->offer.basevolume64; + swap->satoshis[1] = relsatoshis; + swap->insurance = (relsatoshis * INSTANTDEX_INSURANCERATE + coinbtc->chain->txfee); // txfee + return(0); + } + + char *instantdex_sendoffer(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *argjson) // Bob sending to network (Alice) + { + struct iguana_info *other; struct bitcoin_swapinfo *swap; int32_t isbob; cJSON *newjson; char *retstr; + if ( strcmp(ap->offer.rel,"BTC") != 0 ) + return(clonestr("{\"error\":\"invalid othercoin\"}")); + else if ( (other= iguana_coinfind(ap->offer.base)) == 0 ) + return(clonestr("{\"error\":\"invalid othercoin\"}")); + else if ( ap->offer.price64 <= 0 || ap->offer.basevolume64 <= 0 ) + return(clonestr("{\"error\":\"illegal price or volume\"}")); + isbob = (ap->offer.myside == 1); + swap = calloc(1,sizeof(struct bitcoin_swapinfo)); + swap->isbob = isbob; + swap->expiration = ap->offer.expiration;//(uint32_t)(time(NULL) + INSTANTDEX_LOCKTIME*isbob); + swap->choosei = swap->otherschoosei = -1; + swap->depositconfirms = swap->paymentconfirms = swap->altpaymentconfirms = swap->myfeeconfirms = swap->otherfeeconfirms = -1; + ap->info = swap; + printf("sendoffer SETSWAP for orderid.%llu ap.%p (%p)\n",(long long)ap->orderid,ap,swap); + if ( (retstr= instantdex_swapset(myinfo,ap,argjson)) != 0 ) + return(retstr); + ap->orderid = swap->orderhash.txid; + if ( (newjson= instantdex_parseargjson(myinfo,exchange,ap,argjson,1)) == 0 ) + return(clonestr("{\"error\":\"instantdex_BTCswap offer null newjson\"}")); + else + { + //instantdex_bobtx(myinfo,iguana_coinfind("BTCD"),&swap->deposittxid,swap->otherpubs[0],swap->mypubs[0],swap->privkeys[swap->choosei],ap->offer.expiration-INSTANTDEX_LOCKTIME*2,swap->satoshis[1],1); + //instantdex_alicetx(myinfo,iguana_coinfind("BTCD"),swap->altmsigaddr,&swap->altpaymenttxid,swap->pubAm,swap->pubBn,swap->satoshis[0]); + if ( 0 ) + { + int32_t i; + for (i=0; ioffer); i++) + printf("%02x ",((uint8_t *)&ap->offer)[i]); + printf("BTCoffer.%llu\n",(long long)ap->orderid); + } + return(instantdex_sendcmd(myinfo,&ap->offer,newjson,"BTCoffer",GENESIS_PUBKEY,INSTANTDEX_HOPS,swap->deck,sizeof(swap->deck))); + } + }*/ + /*ptr = (void *)bp->scriptsmap; + ind = unspentind << 1; + for (i=0; inumscriptsmaps; i++,ptr+=2) + { + if ( ind == ptr[0] ) + { + printf("bp.[%d] ind.%d offset.%d vs %ld\n",bp->hdrsi,ind,ptr[1],coin->scriptsfilesize); + if ( ptr[1] + sizeof(struct scriptdata) <= coin->scriptsfilesize ) + { + if ( memcmp((void *)((long)coin->scriptsptr + ptr[1] + sizeof(struct scriptdata)),spendscript,spendlen) == 0 ) + { + printf("matched against existing scriptsptr[%d] %d\n",ptr[1],spendlen); + return(ptr[1]); + } + printf("mismatch against existing scriptsptr[%d] %d\n",ptr[1],spendlen); + } + else + { + if ( (fp= fopen(coin->scriptsfname,"rb")) != 0 ) + { + fseek(fp,ptr[1] + sizeof(struct scriptdata),SEEK_SET); + for (i=0; ihdrsi,unspentind,i,ftell(fp),ptr[1],ptr[1]+sizeof(struct scriptdata)+spendlen,c,spendscript[i]); + for (; inumscriptsmaps >= bp->maxscriptsmaps ) + { + bp->scriptsmap = realloc(bp->scriptsmap,(1000+bp->maxscriptsmaps) * (sizeof(offset) + sizeof(ind))); + bp->maxscriptsmaps += 1000; + } + ptr = (void *)((long)bp->scriptsmap + bp->numscriptsmaps*size); + ptr[0] = ind; + ptr[1] = offset; + bp->numscriptsmaps++; + }*/ + + uint32_t iguana_scriptstableadd(struct iguana_info *coin,int32_t spendflag,uint32_t fpos,uint8_t *script,uint16_t scriptlen) + { + struct scriptinfo *ptr; + HASH_FIND(hh,coin->scriptstable[spendflag],script,scriptlen,ptr); + if ( ptr == 0 ) + { + ptr = mycalloc('w',1,sizeof(*ptr) + scriptlen); + ptr->fpos = fpos; + ptr->scriptlen = scriptlen; + memcpy(ptr->script,script,scriptlen); + HASH_ADD(hh,coin->scriptstable[spendflag],script,scriptlen,ptr); + } + return(fpos); + } + + uint32_t iguana_scriptstablefind(struct iguana_info *coin,int32_t spendflag,uint8_t *script,int32_t scriptlen) + { + struct scriptinfo *ptr; + HASH_FIND(hh,coin->scriptstable[spendflag],script,scriptlen,ptr); + if ( ptr != 0 ) + return(ptr->fpos); + else return(0); + } + + long iguana_rwscript(struct iguana_info *coin,int32_t rwflag,void *fileptr,long offset,long filesize,FILE *fp,struct iguana_bundle *bp,uint8_t **scriptptrp,int32_t *lenp,int32_t hdrsi,uint32_t ind,int32_t spendflag) + { + long scriptpos; struct scriptdata data; uint8_t *script = *scriptptrp; + if ( spendflag == 0 && (scriptpos= iguana_scriptstablefind(coin,spendflag,script,*lenp)) != 0 ) + return(scriptpos); + memset(&data,0,sizeof(data)); + if ( rwflag != 0 && fp != 0 && fileptr == 0 ) + { + scriptpos = ftell(fp); + data.ind = ind, data.spendflag = spendflag; + data.hdrsi = hdrsi; + data.scriptlen = *lenp; + if ( fwrite(&data,1,sizeof(data),fp) != sizeof(data) ) + return(-1); + if ( fwrite(script,1,data.scriptlen,fp) != data.scriptlen ) + return(-1); + offset = (uint32_t)ftell(fp); + //printf("spend.%d filesize.%ld wrote.h%d u%d len.%d [%ld,%ld) crc.%08x\n",spendflag,coin->scriptsfilesize[spendflag],hdrsi,ind,data.scriptlen,scriptpos,ftell(fp),calc_crc32(0,script,data.scriptlen)); + } + else if ( rwflag == 0 && fp == 0 && fileptr != 0 ) + { + scriptpos = offset; + if ( offset+sizeof(data) <= filesize ) + { + memcpy(&data,(void *)((long)fileptr + offset),sizeof(data)); + if ( data.scriptlen > 0 && data.scriptlen < *lenp && offset+sizeof(data)+data.scriptlen <= filesize ) + { + if ( data.scriptlen > 0 ) + { + *scriptptrp = script = (void *)((long)fileptr + offset); + offset += data.scriptlen + sizeof(data); + if ( data.hdrsi < coin->bundlescount ) + bp = coin->bundles[data.hdrsi]; + else printf("illegal hdrsi.%d/%d\n",data.hdrsi,coin->bundlescount); + } else printf("illegal scriptlen %d\n",data.scriptlen); + //printf("hdrsi.%d loaded script.%d %u s%d\n",data.hdrsi,data.scriptlen,data.ind,data.spendflag); + } + else if ( data.scriptlen > 0 ) + { + printf("spendlen overflow.%d vs %d\n",data.scriptlen,*lenp); + return(-1); + } + } + else + { + printf("error reading from %ld\n",scriptpos); + return(-1); + } + //printf("hdrsi.%d scriptlen.%d\n",data.hdrsi,data.scriptlen); + *lenp = data.scriptlen; + } + if ( bp != 0 ) + { + //if ( spendflag == 0 ) + iguana_scriptstableadd(coin,spendflag,(uint32_t)scriptpos,script,*lenp); + } + else if ( rwflag == 0 ) + { + printf("null bp for iguana_rwscript hdrsi.%d/%d\n",data.hdrsi,coin->bundlescount); + return(-1); + } + return(offset); + } + + long iguana_initscripts(struct iguana_info *coin) + { + long fpos=0,offset = 0; uint8_t scriptdata[IGUANA_MAXSCRIPTSIZE],*scriptptr; int32_t spendflag,size,n=0; struct scriptdata script; + for (spendflag=0; spendflag<2; spendflag++) + { + portable_mutex_lock(&coin->scripts_mutex[spendflag]); + sprintf(coin->scriptsfname[spendflag],"tmp/%s/%sscripts",coin->symbol,spendflag==0?"":"sig"), OS_portable_path(coin->scriptsfname[spendflag]); + printf("scripts fname.(%s)\n",coin->scriptsfname[spendflag]); + if ( (coin->scriptsptr[spendflag]= OS_mapfile(coin->scriptsfname[spendflag],&coin->scriptsfilesize[spendflag],0)) == 0 ) + { + coin->scriptsfp[spendflag] = fopen(coin->scriptsfname[spendflag],"wb"); + memset(&script,0,sizeof(script)); + fwrite(&script,1,sizeof(script),coin->scriptsfp[spendflag]); + } + else + { + while ( 1 ) + { + size = sizeof(scriptdata); + scriptptr = scriptdata; + if ( (offset= iguana_rwscript(coin,0,coin->scriptsptr[spendflag],offset,coin->scriptsfilesize[spendflag],0,0,&scriptptr,&size,0,0,spendflag)) < 0 ) + break; + else fpos = offset; + n++; + } + coin->scriptsfp[spendflag] = fopen(coin->scriptsfname[spendflag],"ab"); + portable_mutex_unlock(&coin->scripts_mutex[spendflag]); + printf("initialized %d scripts, fpos %ld\n",n,fpos); + return(offset); + } + portable_mutex_unlock(&coin->scripts_mutex[spendflag]); + } + return(-1); + } + + uint32_t iguana_scriptsave(struct iguana_info *coin,struct iguana_bundle *bp,uint32_t ind,int32_t spendflag,uint8_t *script,int32_t scriptlen) + { + FILE *fp; long fpos = 0; + if ( scriptlen > 0 && (fp= coin->scriptsfp[spendflag]) != 0 ) + { + portable_mutex_lock(&coin->scripts_mutex[spendflag]); + fpos = ftell(fp); + if ( iguana_rwscript(coin,1,0,0,0,fp,bp,&script,&scriptlen,bp->hdrsi,ind,spendflag) < 0 ) + { + fseek(fp,fpos,SEEK_SET); + fpos = -1; + printf("error saving script at %ld\n",fpos); + } else fflush(fp); + portable_mutex_unlock(&coin->scripts_mutex[spendflag]); + } else printf("cant scriptsave.%d to (%s).%p scriptlen.%d\n",spendflag,coin->scriptsfname[spendflag],coin->scriptsfp[spendflag],scriptlen); + return((uint32_t)fpos); + } + + long iguana_scriptadd(struct iguana_info *coin,struct iguana_bundle *bp,uint32_t unspentind,int32_t type,uint8_t *spendscript,int32_t spendlen,uint8_t rmd160[20],int32_t vout) + { + static long total,saved; + int32_t scriptlen; char asmstr[IGUANA_MAXSCRIPTSIZE*2+1]; uint8_t script[IGUANA_MAXSCRIPTSIZE]; long fpos=0; struct vin_info V,*vp = &V; + if ( spendlen == 0 ) + { + printf("null script?\n"); + getchar(); + return(0); + } + memset(vp,0,sizeof(*vp)); + asmstr[0] = 0; + total++; + scriptlen = iguana_scriptgen(coin,&vp->M,&vp->N,vp->coinaddr,script,asmstr,rmd160,type,(const struct vin_info *)vp,vout); + if ( scriptlen == spendlen && memcmp(script,spendscript,scriptlen) == 0 ) + return(0); + else + { + saved++; + //if ( (saved % 1000) == 0 ) + printf("add type.%d scriptlen.%d fpos.%ld saved.%ld/%ld\n",type,spendlen,coin->scriptsfp!=0?ftell(coin->scriptsfp[0]):-1,saved,total); + fpos = iguana_scriptsave(coin,bp,unspentind,0,spendscript,spendlen); + } + return(fpos); + } + if ( s->sighash != iguana_vinscriptparse(coin,&V,&sigsize,&pubkeysize,&p2shsize,&suffixlen,vinscript,vinscriptlen) ) + { + static uint64_t counter; + if ( counter++ < 100 ) + { + for (i=0; isighash); + } + return(spendind); + } + //ramchain->H.stacksize += sigsize;// + 1 + (sigsize >= 0xfd)*2; + if ( s->numpubkeys > 0 ) + { + for (i=0; inumpubkeys; i++) + { + if ( (ptr= iguana_hashfind(ramchain,'P',V.signers[i].rmd160)) == 0 ) + { + //printf("from addspend\n"); + //pkind = iguana_ramchain_addpkhash(coin,RAMCHAIN_ARG,V.signers[i].rmd160,0,0,0); + //printf("create pkind.%d from vin\n",pkind); + } else pkind = ptr->hh.itemind; + } + } + if ( 0 && s->numsigs > 0 ) + printf("autoverify numsigs.%d\n",s->numsigs); + + + uint8_t *iguana_scriptptr(struct iguana_info *coin,int32_t *scriptlenp,uint8_t _script[IGUANA_MAXSCRIPTSIZE],uint32_t scriptfpos,uint8_t *scriptdata,int32_t scriptlen,int32_t maxsize,int32_t spendflag) + { + *scriptlenp = scriptlen; + if ( 0 && scriptlen > 0 ) + { + if ( scriptfpos != 0 ) + scriptdata = iguana_scriptfpget(coin,scriptlenp,_script,scriptfpos,spendflag); + } + return(scriptdata); + } + + uint8_t *iguana_scriptfpget(struct iguana_info *coin,int32_t *scriptlenp,uint8_t _script[IGUANA_MAXSCRIPTSIZE],uint32_t scriptoffset,int32_t spendflag) + { + FILE *fp; uint8_t *scriptdata=0; int32_t scriptlen=0; struct scriptdata sdata; + *scriptlenp = 0; + if ( (fp= fopen(coin->scriptsfname[spendflag],"rb")) != 0 ) + { + fseek(fp,scriptoffset,SEEK_SET); + if ( fread(&sdata,1,sizeof(sdata),fp) != sizeof(sdata) ) + printf("iguana_scriptfpget: error reading sdata\n"); + else if ( sdata.scriptlen > 0 && sdata.scriptlen <= IGUANA_MAXSCRIPTSIZE ) + { + if ( fread(_script,1,sdata.scriptlen,fp) == sdata.scriptlen ) + { + scriptdata = _script; + *scriptlenp = scriptlen = sdata.scriptlen; + //printf("raw [%d] offset.%d scriptlen.%d\n",bp->hdrsi,scriptoffset,scriptlen); + //for (i=0; i<16; i++) + // printf("%02x",_script[i]); + //printf(" set script.%d\n",scriptlen); + } + } + fclose(fp); + } + return(scriptdata); + } + //struct scriptdata { uint32_t ind:31,spendflag:1; uint16_t hdrsi,scriptlen; }__attribute__((packed)); + + if ( ramchain->expanded != 0 ) + { + if ( (long)destoffset < (long)srcoffset ) + { + /*sprintf(fname,"sigs/%s/%s",coin->symbol,bits256_str(str,bp->hashes[0])); + if ( (fp= fopen(fname,"wb")) != 0 ) + { + if ( ramchain->H.stacksize > 0 ) + { + if ( fwrite(srcoffset,1,ramchain->H.stacksize,fp) != ramchain->H.stacksize ) + printf("error writing %d sigs to %s\n",ramchain->H.stacksize,fname); + } + else + { + if ( fwrite(&izero,1,sizeof(izero),fp) != sizeof(izero) ) + printf("error writing izero to %s\n",fname); + } + fclose(fp); + } + if ( (ramchain->sigsfileptr= OS_mapfile(fname,&ramchain->sigsfilesize,0)) == 0 ) + return(-1); + printf("%s bp.[%d] ht.%d stacksize.%u filesize.%u\n",fname,bp->hdrsi,bp->bundleheight,ramchain->H.stacksize,(uint32_t)ramchain->sigsfilesize);*/ + //for (i=0; iH.stacksize; i++) + // c = *srcoffset, *destoffset++ = c, *srcoffset++ = 0; + } else printf("smashed stack? dest.%ld vs src %ld offset.%u stacksize.%u space.%u\n",(long)destoffset,(long)srcoffset,(uint32_t)ramchain->H.scriptoffset,(uint32_t)ramchain->H.stacksize,(uint32_t)ramchain->H.scriptoffset); + } + // if file exists and is valid, load and then process only the incremental + long iguana_spentsfile(struct iguana_info *coin,int32_t n) + { + int32_t i,iter,allocated = 0; long filesize,total,count; struct iguana_bundleind *spents = 0; struct iguana_ramchain *ramchain; char fname[1024]; struct iguana_bundle *bp; FILE *fp; + fname[0] = 0; + for (total=iter=0; iter<2; iter++) + { + for (count=i=0; ibundles[i]) != 0 ) + { + ramchain = &bp->ramchain; + if ( ramchain->H.data != 0 ) + { + if ( iter == 1 ) + { + ramchain->spents = &spents[count]; + //printf("bp.[%d] count.%ld %p\n",i,count,ramchain->spents); + if ( allocated != 0 && iguana_spentsinit(coin,spents,bp,ramchain) < 0 ) + { + printf("error initializing spents bp.%d\n",i); + exit(-1); + } + } + count += ramchain->H.data->numunspents; + } else break; + } else return(-1); + } + if ( i < n ) + n = (i + 1); + sprintf(fname,"DB/%s/spents_%d.%ld",coin->symbol,n,count); + printf("%s total unspents.%ld\n",fname,count); + if ( iter == 0 ) + { + total = count; + if ( (spents= OS_filestr(&filesize,fname)) == 0 ) + spents = calloc(total,sizeof(*spents)), allocated = 1; + } + else if ( total != count ) + printf("%s total.%ld != count.%ld\n",fname,total,count); + } + if ( allocated != 0 && fname[0] != 0 && (fp= fopen(fname,"wb")) != 0 ) + { + fwrite(spents,total,sizeof(*spents),fp); + fclose(fp); + } + return(total); + } + + int32_t iguana_spentsinit(struct iguana_info *coin,struct iguana_bundleind *spents,struct iguana_bundle *bp,struct iguana_ramchain *ramchain) + { + int32_t spendind,n,max,hdrsi,errs,flag; uint32_t unspentind; struct iguana_bundle *spentbp; + struct iguana_spend *S; bits256 prevhash; + S = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Soffset); + max = ramchain->H.data->numunspents; + n = ramchain->H.data->numspends; + for (spendind=1,errs=0; spendindhdrsi; + if ( (spentbp= iguana_spent(coin,&prevhash,&unspentind,ramchain,bp->hdrsi,&S[spendind])) != 0 ) + { + spentbp->ramchain.spents[unspentind].ind = spendind; + spentbp->ramchain.spents[unspentind].hdrsi = bp->hdrsi; + flag = 1; + if ( S[spendind].external == 0 && spentbp != bp ) + printf("spentsinit unexpected spendbp: %p bp.[%d] U%d <- S%d.[%d] [%p %p %p]\n",&spentbp->ramchain.spents[unspentind],hdrsi,unspentind,spendind,bp->hdrsi,coin->bundles[0],coin->bundles[1],coin->bundles[2]); + } + else if ( S[spendind].prevout < 0 ) + flag = 1; + else printf("unresolved spendind.%d hdrsi.%d\n",spendind,bp->hdrsi); + if ( flag == 0 ) + errs++; + } + printf("processed %d spendinds for bp.[%d] -> errs.%d\n",spendind,bp->hdrsi,errs); + return(-errs); + } + if ( bp != currentbp ) + { + //printf("initial requests for hdrs.%d\n",bp->hdrsi); + pend = queue_size(&coin->priorityQ) + queue_size(&coin->blocksQ); + for (i=0; ipeers.active[i].pendblocks; + if ( 0 && pend >= IGUANA_BUNDLELOOP ) + { + //for (i=better=0; ibundlescount; i++) + // if ( coin->bundles[i] != 0 && coin->bundles[i]->numsaved > bp->numsaved ) + // better++; + //if ( better > coin->peers.numranked ) + { + //usleep(10000); + //printf("SKIP pend.%d vs %d: better.%d ITERATE bundle.%d n.%d r.%d s.%d finished.%d timelimit.%d\n",pend,coin->MAXPENDING*coin->peers.numranked,better,bp->bundleheight,bp->n,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit); + iguana_bundleQ(coin,bp,1000); + return(0); + } + } + counter = iguana_bundlekick(coin,bp,starti,max); + } + if ( req == 0 && 0 ) + { + if ( 1 )//(rand() % 10) == 0 ) + flag = iguana_neargap(coin,addr); + else if ( 0 && (bp= addr->bp) != 0 && bp->rank != 0 && addr->pendblocks < limit ) + { + r = rand(); + for (j=0; jn; j++) + { + i = (r + j) % bp->n; + if ( (block= bp->blocks[i]) != 0 && block->numrequests == bp->minrequests && block->fpipbits == 0 && block->queued == 0 ) + { + printf("peer.%s BPranked.%d [%d:%d] pending.%d numreqs.%d\n",addr->ipaddr,bp->rank,bp->hdrsi,i,addr->pendblocks,block->numrequests); + block->numrequests++; + flag++; + iguana_sendblockreqPT(coin,addr,bp,i,block->RO.hash2,0); + break; + } + } + } + } + + int32_t iguana_neargap(struct iguana_info *coin,struct iguana_peer *addr) + { + struct iguana_block *block,*bestblock = 0; struct iguana_bundle *bp,*bestbp = 0; + int32_t height,hdrsi,i,j,n,bundlei,gap,besti = -1; uint32_t r; + if ( addr->rank > 0 ) + { + n = coin->peers.numranked * 2; + gap = addr->rank * (1 + n + coin->peers.numranked) + coin->peers.numranked; + for (i=0; ibundlescount; i++) + if ( (bp= coin->bundles[i]) == 0 || bp->emitfinish == 0 ) + break; + height = (i * coin->chain->bundlesize); + r = rand(); + for (i=0; ichain->bundlesize; + if ( (bp= coin->bundles[hdrsi]) != 0 ) + { + bundlei = (height + j) % coin->chain->bundlesize; + if ( (block= bp->blocks[bundlei]) != 0 && block->fpipbits == 0 && block->queued == 0 ) + { + if ( block->numrequests == bp->minrequests ) + { + bestblock = block; + bestbp = bp; + besti = bundlei; + break; + } + else if ( bestblock == 0 || block->numrequests < bestblock->numrequests ) + { + bestblock = block; + bestbp = bp; + besti = bundlei; + } + } + } + } + if ( bestblock != 0 ) + { + printf("near hwm.%d gap.%d peer.%s bpranked.%d [%d:%d] pending.%d numreqs.%d\n",height,j,addr->ipaddr,bestbp->rank,bestbp->hdrsi,besti,addr->pendblocks,bestblock->numrequests); + bestblock->numrequests++; + iguana_sendblockreqPT(coin,addr,bestbp,besti,bestblock->RO.hash2,0); + return(1); + } + } + return(0); + } + /*if ( doneval != maxval ) + { + r = rand() % numpeers; + oldest = 0; + for (i=0; i 0 ) + { + for (i=j; in; i+=numpeers) + if ( (block= bp->blocks[i]) != 0 && block->fpipbits == 0 ) + { + if ( oldest == 0 || block->issued < oldest->issued ) + oldest = block; + if ( now > block->issued+10+60*(bp!=coin->current) ) + { + for (k=0; k 0 && (addr= coin->peers.ranked[z]) != 0 ) + { + if ( bp == coin->current ) + printf("send [%d:%d] to addr[%d]\n",bp->hdrsi,block->bundlei,z); + block->issued = (uint32_t)time(NULL); + counter++; + iguana_sendblockreqPT(coin,addr,bp,block->bundlei,block->RO.hash2,0); + break; + } + } + } + } + } + } + }*/ + //return(counter); + /*if ( 0 && time(NULL) > bp->lastspeculative+60 ) + { + for (i=1,counter=0; in; i++) + { + if ( (block= bp->blocks[i]) == 0 || block->fpos < 0 || block->fpipbits == 0 ) + { + if ( bp->speculative != 0 && bits256_nonz(bp->hashes[i]) == 0 && bits256_nonz(bp->speculative[i]) > 0 && i < bp->numspec ) + iguana_blockQ("speculate0",coin,0,-2,bp->speculative[i],0), counter++; + else if ( bits256_nonz(bp->hashes[i]) != 0 ) + iguana_blockQ("speculate1",coin,0,-3,bp->hashes[i],0), counter++; + } + } + if ( counter != 0 ) + printf("SPECULATIVE issue.%d bp.[%d]\n",counter,bp->hdrsi); + bp->lastspeculative = (uint32_t)time(NULL); + }*/ + //ramchain->A = OS_filestr(&filesize,fname); + //if ( filesize != sizeof(*ramchain->A)*ramchain->H.data->numpkinds ) + // printf("%s unexpected filesize %ld vs %ld\n",fname,filesize,sizeof(*ramchain->A)*ramchain->H.data->numpkinds); + sprintf(fname,"DB/%s/accounts/lastspends.%d",coin->symbol,ramchain->H.data->height); + //ramchain->Uextras = OS_filestr(&filesize,fname); + //if ( filesize != sizeof(*ramchain->Uextras)*ramchain->H.data->numpkinds ) + // printf("%s unexpected filesize %ld vs %ld\n",fname,filesize,sizeof(*ramchain->Uextras)*ramchain->H.data->numpkinds); + //if ( ramchain->A == 0 ) + ramchain->A = myaligned_alloc(sizeof(*ramchain->A) * ramchain->H.data->numpkinds); + //if ( ramchain->Uextras == 0 ) + ramchain->Uextras = myaligned_alloc(sizeof(*ramchain->Uextras) * ramchain->H.data->numunspents); + //printf("hashmem.%p A allocated.%p numpkinds.%d %ld\n",hashmem,ramchain->A,ramchain->H.data->numpkinds,sizeof(struct iguana_account)*ramchain->H.data->numpkinds); + //ramchain->P2 = (hashmem != 0) ? iguana_memalloc(hashmem,sizeof(struct iguana_pkextra) * ramchain->H.data->numpkinds,1) : mycalloc('2',ramchain->H.data->numpkinds,sizeof(struct iguana_pkextra)); + ///ramchain->U2 = (hashmem != 0) ? iguana_memalloc(hashmem,sizeof(struct iguana_Uextra) * ramchain->H.data->numunspents,1) : mycalloc('3',ramchain->H.data->numunspents,sizeof(struct iguana_Uextra)); + //printf("iguana_ramchain_extras A.%p:%p U2.%p:%p P2.%p:%p\n",ramchain->A,ramchain->roA,ramchain->U2,ramchain->roU2,ramchain->P2,ramchain->roP2); + //memcpy(ramchain->U2,ramchain->roU2,sizeof(*ramchain->U2) * ramchain->H.data->numunspents); + //memcpy(ramchain->P2,ramchain->roP2,sizeof(*ramchain->P2) * ramchain->H.data->numpkinds); + + int32_t iguana_spendfind(struct iguana_info *coin,struct iguana_bundle *bp,uint32_t spendind,int32_t emit) + { + struct iguana_unspent *u,*spentU; struct iguana_spend *S,*s; struct iguana_ramchain *ramchain; + struct iguana_bundle *spentbp; struct iguana_txid *T; + ramchain = &bp->ramchain; + if ( ramchain->H.data == 0 || (n= ramchain->H.data->numspends) < 1 || ramchain->Xspendinds == 0 ) + return(-1); + S = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Soffset); + s = &S[spendind]; + u = 0; + unspentind = 0; + hdrsi = -1; + spentbp = 0; + if ( s->external != 0 && s->prevout >= 0 ) + { + if ( emit >= ramchain->numXspends ) + errs++; + else + { + h = ramchain->Xspendinds[emit].height; + unspentind = ramchain->Xspendinds[emit].ind; + if ( (hdrsi= ramchain->Xspendinds[emit].hdrsi) >= 0 && hdrsi <= bp->hdrsi ) + spentbp = coin->bundles[hdrsi]; + else + { + printf("iguana_balancegen[%d] s.%d illegal hdrsi.%d emit.%d\n",bp->hdrsi,spendind,hdrsi,emit); + return(-1); + } + //printf("%d of %d: [%d] X spendind.%d -> (%d u%d)\n",emit,ramchain->numXspends,bp->hdrsi,spendind,hdrsi,unspentind); + emit++; + } + } + else if ( s->prevout >= 0 ) + { + spentbp = bp; + hdrsi = bp->hdrsi; + h = refheight; + if ( (txidind= s->spendtxidind) != 0 && txidind < spentbp->ramchain.H.data->numtxids ) + { + T = (void *)(long)((long)spentbp->ramchain.H.data + spentbp->ramchain.H.data->Toffset); + unspentind = T[txidind].firstvout + s->prevout; + if ( unspentind == 0 || unspentind >= spentbp->ramchain.H.data->numunspents ) + { + printf("iguana_balancegen unspentind overflow %u vs %u\n",unspentind,spentbp->ramchain.H.data->numunspents); + return(-1); + } + //printf("txidind.%d 1st.%d prevout.%d\n",txidind,T[txidind].firstvout,s->prevout); + } + else + { + printf("iguana_balancegen txidind overflow %u vs %u\n",txidind,spentbp->ramchain.H.data->numtxids); + return(-1); + } + //printf("[%d] spendind.%d -> (hdrsi.%d u%d)\n",bp->hdrsi,spendind,hdrsi,unspentind); + } + else return(0); + if ( (spendind & 0xff) == 1 ) + now = (uint32_t)time(NULL); + if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) + { + if ( now > spentbp->lastprefetch+20 || (spentbp->dirty % 50000) == 0 ) + { + //printf("current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); + iguana_ramchain_prefetch(coin,&spentbp->ramchain); + spentbp->lastprefetch = now; + } + } + + } + if ( 0 && coin->blocks.hwmchain.height > coin->chain->bundlesize && bp->hdrsi == coin->blocks.hwmchain.height/coin->chain->bundlesize ) + { + for (bundlei=0; bundlein; bundlei++) + { + checki = iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[bundlei],bundlei>0?bp->hashes[bundlei-1]:zero,1); + if ( checki == bundlei ) + { + if ( (fp= fopen(fname,"rb")) != 0 ) + fclose(fp); + else break; + } + } + if ( bp == coin->current && (bp->ramchain.H.data == 0 || bp->ramchain.H.data->numblocks != bundlei) ) + { + printf("RT bundls\n"); + if ( iguana_bundlesaveHT(coin,mem,memB,bp,(uint32_t)time(NULL)) == 0 ) + { + + } + } + } + /*for (j=0; jRO.prev_block)) != 0 ) + { + printf("iguana_recvblock got prev block [%d:%d]\n",bp->hdrsi,bundlei); + if ( bundlei < bp->n-1 ) + bundlei++; + else bp = 0, bundlei = -2; + /*if ( bits256_cmp(prev->RO.hash2,block->RO.prev_block) == 0 && bundlei < bp->n-1 ) + { + bundlei++; + iguana_bundlehash2add(coin,&tmpblock,bp,bundlei,block->RO.hash2); + if ( tmpblock == block ) + { + printf("[%d:%d] speculative block.%p\n",bp->hdrsi,bundlei,block); + bp->blocks[bundlei] = block; + bp->hashes[bundlei] = block->RO.hash2; + block->bundlei = bundlei; + block->hdrsi = bp->hdrsi; + block->mainchain = prev->mainchain; + } else printf("error adding speculative prev [%d:%d]\n",bp->hdrsi,bundlei); + }*/ + } + /*for (i=coin->bundlescount-1; i>=0; i--) + { + //if ( coin->bundles[i] != 0 ) + // printf("compare vs %s\n",bits256_str(str,coin->bundles[i]->hashes[0])); + if ( coin->bundles[i] != 0 && bits256_cmp(origblock->RO.prev_block,coin->bundles[i]->hashes[0]) == 0 ) + { + bp = coin->bundles[i]; + bundlei = 1; + iguana_bundlehash2add(coin,&block,bp,bundlei,origblock->RO.hash2); + printf("iguana_recvblock [%d] bundlehashadd set.%d block.%p\n",i,bundlei,block); + if ( block != 0 ) + { + bp->blocks[bundlei] = block; + block->bundlei = bundlei; + block->hdrsi = bp->hdrsi; + } + break; + } + }*/ + //printf("i.%d ref prev.(%s)\n",i,bits256_str(str,origblock->RO.prev_block)); + /*if ( checki != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) + { + printf("iguana_bundlecalcs.(%s) illegal hdrsi.%d bundlei.%d checki.%d\n",fname,hdrsi,bundlei,checki); + continue; + }*/ + if ( 0 && coin->current == bp )//&& (bp->isRT != 0 || bp->hdrsi > coin->bundlescount-3) ) + { + //checki = iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[bundlei],bundlei>0?bp->hashes[bundlei-1]:zero,1); + if ( (fp= fopen(fname,"rb")) != 0 ) + { + fseek(fp,0,SEEK_END); + block->RO.recvlen = (uint32_t)ftell(fp); + block->fpipbits = 1; + block->fpos = 0; + //printf("fp.[%d:%d] len.%d\n",hdrsi,bundlei,block->RO.recvlen); + fclose(fp); + } + else + { + //char str[65]; printf("missing.(%s) issue.%s\n",fname,bits256_str(str,bp->hashes[bundlei])); + block->RO.recvlen = 0; + block->fpipbits = 0; + block->fpos = -1; + //iguana_blockQ("missing",coin,0,-1,block->RO.hash2,1); + } + } + int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int32_t max,int32_t timelimit) + { + int32_t i,j,k,peerid,doneflag,len,forceflag,saved,starti,lag,doneval,nonz,total=0,maxval,numpeers,laggard=0,flag=0,finished=0,peercounts[IGUANA_MAXPEERS],donecounts[IGUANA_MAXPEERS],priority,counter = 0; + struct iguana_peer *addr; uint32_t now; struct iguana_block *block; + bits256 hashes[50],hash2; uint8_t serialized[sizeof(hashes) + 256]; + if ( bp == 0 ) + return(0); + now = (uint32_t)time(NULL); + memset(peercounts,0,sizeof(peercounts)); + memset(donecounts,0,sizeof(donecounts)); + if ( coin->current != 0 ) + starti = coin->current->hdrsi; + else starti = 0; + priority = (bp->hdrsi < starti + coin->peers.numranked); + if ( strcmp("BTC",coin->symbol) == 0 ) + lag = 10 + (bp->hdrsi - starti); + else lag = 3 + (bp->hdrsi - starti)/10; + if ( coin->current != bp ) + lag *= 3; + if ( (numpeers= coin->peers.numranked) > 3 && 0 )//(bp->numhashes == bp->n || bp->speculative != 0) )//&& bp->currentflag < bp->n ) + { + if ( numpeers > 0xff ) + numpeers = 0xff; // fit into 8 bitfield + if ( bp->currentflag == 0 ) + bp->currenttime = now; + if ( bp->numhashes >= 1 ) + { + for (j=0; jpeers.ranked[j]) != 0 && addr->dead == 0 && addr->usock >= 0 && addr->msgcounts.verack != 0 ) + { + now = (uint32_t)time(NULL); + for (i=j,k=doneval=maxval=0; in&&khashes[i]) != 0 ) + { + hash2 = bp->hashes[i]; + if ( (block= bp->blocks[i]) != 0 ) + { + if ( (peerid= block->peerid) == 0 ) + { + //printf("<%d>.%d ",i,j); + if ( block->fpipbits != 0 || bp->speculativecache[i] != 0 ) + doneflag = 1; + } + } + } + else if ( bp->speculative != 0 && i < bp->numspec && bits256_nonz(bp->speculative[i]) != 0 ) + { + hash2 = bp->speculative[i]; + if ( bp->speculativecache[i] != 0 ) + doneflag = peerid = 1; + } + if ( doneflag == 0 ) + { + hashes[k++] = hash2; + bp->issued[i] = now; + if ( block != 0 ) + { + block->issued = now; + block->peerid = j + 1; + block->numrequests++; + } + } + else + { + doneflag = 1; + if ( block != 0 ) + { + block->peerid = 1; + block->numrequests++; + } + } + if ( bits256_nonz(hash2) != 0 ) + { + if ( peerid > 1 ) + { + total++; + if ( doneflag != 0 ) + { + donecounts[peerid - 1]++; + if ( donecounts[peerid - 1] > doneval ) + doneval = donecounts[peerid - 1]; + } + else + { + peercounts[peerid - 1]++; + if ( peercounts[peerid - 1] > maxval ) + maxval = peercounts[peerid - 1]; + } + } + } + } + if ( k > 0 ) + { + if ( (len= iguana_getdata(coin,serialized,MSG_BLOCK,hashes,k)) > 0 ) + { + iguana_send(coin,addr,serialized,len); + counter += k; + coin->numreqsent += k; + addr->pendblocks += k; + addr->pendtime = (uint32_t)time(NULL); + bp->currentflag += k; + } + //printf("a%d/%d ",j,k); + } + } + } + //printf("doneval.%d maxval.%d\n",doneval,maxval); + if ( 0 && priority != 0 ) + { + double threshold; + for (i=nonz=0; i threshold ) + laggard++; + if ( peercounts[i] == 0 && donecounts[i] > threshold ) + finished++; + } + if ( finished > laggard*10 && numpeers > 2*laggard && laggard > 0 ) + { + for (i=0; i threshold && (addr= coin->peers.ranked[i]) != 0 && now > bp->currenttime+lag && addr->dead == 0 ) + { + if ( (numpeers > 64 || addr->laggard++ > 13) && coin->current == bp ) + { + addr->dead = (uint32_t)time(NULL); + addr->rank = 0; + } + for (j=0; jn; j++) + { + if ( ((block= bp->blocks[j]) != 0 && block->peerid == i && block->fpipbits == 0) || bp->speculativecache[i] == 0 ) + { + if ( bp == coin->current ) + printf("%d ",j); + flag++; + counter++; + if ( block != 0 ) + { + block->issued = now; + block->peerid = 0; + iguana_blockQ("kick",coin,bp,j,block->RO.hash2,0);//bp == coin->current); + } else iguana_blockQ("kick",coin,bp,j,block->RO.hash2,0);//bp == coin->current); + if ( bp == coin->current ) + bp->issued[i] = now; + } + } + if ( flag != 0 && bp == coin->current ) + printf("slow peer.%d dead.%u (%s) reissued.%d [%d]\n",i,addr->dead,addr->ipaddr,flag,bp->hdrsi); + } + } + } + if ( 0 && laggard != 0 ) + { + for (i=0; ihdrsi,finished,laggard,threshold); + } + } + } + for (i=0; in; i++) + { + if ( 0 && (block= bp->blocks[i]) != 0 && iguana_blockstatus(coin,block) == 0 && bp->speculativecache[i] == 0 ) + { + if ( now > block->issued+lag ) + { + counter++; + saved = block->issued; + if ( bp == coin->current ) + forceflag = (now > block->issued + lag); + else forceflag = (now > block->issued + 10*lag); + if ( priority != 0 ) + { + printf("kick.[%d:%d] ",bp->hdrsi,i); + iguana_blockQ("kicka",coin,bp,i,block->RO.hash2,0*forceflag); + if ( forceflag != 0 && (addr= coin->peers.ranked[rand() % numpeers]) != 0 ) + iguana_sendblockreqPT(coin,addr,bp,i,block->RO.hash2,0); + } else iguana_blockQ("kickb",coin,bp,i,block->RO.hash2,0*forceflag); + if ( forceflag != 0 ) + bp->issued[i] = block->issued = now; + else bp->issued[i] = block->issued = saved; + flag++; + } //else printf("%d ",now - block->issued); + } + } + if ( flag != 0 && priority != 0 && laggard != 0 && coin->current == bp ) + printf("[%d] reissued.%d currentflag.%d ht.%d s.%d finished.%d most.%d laggards.%d maxunfinished.%d\n",bp->hdrsi,flag,bp->currentflag,bp->bundleheight,bp->numsaved,finished,doneval,laggard,maxval); + } + if ( bp == coin->current ) + return(counter); + } + for (i=0; in; i++) + { + if ( (block= bp->blocks[i]) != 0 && bp->speculativecache[i] == 0 ) + { + if ( block->fpipbits == 0 || block->fpos < 0 )// || block->RO.recvlen == 0 ) + { + if ( now > block->issued+lag ) + { + block->numrequests++; + if ( bp == coin->current ) + printf("[%d:%d].%x ",bp->hdrsi,i,block->fpipbits); + iguana_blockQ("kickc",coin,bp,i,block->RO.hash2,0);//bp == coin->current && now > block->issued+lag); + bp->issued[i] = block->issued = now; + counter++; + if ( --max <= 0 ) + break; + } + } + } + else if ( block != 0 && block->fpipbits == 0 && bits256_nonz(bp->hashes[i]) != 0 && now > bp->issued[i]+lag ) + { + if ( bp == coin->current ) + printf("b[%d:%d].%x ",bp->hdrsi,i,block->fpipbits); + iguana_blockQ("kickd",coin,bp,i,bp->hashes[i],0);//bp == coin->current && now > bp->issued[i]+lag*3); + bp->issued[i] = now; + counter++; + } + else if ( bp->speculative != 0 && bits256_nonz(bp->speculative[i]) != 0 && now > bp->issued[i]+lag ) + { + if ( bp == coin->current ) + printf("i[%d:%d] ",bp->hdrsi,i); + iguana_blockQ("kicke",coin,bp,i,bp->speculative[i],0); + bp->issued[i] = now; + counter++; + } + } + return(counter); + } + /*else if ( 0 && bp == coin->current && bp->speculativecache[bundlei] == 0 ) + { + char str[65]; printf("missing prev_block [%d:%d] %s\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei])); + if ( block != 0 ) + { + block->RO.recvlen = 0; + block->fpipbits = 0; + block->fpos = -1; + } + else if ( now > bp->issued[bundlei]+13 ) + iguana_blockQ("missing",coin,bp,bundlei,bp->hashes[bundlei],1); + }*/ + } + /*else + { + char str[65],str2[65]; printf(" mismatched [%d:%d] %s vs %s\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei]),bits256_str(str2,block->RO.hash2)); + //iguana_blockQ("missing",coin,0,-1,block->RO.hash2,1); + bp->issued[bundlei] = 0; + bp->blocks[bundlei] = 0; + memset(bp->hashes[bundlei].bytes,0,sizeof(bp->hashes[bundlei])); + OS_removefile(fname,0); + }*/ + /*if ( 0 && bp->numhashes < bp->n && bp->speculative != 0 ) + { + for (j=1; jnumspec&&jn; j++) + { + if ( (block= bp->blocks[j]) == 0 ) + { + if ( bits256_nonz(bp->hashes[j]) != 0 ) + block = iguana_blockfind(coin,bp->hashes[j]); + else if ( bits256_nonz(bp->speculative[j]) != 0 ) + { + if ( (block= iguana_blockfind(coin,bp->speculative[j])) == 0 ) + block = iguana_blockhashset(coin,-1,bp->speculative[j],1); + } + } + else if ( bits256_nonz(block->RO.prev_block) != 0 && iguana_blockstatus(coin,block) != 0 ) + continue; + prev = bp->blocks[j-1]; + //printf("[%d:%d] prev.%p nonz.%d speculative.%d block.%p\n",bp->hdrsi,j,bp->blocks[j-1],bits256_nonz(bp->hashes[j]),bits256_nonz(bp->speculative[j]),bp->blocks[j]); + if ( block != 0 && bp->blocks[j] == 0 ) //prev != 0 && + { + //char str2[65]; printf("[%d:%d] prev.%p nonz.%d speculative.%d prev.%s vs %s ipbits.%x q.%d\n",bp->hdrsi,j,bp->blocks[j-1],bits256_nonz(bp->hashes[j]),bits256_nonz(bp->speculative[j]),bits256_str(str,prev->RO.hash2),bits256_str(str2,block->RO.prev_block),block->fpipbits,block->queued); + if ( iguana_blockstatus(coin,block) == 0 && bp->speculativecache[j] == 0 ) + { + if ( block->req != 0 ) + { + block->queued = 1; + queue_enqueue("cacheQ",&coin->cacheQ,&block->req->DL,0); + block->req = 0; + //printf("submit cached [%d:%d]\n",bp->hdrsi,j); + } + else if ( now > block->issued+10 ) + { + block->issued = now; + //printf("submit speculative [%d:%d]\n",bp->hdrsi,j); + iguana_blockQ("spec",coin,0,-1,block->RO.hash2,0); + } + } + } // else break; + } + }*/ + int32_t checki,hdrsi,havefile,missing,recvlen; char fname[1024]; FILE *fp; + static bits256 zero; + //if ( bp->speculative != 0 ) + { + now = (int32_t)time(NULL); + for (j=havefile=missing=0; jn; j++) + { + if ( bits256_nonz(bp->hashes[j]) != 0 ) + hash2 = bp->hashes[j]; + else if ( bp->speculative != 0 ) + hash2 = bp->speculative[j]; + if ( bits256_nonz(hash2) == 0 ) + { + missing++; + continue; + } + checki = iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,hash2,zero,1,0); + if ( 1 && (fp= fopen(fname,"rb")) != 0 ) + { + havefile++; + fclose(fp); + continue; + } + //if ( (block= bp->blocks[j]) != 0 && block->fpipbits != 0 && block->fpos >= 0 && block->RO.recvlen > 0 && bits256_nonz(block->RO.prev_block) != 0 ) + // continue; + missing++; + if ( bp->speculativecache[j] != 0 ) + { + block = iguana_blockfind(coin,bp->speculative[j]); + if ( block != 0 ) + block->queued = 1; + if ( bp->speculativecache[j] != 0 && block != 0 ) + xx else if ( bits256_nonz(bp->hashes[j]) != 0 ) + { + iguana_blockQ("currentstop",coin,bp,j,hash2,0); + + } + continue; + } + if ( bp == coin->current && (now > bp->issued[j]+3 || (rand() % 10) == 0) ) + { + fprintf(stderr,"-[%d:%d].%d ",bp->hdrsi,j,now-bp->issued[j]); + struct iguana_peer *addr; int32_t r; + if ( (rand() % 10) == 0 && (r= coin->peers.numranked) != 0 && (addr= coin->peers.ranked[rand() % r]) != 0 && addr->dead == 0 && addr->usock >= 0 ) + iguana_sendblockreqPT(coin,addr,bp,j,hash2,0); + else iguana_blockQ("currentstop",coin,bp,j,hash2,1); + //fprintf(stderr,"currentstop [%d:%d]\n",bp->hdrsi,j); + bp->issued[j] = now; + } + } + if ( bp == coin->current ) + fprintf(stderr,"[%d] check numcached.%d numhashes.%d numsaved.%d havefile.%d missing.%d\n",bp->hdrsi,bp->numcached,bp->numhashes,bp->numsaved,havefile,missing); + } + if ( bp->speculative != 0 && missing == 0 ) + { + hash2 = bp->hashes[0]; + for (i=1; in; i++) + { + /*if ( bits256_nonz(bp->speculative[i]) != 0 ) + block = iguana_blockfind(coin,bp->speculative[i]); + else if ( bits256_nonz(bp->hashes[i]) != 0 ) + block = iguana_blockfind(coin,bp->hashes[i]);*/ + if ( (block= bp->blocks[i]) == 0 || bits256_cmp(block->RO.prev_block,hash2) != 0 ) + { + char str[65],str2[65]; + printf("error with speculative prev at i.%d block.%p %s vs %s\n",i,block,bits256_str(str,bp->hashes[i]),bits256_str(str2,hash2)); + if ( block != 0 ) + { + checki = iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[i],zero,1,0); + if ( fname[0] != 0 ) + OS_removefile(fname,0); + printf(">>>>>>> block contents error at ht.%d (%s)\n",bp->bundleheight+i,fname); + //char str[65]; patch.(%s) and reissue %s checki.%d vs %d\n",block->fpipbits,bp->bundleheight+i,bits256_str(str,block->RO.prev_block),fname,checki,i); + block->fpipbits = 0; + block->fpos = -1; + block->queued = 0; + block->RO.recvlen = 0; + } + break; + } + hash2 = block->RO.hash2; + } + if ( i == bp->n && iguana_bundlefinalize(coin,bp,&coin->MEM,coin->MEMB) == 0 ) + { + //free(bp->speculative); + //bp->speculative = 0; + } + } + /*if ( bp->speculative != 0 && missing == 0 ) + { + if ( i == bp->n ) + { + printf("have complete speculative bundle!\n"); + for (i=1; in; i++) + { + if ( bits256_nonz(bp->speculative[i]) != 0 && bits256_nonz(bp->hashes[i]) != 0 ) + { + if ( (block= iguana_blockfind(coin,bp->speculative[i])) != 0 ) + { + block->bundlei = i; + block->hdrsi = bp->hdrsi; + bp->blocks[i] = block; + printf("bundlehashadd set.%d\n",i); + iguana_bundlehash2add(coin,0,bp,i,bp->speculative[i]); + } + } + } + } + }*/ + //bp->rank = 0; + /*if ( bp->speculative != 0 )//&& bp == coin->current ) + { + now = (uint32_t)time(NULL); + for (i=1; inumspec&&in; i++) + { + if ( bits256_nonz(bp->hashes[i]) == 0 && bits256_nonz(bp->speculative[i]) != 0 ) + { + if ( (block= bp->blocks[i]) == 0 && bp->speculativecache[i] == 0 && now > bp->issued[i]+60 ) + { + //printf("speculative.[%d:%d]\n",bp->hdrsi,i); + iguana_blockQ("speculative",coin,bp,-i,bp->speculative[i],0);//now > bp->issued[i]+60); + bp->issued[i] = now; + continue; + } + } + else if ( 0 && (block= bp->blocks[i]) != 0 && bp->speculativecache[i] == 0 && block->fpipbits == 0 && now > bp->issued[i]+60 ) + { + printf("speculativeB.[%d:%d]\n",bp->hdrsi,i); + iguana_blockQ("speculativeB",coin,bp,i,block->RO.hash2,1); + continue; + } + if ( bits256_nonz(bp->speculative[i]) != 0 && now > bp->issued[i]+13 ) + { + //printf("speculativeC [%d:%d]\n",bp->hdrsi,i); + iguana_blockQ("speculativeC",coin,bp,-i,bp->speculative[i],0); + bp->issued[i] = now; + } + } + }*/ + if ( 0 && block->newtx != 0 ) + { + if ( (prev= iguana_blockfind(coin,block->RO.prev_block)) == 0 ) + prev = iguana_blockhashset(coin,-1,block->RO.prev_block,1); + width = coin->chain->bundlesize; + while ( coin->active != 0 && prev != 0 && width-- > 0 ) + { + if ( prev->fpipbits == 0 || prev->RO.recvlen == 0 || prev->fpos < 0 || bits256_nonz(prev->RO.prev_block) == 0 ) + { + //printf("width.%d auto prev newtx %s ht.%d\n",width,bits256_str(str,prev->RO.hash2),prev->height); + prev->newtx = 1; + iguana_blockQ("autoprev",coin,0,-1,prev->RO.hash2,0); + } + tmpblock = prev; + if ( bits256_nonz(prev->RO.prev_block) != 0 ) + { + if ( (prev = iguana_blockhashset(coin,-1,prev->RO.prev_block,1)) != 0 ) + prev->newtx = 1; + prev->hh.next = tmpblock; + if ( prev->mainchain != 0 ) + { + while ( tmpblock != 0 && _iguana_chainlink(coin,tmpblock) != 0 ) + { + printf("NEWHWM.%d\n",tmpblock->height); + tmpblock = tmpblock->hh.next; + } + break; + } + } else prev = 0; + } + } + /*else if ( bp != 0 && bits256_nonz(bp->hashes[bundlei]) == 0 && time(NULL) > bp->issued[bundlei]+60 ) + { + if ( bundlei > 0 && bits256_nonz(bp->hashes[bundlei+1]) != 0 ) + { + if ( (block= iguana_blockfind(coin,bp->hashes[bundlei+1])) != 0 && bits256_nonz(block->RO.prev_block) != 0 ) + { + bp->hashes[bundlei] = block->RO.prev_block; + printf("reqblock [%d:%d]\n",bp->hdrsi,bundlei); + iguana_blockQ("reqblocks1",coin,bp,bundlei,bp->hashes[bundlei],0); + } + } + }*/ + else if ( 0 && bp != 0 && time(NULL) > bp->hdrtime+10 && bp->speculative == 0 ) + { + char str[65]; + //printf("MAINCHAIN gethdr %d %s\n",bp->bundleheight,bits256_str(str,bp->hashes[0])); + queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); + bp->hdrtime = (uint32_t)time(NULL); + } + /*if ( block != 0 && bundlei > 0 && (prev= iguana_blockfind(coin,block->RO.prev_block)) != 0 ) + { + if ( bp->bundleheight+bundlei-1 >= coin->blocks.hwmchain.height ) + { + printf("prev issue.%s\n",bits256_str(str,prev->RO.hash2)); + iguana_blockQ("previssue",coin,bp,bundlei-1,prev->RO.hash2,0); + } + }*/ + /*if ( 0 && (bp= coin->current) != 0 && bp->numsaved < bp->n ) + { + for (hdrsi=numissued=0; hdrsiMAXBUNDLES && coin->current->hdrsi+hdrsibundlescount && numissued<100; hdrsi++) + { + if ( (bp= coin->bundles[hdrsi + coin->current->hdrsi]) == 0 ) + continue; + if ( (addr= coin->peers.ranked[hdrsi]) == 0 || addr->msgcounts.verack == 0 ) + continue; + for (bundlei=n=flag=0; bundlein; bundlei++) + if ( (block= bp->blocks[bundlei]) != 0 ) + { + if ( bits256_nonz(block->RO.hash2) > 0 && block->fpos >= 0 ) + n++; + else if ( block->fpipbits == 0 || time(NULL) > block->issued+60 ) + { + block->issued = (uint32_t)time(NULL); + //iguana_sendblockreqPT(coin,addr,bp,bundlei,block->RO.hash2,0); + iguana_blockQ("reqblocks",coin,bp,bundlei,block->RO.hash2,0); + flag++; + if ( ++numissued > 100 ) + break; + } + } + if ( 0 && flag != 0 ) + printf("issued %d priority blocks for %d current.[%d] have %d blocks emit.%u\n",flag,hdrsi,bp->hdrsi,n,bp->emitfinish); + } + }*/ + /*else if ( iguana_blockfind(coin,bp->hashes[bundlei]) == 0 ) + { + //if ( bits256_nonz(bp->hashes[bundlei]) > 0 ) + // { + // printf("next %d\n",coin->blocks.hwmchain.height+1); + // iguana_blockQ(coin,bp,bundlei,bp->hashes[bundlei],0); + // } + // else if ( bp->speculative != 0 && (bits256_cmp(bp->hashes[bundlei],bp->speculative[bundlei]) != 0 || (rand() % 100) == 0) ) + { + if ( time(NULL) > bp->issued[bundlei]+30 && iguana_blockfind(coin,bp->speculative[bundlei]) == 0 ) + { + bp->hashes[bundlei] = bp->speculative[bundlei]; + struct iguana_bloominds bit = iguana_calcbloom(bp->speculative[bundlei]); + if ( iguana_bloomfind(coin,&bp->bloom,0,bit) < 0 ) + iguana_bloomset(coin,&bp->bloom,0,bit); + printf("speculative next %d\n",coin->blocks.hwmchain.height+1); + iguana_blockQ("speculativenext",coin,0,-1,bp->speculative[bundlei],0); + bp->issued[bundlei] = (uint32_t)time(NULL); + } + } + }*/ + /*else if ( 0 && (bp= coin->bundles[--hdrsi]) != 0 ) + { + char str[65]; + queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); + }*/ + /*double threshold,lag = OS_milliseconds() - coin->backstopmillis; + threshold = (10 + coin->longestchain - coin->blocksrecv); + if ( threshold < 1 ) + threshold = 1.; + if ( (bp= coin->bundles[(coin->blocks.hwmchain.height+1)/coin->chain->bundlesize]) != 0 ) + threshold = (bp->avetime + coin->avetime) * .5; + else threshold = coin->avetime; + threshold *= 100. * sqrt(threshold) * .000777;*/ + /*for (i=n=0; in; i++) + { + if ( lag < coin->MAXSTUCKTIME ) + { + if ( bits256_nonz(bp->hashes[i]) != 0 ) + iguana_blockQ("stuck",coin,bp,i,bp->hashes[i],0); + } + if ( (block= bp->blocks[i]) != 0 && block->fpipbits == 0 && bp->speculativecache[i] == 0 ) + { + printf("s.[%d:%d] ",bp->hdrsi,i); + iguana_blockQ("stuck",coin,bp,i,block->RO.hash2,0); + iguana_blockQ("stuck",coin,bp,i,block->RO.hash2,1); + if ( coin->peers.numranked > 8 && (addr= coin->peers.ranked[n % 8]) != 0 && addr->usock >= 0 && addr->dead == 0 && addr->msgcounts.verack != 0 ) + { + if ( (len= iguana_getdata(coin,serialized,MSG_BLOCK,&block->RO.hash2,1)) > 0 ) + { + printf("%s, ",addr->ipaddr); + iguana_send(coin,addr,serialized,len); + } + } + block->issued = (uint32_t)time(NULL); + n++; + } + } + if ( n > 0 ) + printf("issued %d priority requests [%d] to unstick stuckiters.%d lag.%d\n",n,bp->hdrsi,coin->stuckiters,lag);*/ + /*if ( 0 && n >= coin->chain->bundlesize ) + { + blockhashes = malloc(sizeof(*blockhashes) * coin->chain->bundlesize); + for (i=0; ichain->bundlesize; i++) + blockhashes[i] = blocks[i].RO.hash2; + for (i=0; ibundlescount; i++) + { + if ( (bp= coin->bundles[i]) != 0 && bp->emitfinish == 0 ) + { + blockhashes[0] = bp->hashes[0]; + vcalc_sha256(0,allhash.bytes,blockhashes[0].bytes,coin->chain->bundlesize * sizeof(*blockhashes)); + if ( bits256_cmp(allhash,bp->allhash) == 0 ) + { + if ( bp->queued != 0 ) + bp->queued = 0; + if ( iguana_allhashcmp(coin,bp,blockhashes,coin->chain->bundlesize) > 0 ) + { + free(blockhashes); + return(req); + } + } + } + } + free(blockhashes); + }*/ + + + /*void iguana_patch(struct iguana_info *coin,struct iguana_block *block) + { + int32_t i,j,origheight,height; struct iguana_block *prev,*next; struct iguana_bundle *bp; + prev = iguana_blockhashset(coin,-1,block->RO.prev_block,1); + block->hh.prev = prev; + if ( prev != 0 ) + { + if ( prev->mainchain != 0 ) + { + prev->hh.next = block; + if ( memcmp(block->RO.prev_block.bytes,coin->blocks.hwmchain.RO.hash2.bytes,sizeof(bits256)) == 0 ) + _iguana_chainlink(coin,block); + if ( (next= block->hh.next) != 0 && bits256_nonz(next->RO.hash2) > 0 ) + next->height = block->height + 1; + } + else if ( 0 && block->height < 0 ) + { + for (i=0; i<1; i++) + { + if ( (prev= prev->hh.prev) == 0 ) + break; + if ( prev->mainchain != 0 && prev->height >= 0 ) + { + j = i; + origheight = (prev->height + i + 2); + prev = block->hh.prev; + height = (origheight - 1); + while ( i > 0 && prev != 0 ) + { + if ( prev->mainchain != 0 && prev->height != height ) + { + printf("mainchain height mismatch j.%d at i.%d %d != %d\n",j,i,prev->height,height); + break; + } + prev = prev->hh.prev; + height--; + } + if ( i == 0 ) + { + //printf("SET HEIGHT.%d j.%d\n",origheight,j); + if ( (bp= coin->bundles[origheight / coin->chain->bundlesize]) != 0 ) + { + iguana_bundlehash2add(coin,0,bp,origheight % coin->chain->bundlesize,block->RO.hash2); + block->height = origheight; + block->mainchain = 1; + prev = block->hh.prev; + prev->hh.next = block; + } + } //else printf("break at i.%d for j.%d origheight.%d\n",i,j,origheight); + break; + } + } + } + } + }*/ + +#ifdef newstuff + int32_t iguana_realtime_update(struct iguana_info *coin) + { + double startmillis0; static double totalmillis0; static int32_t num0; + struct iguana_bundle *bp; struct iguana_ramchaindata *rdata; int32_t bundlei,i,n,flag=0; bits256 hash2; struct iguana_peer *addr; + struct iguana_block *block=0; struct iguana_blockRO *B; struct iguana_ramchain *dest=0,blockR; + if ( (bp= coin->current) != 0 && bp->hdrsi == coin->longestchain/coin->chain->bundlesize && bp->hdrsi == coin->balanceswritten && coin->RTheight >= bp->bundleheight && coin->RTheight < bp->bundleheight+bp->n && (coin->RTheight < coin->blocks.hwmchain.height-3 || time(NULL) > bp->lastRT) )//&& coin->blocks.hwmchain.height >= coin->longestchain-1 && coin->RTramchain.H.data->numblocks < bp->n ) + { + if ( bits256_cmp(coin->RThash1,bp->hashes[1]) != 0 ) + coin->RThash1 = bp->hashes[1]; + bp->lastRT = (uint32_t)time(NULL); + if ( coin->peers.numranked > 0 && time(NULL) > coin->RThdrstime+10 ) + { + iguana_RThdrs(coin,bp,coin->peers.numranked); + coin->RThdrstime = bp->lastRT; + for (i=0; ipeers.numranked; i++) + { + if ( (addr= coin->peers.ranked[i]) != 0 ) + printf("%d ",addr->numRThashes); + } + printf("RTheaders\n"); + } + iguana_RTramchainalloc(coin,bp); + bp->isRT = 1; + while ( (rdata= coin->RTramchain.H.data) != 0 && coin->RTheight <= coin->blocks.hwmchain.height ) + { + //printf("RT.%d vs hwm.%d starti.%d bp->n %d\n",coin->RTheight,coin->blocks.hwmchain.height,starti,bp->n); + dest = &coin->RTramchain; + B = (void *)(long)((long)rdata + rdata->Boffset); + bundlei = (coin->RTheight % coin->chain->bundlesize); + if ( (block= bp->blocks[bundlei]) != 0 && bits256_nonz(block->RO.prev_block) != 0 ) + { + iguana_blocksetcounters(coin,block,dest); + startmillis0 = OS_milliseconds(); + if ( iguana_ramchainfile(coin,dest,&blockR,bp,bundlei,block) == 0 ) + { + for (i=bundlei; in; i++) + { + block = iguana_bundleblock(coin,&hash2,bp,bundlei+i); + if ( i == 0 || (bits256_nonz(hash2) != 0 && (block == 0 || block->txvalid == 0)) ) + { + uint8_t serialized[512]; int32_t len; + //char str[65]; printf("RT error [%d:%d] %s %p\n",bp->hdrsi,i,bits256_str(str,hash2),block); + addr = coin->peers.ranked[rand() % 8]; + if ( addr != 0 && (len= iguana_getdata(coin,serialized,MSG_BLOCK,&hash2,1)) > 0 ) + iguana_send(coin,addr,serialized,len); + coin->RTgenesis = 0; + } + break; + } + return(-1); + } else iguana_ramchain_free(coin,&blockR,1); + B[bundlei] = block->RO; + totalmillis0 += (OS_milliseconds() - startmillis0); + num0++; + flag++; + coin->blocks.RO[bp->bundleheight+bundlei] = block->RO; + coin->RTheight++; + printf(">>>> RT.%d hwm.%d L.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld\n",coin->RTheight,coin->blocks.hwmchain.height,coin->longestchain,dest->H.txidind,dest->H.unspentind,dest->H.spendind,dest->pkind,dest->externalind,(long)dest->H.data->allocsize); + coin->RTramchain.H.data->numblocks = bundlei + 1; + } else break; + } + } + n = 0; + if ( dest != 0 && flag != 0 && coin->RTheight >= coin->longestchain ) + { + while ( block != 0 ) + { + if ( bits256_cmp(iguana_blockhash(coin,coin->RTheight-n-1),block->RO.hash2) != 0 ) + { + printf("blockhash error at %d\n",coin->RTheight-n-1); + break; + } + block = iguana_blockfind("RTupdate",coin,block->RO.prev_block); + n++; + if ( coin->RTgenesis != 0 && n >= bp->n ) + break; + } + if ( coin->RTgenesis == 0) + { + if ( n == coin->RTheight ) + { + printf("RTgenesis verified\n"); + coin->RTgenesis = (uint32_t)time(NULL); + } else printf("RTgenesis failed to verify\n"); + } + if ( coin->RTgenesis != 0 ) + { + struct iguana_ramchain R; struct iguana_ramchaindata RDATA; + iguana_rdataset(&R,&RDATA,dest); + bp->ramchain = coin->RTramchain; + printf("ramchainiterate.[%d] ave %.2f micros, total %.2f seconds starti.%d num.%d\n",num0,(totalmillis0*1000.)/num0,totalmillis0/1000.,coin->RTstarti,coin->RTheight%bp->n); + if ( iguana_spendvectors(coin,bp,dest,coin->RTstarti,coin->RTheight%bp->n,0) < 0 ) + { + printf("RTutxo error -> RTramchainfree\n"); + iguana_RTramchainfree(coin); + return(-1); + } + else + { + coin->RTstarti = (coin->RTheight % bp->n); + printf("spendvectors calculated to %d\n",coin->RTheight); + iguana_convert(coin,bp);//,dest); + printf("spendvectors converted to %d\n",coin->RTheight); + } + iguana_rdatarestore(&R,&RDATA,dest); + } + } + if ( dest != 0 && flag != 0 ) + printf("<<<< flag.%d RT.%d:%d hwm.%d L.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld\n",flag,coin->RTheight,n,coin->blocks.hwmchain.height,coin->longestchain,dest->H.txidind,dest->H.unspentind,dest->H.spendind,dest->pkind,dest->externalind,(long)dest->H.data->allocsize); + return(flag); + } + + int32_t iguana_blocksmissing(struct iguana_info *coin,int32_t *nonzp,uint8_t missings[IGUANA_MAXBUNDLESIZE/8+1],bits256 hashes[],double mult,struct iguana_bundle *bp,int32_t capacity) + { + int32_t i,lag,nonz=0,m = 0; double aveduration; bits256 hash2; struct iguana_block *block; uint32_t now = (uint32_t)time(NULL); + if ( bp->durationscount != 0 ) + aveduration = (double)bp->totaldurations / bp->durationscount; + else aveduration = IGUANA_DEFAULTLAG/3 + 1; + aveduration *= mult; + lag = aveduration; + if ( lag > IGUANA_DEFAULTLAG ) + lag = IGUANA_DEFAULTLAG * 8; + memset(missings,0,IGUANA_MAXBUNDLESIZE/8+1); + if ( bp->emitfinish == 0 || bp->ramchain.H.data == 0 ) + { + for (i=0; in; i++) + { + if ( bp->speculativecache[i] != 0 ) + { + //printf("[%d:%d].havec ",bp->hdrsi,i); + continue; + } + if ( (block= iguana_bundleblock(coin,&hash2,bp,i)) != 0 ) + { + if ( block->fpipbits != 0 && block->txvalid != 0 && block->fpos >= 0 && block->RO.recvlen != 0 && (bp->bundleheight+i == 0 || bits256_nonz(block->RO.prev_block) != 0) ) + { + //printf("[%d:%d].have ",bp->hdrsi,i); + continue; + } + } + if ( bits256_nonz(hash2) != 0 ) + { + if ( now > bp->issued[i]+lag ) + { + if ( nonz < capacity ) + { + if ( hashes != 0 ) + hashes[nonz] = hash2; + nonz++; + } + } + } + SETBIT(missings,i); + m++; + } + } //else printf("[%d] emitfinish.%u\n",bp->hdrsi,bp->emitfinish); + *nonzp = nonz; + //printf("missings.[%d] m.%d nonz.%d spec.%p[%d]\n",bp->hdrsi,m,nonz,bp->speculative,bp->numspec); + return(m); + } + + /*int32_t iguana_nextnonz(uint8_t *missings,int32_t i,int32_t max) + { + for (; i 0 ) + { + *capacityp = capacity; + if ( (n= iguana_blocksmissing(coin,&avail,missings,hashes,mult,bp,capacity < max ? capacity : max)) > 0 && avail > 0 ) + { + *missingp = n; + printf("n.%d avail.%d numpeers.%d\n",n,avail,numpeers); + for (i=0; i0; i++) + { + if ( (addr= peers[i]) != 0 && addr->usock >= 0 && addr->dead == 0 && (c= (coin->MAXPENDINGREQUESTS - addr->pendblocks)) > 0 ) + { + if ( c+m > max ) + c = max - m; + if ( avail < c ) + c = avail; + printf("i.%d c.%d avail.%d m.%d max.%d\n",i,c,avail,m,max); + if ( c > 0 && (numsent= iguana_sendhashes(coin,addr,MSG_BLOCK,&hashes[m],c,priority)) > 0 ) + { + for (j=0; jn)) < bp->n ) + { + if ( (block= iguana_bundleblock(coin,&hash2,bp,nonz)) != 0 ) + { + hash2 = block->RO.hash2; + if ( addr->addrind < 0x100 ) + block->peerid = addr->addrind; + else block->peerid = 0; + block->issued = now; + } + bp->issued[nonz] = now; + //char str[65]; printf("issue.[%d:%d] %s %u\n",bp->hdrsi,nonz,bits256_str(str,hash2),now); + nonz++; + } else printf("bundlerequests unexpected nonz.%d c.%d m.%d n.%d numsent.%d i.%d\n",nonz,c,m,n,numsent,i); + } + m += numsent; + avail -= numsent; + } + } + } + } //else printf("err avail.%d n.%d\n",avail,n); + } //else printf("numpeers.%d\n",numpeers); + return(m); + }*/ + /*missing = iguana_blocksmissing(coin,&avail,missings,0,mult,bp,0); + /*if ( coin->current != 0 ) + { + if ( (dist= bp->hdrsi - coin->current->hdrsi) < coin->MAXBUNDLES && (bp == coin->current || netBLOCKS < 50*bp->n) ) + { + iguana_unstickhdr(coin,bp,60); + if ( bp->numcached > bp->n - (coin->MAXBUNDLES - dist) ) + priority += 1 + (bp == coin->current); + if ( bp == coin->current || queue_size(&coin->priorityQ) < (2 * bp->n)/(dist+1) ) + { + //printf("[%d] dist.%d numcached.%d priority.%d\n",bp->hdrsi,dist,bp->numcached,priority); + //iguana_bundleissuemissing(coin,bp,missings,((rand() % 100) == 0 && bp == coin->current)*3); + priority = ((rand() % 20) == 0 && bp == coin->current) * 3; + if ( (n= iguana_bundlerequests(coin,missings,&bp->origmissings,&tmp,mult,bp,priority)) > 0 ) + { + bp->numissued += n; + bp->missingstime = (uint32_t)time(NULL); + } + return(aveduration); + } + } + }*/ + //printf("helper.%d\n",helperid); + /*if ( ((ptr= queue_dequeue(&emitQ,0)) != 0 || (ptr= queue_dequeue(&helperQ,0)) != 0) ) + { + printf("unexpected emitQ or helperQ\n"); + exit(-1); + if ( ptr->bp != 0 && (coin= ptr->coin) != 0 && coin->active != 0 ) + { + idle = 0; + coin->helperdepth++; + iguana_helpertask(fp,&MEM,MEMB,ptr); + coin->helperdepth--; + flag++; + } + myfree(ptr,ptr->allocsize); + }*/ + if ( 0 && (ptr= queue_dequeue(&spendvectorsQ,0)) != 0 ) + { + //printf("spendvectorsQ size.%d\n",queue_size(&spendvectorsQ)); + coin = ptr->coin; + if ( (bp= ptr->bp) != 0 && coin != 0 ) + { + if ( coin->polltimeout < polltimeout ) + polltimeout = coin->polltimeout; + //printf("call spendvectors.%d\n",bp->hdrsi); + if ( coin->PREFETCHLAG > 0 ) + { + iguana_ramchain_prefetch(coin,&bp->ramchain,0); + if ( 0 && bp->hdrsi > 0 ) + iguana_prefetch(coin,bp,bp->hdrsi-1,1); + } + if ( (retval= iguana_spendvectors(coin,bp,&bp->ramchain,0,bp->n,0)) >= 0 ) + { + flag++; + if ( retval > 0 ) + { + printf("GENERATED UTXO.%d for ht.%d duration %d seconds\n",bp->hdrsi,bp->bundleheight,(uint32_t)time(NULL)-bp->startutxo); + } // else printf("null retval from iguana_spendvectors.[%d]\n",bp->hdrsi); + bp->utxofinish = (uint32_t)time(NULL); + iguana_balancesQ(coin,bp); + } else printf("UTXO gen.[%d] utxo error\n",bp->hdrsi); + } + else if ( coin->active != 0 ) + printf("helper missing param? %p %p\n",coin,bp); + myfree(ptr,ptr->allocsize); + } + void iguana_spendvectorsQ(struct iguana_info *coin,struct iguana_bundle *bp) + { + struct iguana_helper *ptr; + bp->queued = (uint32_t)time(NULL); + ptr = mycalloc('i',1,sizeof(*ptr)); + ptr->allocsize = sizeof(*ptr); + ptr->coin = coin; + ptr->bp = bp, ptr->hdrsi = bp->hdrsi; + ptr->type = 's'; + ptr->starttime = (uint32_t)time(NULL); + queue_enqueue("spendvectorsQ",&spendvectorsQ,&ptr->DL,0); + } + + void iguana_convertQ(struct iguana_info *coin,struct iguana_bundle *bp) + { + struct iguana_helper *ptr; + bp->queued = (uint32_t)time(NULL); + ptr = mycalloc('i',1,sizeof(*ptr)); + ptr->allocsize = sizeof(*ptr); + ptr->coin = coin; + ptr->bp = bp, ptr->hdrsi = bp->hdrsi; + ptr->type = 's'; + ptr->starttime = (uint32_t)time(NULL); + queue_enqueue("convertQ",&convertQ,&ptr->DL,0); + } + + void iguana_balancesQ(struct iguana_info *coin,struct iguana_bundle *bp) + { + struct iguana_helper *ptr; + ptr = mycalloc('i',1,sizeof(*ptr)); + ptr->allocsize = sizeof(*ptr); + ptr->coin = coin; + ptr->bp = bp, ptr->hdrsi = bp->hdrsi; + ptr->type = 'B'; + ptr->starttime = (uint32_t)time(NULL); + ptr->timelimit = 0; + if ( bp->balancefinish == 0 ) + bp->balancefinish = 1; + coin->pendbalances++; + //printf("BALANCES Q[%d] %s bundle.%d[%d] balances.%u balancefinish.%u\n",coin->pendbalances,coin->symbol,ptr->hdrsi,bp->n,bp->utxofinish,bp->balancefinish); + queue_enqueue("balancesQ",&balancesQ,&ptr->DL,0); + } + + /*int32_t iguana_helpertask(FILE *fp,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_helper *ptr) + { + struct iguana_info *coin; struct iguana_peer *addr; struct iguana_bundle *bp,*nextbp; + addr = ptr->addr; + if ( (coin= ptr->coin) != 0 ) + { + if ( (bp= ptr->bp) != 0 ) + { + if ( 0 && ptr->type == 'M' ) + { + if ( (nextbp= ptr->nextbp) != 0 ) + { + bp->mergefinish = nextbp->mergefinish = (uint32_t)time(NULL); + if ( iguana_bundlemergeHT(coin,mem,memB,bp,nextbp,ptr->starttime) < 0 ) + bp->mergefinish = nextbp->mergefinish = 0; + } + } + else if ( ptr->type == 'B' ) + { + printf("helper bundleiters\n"); + iguana_bundleiters(coin,mem,memB,bp,ptr->timelimit); + } + else if ( ptr->type == 'E' ) + { + coin->emitbusy++; + if ( iguana_bundlesaveHT(coin,mem,memB,bp,ptr->starttime) == 0 ) + { + //fprintf(stderr,"emitQ coin.%p bp.[%d]\n",ptr->coin,bp->bundleheight); + bp->emitfinish = (uint32_t)time(NULL) + 1; + coin->numemitted++; + } else bp->emitfinish = 0; + coin->emitbusy--; + } + } else printf("no bundle in helperrequest\n"); + } else printf("no coin in helperrequest\n"); + return(0); + }*/ + + void iguana_mergeQ(struct iguana_info *coin,struct iguana_bundle *bp,struct iguana_bundle *nextbp) + { + struct iguana_helper *ptr; + ptr = mycalloc('i',1,sizeof(*ptr)); + ptr->allocsize = sizeof(*ptr); + ptr->coin = coin; + ptr->bp = bp, ptr->hdrsi = bp->hdrsi; + ptr->nextbp = nextbp; + ptr->type = 'M'; + ptr->starttime = (uint32_t)time(NULL); + //printf("%s EMIT.%d[%d] emitfinish.%u\n",coin->symbol,ptr->hdrsi,bp->n,bp->emitfinish); + queue_enqueue("helperQ",&helperQ,&ptr->DL,0); + } + if ( (bp= coin->current) != 0 && bp->hdrsi == coin->longestchain/coin->chain->bundlesize ) + { + n = bp->hdrsi; + for (j=0; jbundles[j]) == 0 || bp->emitfinish <= 1 ) + break; + } + if ( j == n ) + { + for (j=0; jbundles[j]) == 0 || (bp->startutxo == 0 && bp->utxofinish == 0) ) + break; + } + if ( j != n ) + { + for (j=0; jbundles[j]) != 0 ) + { + //printf("bundleQ.[%d]\n",j); + bp->balancefinish = bp->startutxo = 0; + bp->utxofinish = 1; + iguana_bundleQ(coin,bp,1000); + } + } + } //else printf("skip A j.%d vs n.%d\n",j,n); + } //else printf("skip j.%d vs n.%d\n",j,n); + } //else printf("skip hdrsi.%d vs %d\n",coin->current->hdrsi,coin->longestchain/coin->chain->bundlesize); + n = queue_size(&balancesQ); + for (iter=0; iterbp; + if ( ptr->coin != coin || bp == 0 || time(NULL) < bp->nexttime ) + { + if ( 0 && bp != 0 ) + printf("skip.%d lag.%ld\n",bp->hdrsi,bp->nexttime-time(NULL)); + //bp->nexttime = (uint32_t)time(NULL); + queue_enqueue("balanceQ",&balancesQ,&ptr->DL,0); + continue; + } + flag++; + if ( coin != 0 ) + { + iguana_balancecalc(coin,bp,bp->bundleheight,bp->bundleheight+bp->n-1); + if ( coin->active == 0 ) + { + printf("detected autopurge after account filecreation. restarting.%s\n",coin->symbol); + coin->active = 1; + } + } + myfree(ptr,ptr->allocsize); + } + } + + int32_t iguana_RTutxo(struct iguana_info *coin,struct iguana_bundle *bp,struct iguana_ramchain *RTramchain,int32_t bundlei) + { + struct iguana_txid *T; int32_t height,spendind,txidind,j,k; bits256 prevhash; + struct iguana_bundle *spentbp; struct iguana_unspent *spentU,*u; + struct iguana_ramchaindata *RTdata,*rdata; + uint32_t spent_unspentind,now; struct iguana_blockRO *B; struct iguana_spend *S,*s; + if ( (RTdata= RTramchain->H.data) == 0 || RTdata->numspends < 1 ) + { + printf("iguana_RTutxo null data or no spends %p\n",RTramchain->H.data); + return(-1); + } + B = (void *)(long)((long)RTdata + RTdata->Boffset); + S = (void *)(long)((long)RTdata + RTdata->Soffset); + T = (void *)(long)((long)RTdata + RTdata->Toffset); + txidind = B[bundlei].firsttxidind; + spendind = B[bundlei].firstvin; + height = bp->bundleheight + bundlei; + now = (uint32_t)time(NULL); + //printf("RTutxo.[%d:%d] txn_count.%d\n",bp->hdrsi,bundlei,B[bundlei].txn_count); + for (j=0; jexternal != 0 && s->prevout >= 0 ) + { + continue; + double startmillis = OS_milliseconds(); static double totalmillis; static int32_t num; + if ( (spentbp= iguana_externalspent(coin,&prevhash,&spent_unspentind,RTramchain,bp->hdrsi,s,2)) == 0 || spent_unspentind == 0 || spent_unspentind >= spentbp->ramchain.H.data->numunspents || spentbp->hdrsi < 0 || spentbp->hdrsi >= bp->hdrsi || spentbp == bp ) + { + char str[65]; + printf("RTutxo: unexpected spendbp: height.%d bp.[%d] U%d <- S%d.[%d] [ext.%d %s prev.%d]\n",height,spentbp!=0?spentbp->hdrsi:-1,spent_unspentind,spendind,bp->hdrsi,s->external,bits256_str(str,prevhash),s->prevout); + return(-1); + } + totalmillis += (OS_milliseconds() - startmillis); + if ( (++num % 10000) == 0 ) + printf("externalspents.[%d] ave %.2f micros, total %.2f seconds\n",num,(totalmillis*1000.)/num,totalmillis/1000.); + rdata = spentbp->ramchain.H.data; + if ( 0 && coin->PREFETCHLAG > 0 && now >= spentbp->lastprefetch+coin->PREFETCHLAG ) + { + printf("RT prefetch[%d] from.[%d] lag.%d bundlei.%d numspends.%d of %d\n",spentbp->hdrsi,bp->hdrsi,now - spentbp->lastprefetch,bundlei,spendind,RTramchain->H.spendind); + iguana_ramchain_prefetch(coin,&spentbp->ramchain,2); + spentbp->lastprefetch = now; + } + } + else if ( s->prevout >= 0 ) + { + spentbp = bp; + rdata = RTramchain->H.data; + if ( s->spendtxidind != 0 && s->spendtxidind < RTdata->numtxids ) + { + spent_unspentind = T[s->spendtxidind].firstvout + s->prevout; + //printf("txidind.%d 1st.%d prevout.%d\n",txidind,T[txidind].firstvout,s->prevout); + } + else + { + printf("RTutxo txidind overflow %u vs %d\n",s->spendtxidind,RTdata->numtxids); + return(-1); + } + } + else continue; // coinbase always already spent + if ( spentbp != 0 && rdata != 0 && spent_unspentind != 0 && spent_unspentind < rdata->numunspents ) + { + double startmillis = OS_milliseconds(); static double totalmillis; static int32_t num; + spentU = (void *)(long)((long)rdata + rdata->Uoffset); + u = &spentU[spent_unspentind]; + if ( iguana_volatileupdate(coin,1,spentbp == bp ? RTramchain : &spentbp->ramchain,spentbp->hdrsi,spent_unspentind,u->pkind,u->value,spendind,height) < 0 ) + return(-1); + totalmillis += (OS_milliseconds() - startmillis); + if ( (++num % 10000) == 0 ) + printf("volatile.[%d] ave %.2f micros, total %.2f seconds\n",num,(totalmillis*1000.)/num,totalmillis/1000.); + } + else + { + printf("RTutxo error spentbp.%p u.%u vs %d\n",spentbp,spent_unspentind,rdata->numunspents); + return(-1); + } + } + } + return(0); + } + + /*int32_t iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp,int32_t startheight,int32_t endheight) + { + int32_t retval=-1,i,n,flag = 0; + if ( bp->balancefinish > 1 ) + { + printf("make sure DB files have this bp.%d\n",bp->hdrsi); + iguana_validateQ(coin,bp); + return(flag); + } + bp->nexttime = (uint32_t)time(NULL) + 1; + if ( bp != 0 && coin != 0 ) + { + if ( coin->origbalanceswritten <= 1 && coin->spendvectorsaved == 0 ) + { + for (i=0; ibundlescount-1; i++) + { + if ( coin->bundles[i] == 0 || coin->bundles[i]->tmpspends == 0 ) + break; + } + if ( i == coin->bundlescount-1 && bp->tmpspends != 0 && bp->ramchain.H.data != 0 && (n= bp->ramchain.H.data->numspends) != 0 && bp->converted == 0 ) + { + iguana_convertQ(coin,bp); + retval = 0; + } + else if ( bp->converted == 0 ) + { + for (i=0; ibundlescount-1; i++) + { + if ( coin->bundles[i] == 0 || coin->bundles[i]->utxofinish <= 1 ) + break; + } + if ( i == coin->bundlescount-1 ) + { + printf("must be restart after all the spendvectors are saved\n"); + coin->spendvectorsaved = (uint32_t)time(NULL); + } + } + } else retval = iguana_balancenormal(coin,bp,startheight,endheight); + if ( retval < 0 ) + { + //printf("third case.%d utxo.%u balance.%u prev.%u\n",bp->hdrsi,bp->utxofinish,bp->balancefinish,prevbp!=0?prevbp->utxofinish:-1); + coin->pendbalances--; + iguana_balancesQ(coin,bp); + } + else + { + iguana_validateQ(coin,bp); + flag++; + } + } + return(flag); + }*/ + + /*int32_t iguana_balancenormal(struct iguana_info *coin,struct iguana_bundle *bp,int32_t startheight,int32_t endheight) + { + uint32_t starttime; int32_t j=0,n; struct iguana_bundle *prevbp; + n = coin->bundlescount - 1; + for (j=0; jbundles[j]) == 0 ) + break; + if ( prevbp->utxofinish <= 1 || (j < bp->hdrsi && prevbp->balancefinish <= 1) ) + break; + } + //printf("B [%d] j.%d u.%u b.%u\n",bp->hdrsi,j,bp->utxofinish,bp->balancefinish); + if ( (j == n || bp->hdrsi == 0) && bp->bundleheight+bp->n <= coin->blocks.hwmchain.height && bp->utxofinish > 1 && bp->balancefinish <= 1 ) + { + bp->balancefinish = 1; + if ( bp->hdrsi >= coin->balanceswritten ) + { + //printf("balancecalc for %d when %d\n",bp->hdrsi,coin->balanceswritten); + starttime = (uint32_t)time(NULL); + for (j=0; j<=bp->hdrsi; j++) + iguana_allocvolatile(coin,&coin->bundles[j]->ramchain); + if ( iguana_balancegen(coin,bp,startheight,endheight) < 0 ) + { + printf("GENERATE BALANCES.%d ERROR ht.%d\n",bp->hdrsi,bp->bundleheight); + exit(-1); + } + printf("GENERATED BALANCES.%d for ht.%d duration %d seconds, (%d %d).%d\n",bp->hdrsi,bp->bundleheight,(uint32_t)time(NULL) - (uint32_t)starttime,bp->hdrsi,coin->blocks.hwmchain.height/coin->chain->bundlesize-1,bp->hdrsi >= coin->blocks.hwmchain.height/coin->chain->bundlesize-1); + coin->balanceswritten++; + } + bp->balancefinish = (uint32_t)time(NULL); + bp->queued = 0; + if ( bp->hdrsi >= coin->blocks.hwmchain.height/coin->chain->bundlesize-1 && bp->hdrsi == coin->longestchain/coin->chain->bundlesize-1 ) + { + printf("TRIGGER FLUSH %d vs %d\n",bp->hdrsi,coin->blocks.hwmchain.height/coin->chain->bundlesize); + sleep(1); + if ( time(NULL) > coin->startutc+10 && bp->hdrsi >= coin->blocks.hwmchain.height/coin->chain->bundlesize-1 ) + { + if ( iguana_balanceflush(coin,bp->hdrsi,3) > 0 ) + printf("balanceswritten.%d flushed bp->hdrsi %d vs %d coin->longestchain/coin->chain->bundlesize\n",coin->balanceswritten,bp->hdrsi,coin->longestchain/coin->chain->bundlesize); + } else printf("TRIGGER cancelled %d vs %d\n",bp->hdrsi,coin->longestchain/coin->chain->bundlesize-1); + } + return(0); + } + return(-1); + }*/ + /*if ( iguana_spendvectors(coin,bp,dest,starti,coin->RTheight%bp->n,0) < 0 ) + { + printf("RTutxo error -> RTramchainfree\n"); + iguana_RTramchainfree(coin); + return(-1); + } else printf("spendvectors calculated to %d\n",coin->RTheight);*/ + /*while ( block != 0 ) + { + if ( bits256_cmp(iguana_blockhash(coin,coin->RTheight-n-1),block->RO.hash2) != 0 ) + { + printf("blockhash error at %d\n",coin->RTheight-n-1); + break; + } + block = iguana_blockfind("RTupdate",coin,block->RO.prev_block); + n++; + if ( coin->RTgenesis != 0 && n >= bp->n ) + break; + }*/ + //if ( coin->RTHASHMEM.ptr == 0 ) + // iguana_meminit(&coin->RTHASHMEM,"RTHASH",0,1024L*1024L*1024L,0); + if ( coin->PREFETCHLAG > 0 ) + { + //iguana_ramchain_prefetch(coin,&coin->RTramchain,0); + //iguana_prefetch(coin,bp,coin->bundlescount,1); + } + + void iguana_prefetch(struct iguana_info *coin,struct iguana_bundle *bp,int32_t width,int32_t flags) + { + int32_t i; struct iguana_bundle *spentbp; uint32_t starttime = (uint32_t)time(NULL); + if ( bp->hdrsi > width ) + { + //printf("start prefetch.%d for [%d]\n",width,bp->hdrsi); + for (i=1; ibundles[bp->hdrsi - i]) != 0 ) + { + iguana_ramchain_prefetch(coin,&spentbp->ramchain,flags); + spentbp->lastprefetch = starttime; + } + } + //printf("end prefetch.%d for [%d] elapsed %d\n",width,bp->hdrsi,(uint32_t)time(NULL)-starttime); + } + } + /*if ( (fp= fopen(fname,"r")) == 0 ) + { + sprintf(fname,"confs/%s_%s.txt",coin->symbol,(iter == 0) ? "peers" : "hdrs"); + OS_compatible_path(fname); + fp = fopen(fname,"r"); + } + else if ( 0 && iter == 1 ) + { + sprintf(fname,"confs/%s_%s.txt",coin->symbol,(iter == 0) ? "peers" : "hdrs"); + OS_compatible_path(fname); + if ( (fp2= fopen(fname,"r")) != 0 ) + { + fseek(fp,0,SEEK_END), fseek(fp2,0,SEEK_END); + if ( ftell(fp2) > ftell(fp) ) + { + fclose(fp); + fp = fp2; + } + else + { + fclose(fp2); + printf("%s is not used as tmp version is bigger\n",fname); + } + } + }*/ + /*else if ( bp->emitfinish != 0 ) + { + if ( bp->utxofinish > 1 ) + { + if ( bp->balancefinish == 0 ) + { + //bp->queued = 0; + iguana_balancesQ(coin,bp); + } + return(1); + } + if ( bp->emitfinish > 1 ) + { + if ( (retval= iguana_bundlefinish(coin,bp)) > 0 ) + { + //printf("moved to balancesQ.%d bundleiters.%d\n",bp->hdrsi,bp->bundleheight); + //bp->queued = 0; + return(0); + } //else printf("finish incomplete.%d\n",bp->hdrsi); + } + }*/ + //fprintf(stderr,"RO %p U[%d] txidind.%d pkind.%d\n",u,unspentind,ramchain->H.txidind,ramchain->pkind); + /*if ( 0 && u->scriptpos != 0 && u->scriptlen > 0 )//&& u->scriptlen <= sizeof(u->script) ) + { + scriptptr = &Kspace[u->scriptpos]; + if ( memcmp(script,scriptptr,u->scriptlen) != 0 ) + { + int32_t i; + for (i=0; iscriptlen; i++) + printf("%02x",scriptptr[i]); + printf(" u->script\n"); + for (i=0; iscriptlen; i++) + printf("%02x",script[i]); + printf(" script\n"); + printf("[%d] u%d script compare error.%d vs %d\n",bp->hdrsi,unspentind,scriptlen,u->scriptlen); + return(0); + } //else printf("SCRIPT.%d MATCHED!\n",u->scriptlen); + } // else would need to get from HDD to verify*/ + + /* + //char *hashstr,*txidstr,*coinaddr,*txbytes,rmd160str[41],str[65]; int32_t len,height,i,n,valid = 0; + //cJSON *addrs,*retjson,*retitem; uint8_t rmd160[20],addrtype; bits256 hash2,checktxid; + //memset(&hash2,0,sizeof(hash2)); struct iguana_txid *tx,T; struct iguana_block *block = 0; + + if ( (coinaddr= jstr(json,"address")) != 0 ) + { + if ( btc_addr2univ(&addrtype,rmd160,coinaddr) == 0 ) + { + if ( addrtype == coin->chain->pubval || addrtype == coin->chain->p2shval ) + valid = 1; + else return(clonestr("{\"error\":\"invalid addrtype\"}")); + } else return(clonestr("{\"error\":\"cant convert address to rmd160\"}")); + } + if ( strcmp(method,"block") == 0 ) + { + height = -1; + if ( ((hashstr= jstr(json,"blockhash")) != 0 || (hashstr= jstr(json,"hash")) != 0) && strlen(hashstr) == sizeof(bits256)*2 ) + decode_hex(hash2.bytes,sizeof(hash2),hashstr); + else + { + height = juint(json,"height"); + hash2 = iguana_blockhash(coin,height); + } + retitem = cJSON_CreateObject(); + if ( (block= iguana_blockfind(coin,hash2)) != 0 ) + { + if ( (height >= 0 && block->height == height) || memcmp(hash2.bytes,block->RO.hash2.bytes,sizeof(hash2)) == 0 ) + { + char str[65],str2[65]; printf("hash2.(%s) -> %s\n",bits256_str(str,hash2),bits256_str(str2,block->RO.hash2)); + return(jprint(iguana_blockjson(coin,block,juint(json,"txids")),1)); + } + } + else return(clonestr("{\"error\":\"cant find block\"}")); + } + else if ( strcmp(method,"tx") == 0 ) + { + if ( ((txidstr= jstr(json,"txid")) != 0 || (txidstr= jstr(json,"hash")) != 0) && strlen(txidstr) == sizeof(bits256)*2 ) + { + retitem = cJSON_CreateObject(); + decode_hex(hash2.bytes,sizeof(hash2),txidstr); + if ( (tx= iguana_txidfind(coin,&height,&T,hash2)) != 0 ) + { + jadd(retitem,"tx",iguana_txjson(coin,tx,height)); + return(jprint(retitem,1)); + } + return(clonestr("{\"error\":\"cant find txid\"}")); + } + else return(clonestr("{\"error\":\"invalid txid\"}")); + } + else if ( strcmp(method,"rawtx") == 0 ) + { + if ( ((txidstr= jstr(json,"txid")) != 0 || (txidstr= jstr(json,"hash")) != 0) && strlen(txidstr) == sizeof(bits256)*2 ) + { + decode_hex(hash2.bytes,sizeof(hash2),txidstr); + if ( (tx= iguana_txidfind(coin,&height,&T,hash2)) != 0 ) + { + if ( (len= iguana_txbytes(coin,coin->blockspace,sizeof(coin->blockspace),&checktxid,tx,height,0,0)) > 0 ) + { + txbytes = mycalloc('x',1,len*2+1); + init_hexbytes_noT(txbytes,coin->blockspace,len*2+1); + retitem = cJSON_CreateObject(); + jaddstr(retitem,"txid",bits256_str(str,hash2)); + jaddnum(retitem,"height",height); + jaddstr(retitem,"rawtx",txbytes); + myfree(txbytes,len*2+1); + return(jprint(retitem,1)); + } else return(clonestr("{\"error\":\"couldnt generate txbytes\"}")); + } + return(clonestr("{\"error\":\"cant find txid\"}")); + } + else return(clonestr("{\"error\":\"invalid txid\"}")); + } + else if ( strcmp(method,"txs") == 0 ) + { + if ( ((hashstr= jstr(json,"block")) != 0 || (hashstr= jstr(json,"blockhash")) != 0) && strlen(hashstr) == sizeof(bits256)*2 ) + { + decode_hex(hash2.bytes,sizeof(hash2),hashstr); + if ( (block= iguana_blockfind(coin,hash2)) == 0 ) + return(clonestr("{\"error\":\"cant find blockhash\"}")); + } + else if ( jobj(json,"height") != 0 ) + { + height = juint(json,"height"); + hash2 = iguana_blockhash(coin,height); + if ( (block= iguana_blockfind(coin,hash2)) == 0 ) + return(clonestr("{\"error\":\"cant find block at height\"}")); + } + else if ( valid == 0 ) + return(clonestr("{\"error\":\"txs needs blockhash or height or address\"}")); + retitem = cJSON_CreateArray(); + if ( block != 0 ) + { + for (i=0; iRO.txn_count; i++) + { + if ( (tx= iguana_blocktx(coin,&T,block,i)) != 0 ) + jaddi(retitem,iguana_txjson(coin,tx,-1)); + } + } + else + { + init_hexbytes_noT(rmd160str,rmd160,20); + jaddnum(retitem,"addrtype",addrtype); + jaddstr(retitem,"rmd160",rmd160str); + jaddstr(retitem,"txlist","get list of all tx for this address"); + } + return(jprint(retitem,1)); + } + + else + { + n = 0; + if ( valid == 0 ) + { + if ( (addrs= jarray(&n,json,"addrs")) == 0 ) + return(clonestr("{\"error\":\"need address or addrs\"}")); + } + for (i=0; i<=n; i++) + { + retitem = cJSON_CreateObject(); + if ( i > 0 ) + retjson = cJSON_CreateArray(); + if ( i > 0 ) + { + if ( (coinaddr= jstr(jitem(addrs,i-1),0)) == 0 ) + return(clonestr("{\"error\":\"missing address in addrs\"}")); + if ( btc_addr2univ(&addrtype,rmd160,coinaddr) < 0 ) + { + free_json(retjson); + return(clonestr("{\"error\":\"illegal address in addrs\"}")); + } + if ( addrtype != coin->chain->pubval && addrtype != coin->chain->p2shval ) + return(clonestr("{\"error\":\"invalid addrtype in addrs\"}")); + } + if ( strcmp(method,"utxo") == 0 ) + { + jaddstr(retitem,"utxo","utxo entry"); + } + else if ( strcmp(method,"unconfirmed") == 0 ) + { + jaddstr(retitem,"unconfirmed","unconfirmed entry"); + } + else if ( strcmp(method,"balance") == 0 ) + { + jaddstr(retitem,"balance","balance entry"); + } + else if ( strcmp(method,"totalreceived") == 0 ) + { + jaddstr(retitem,"totalreceived","totalreceived entry"); + } + else if ( strcmp(method,"totalsent") == 0 ) + { + jaddstr(retitem,"totalsent","totalsent entry"); + } + else if ( strcmp(method,"validateaddress") == 0 ) + { + jaddstr(retitem,"validate",coinaddr); + } + if ( n == 0 ) + return(jprint(retitem,1)); + else jaddi(retjson,retitem); + } + return(jprint(retjson,1)); + } + */ + + /* + char *iguana_listsinceblock(struct supernet_info *myinfo,struct iguana_info *coin,bits256 blockhash,int32_t target) + { + cJSON *retitem = cJSON_CreateObject(); + return(jprint(retitem,1)); + } + + char *iguana_getinfo(struct supernet_info *myinfo,struct iguana_info *coin) + { + cJSON *retitem = cJSON_CreateObject(); + jaddstr(retitem,"result",coin->statusstr); + return(jprint(retitem,1)); + } + + char *iguana_getbestblockhash(struct supernet_info *myinfo,struct iguana_info *coin) + { + cJSON *retitem = cJSON_CreateObject(); + char str[65]; jaddstr(retitem,"result",bits256_str(str,coin->blocks.hwmchain.RO.hash2)); + return(jprint(retitem,1)); + } + + char *iguana_getblockcount(struct supernet_info *myinfo,struct iguana_info *coin) + { + cJSON *retitem = cJSON_CreateObject(); + jaddnum(retitem,"result",coin->blocks.hwmchain.height); + return(jprint(retitem,1)); + }*/ + if ( 0 ) + { + int32_t i,n; int64_t total; char *coinaddr; struct iguana_pkhash *P; struct iguana_info *coin; uint8_t rmd160[20],addrtype,pubkey33[33]; double startmillis; + coin = iguana_coinfind("BTCD"); + if ( 1 && coin != 0 ) + { + getchar(); + for (i=0; ibundlescount; i++) + if ( coin->bundles[i] == 0 ) + break; + coinaddr = "RUZ9AKxy6J2okcBd1PZm4YH6atmPwqV4bo"; + bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr); + P = calloc(coin->bundlescount,sizeof(*P)); + memset(pubkey33,0,sizeof(pubkey33)); + n = iguana_pkhasharray(coin,0,0,0,&total,P,coin->bundlescount,rmd160,coinaddr,pubkey33); + printf("%s has total outputs %.8f from %d bundles\n",coinaddr,dstr(total),n); + startmillis = OS_milliseconds(); + for (i=0; i<1000; i++) + n = iguana_pkhasharray(coin,0,0,0,&total,P,coin->bundlescount,rmd160,coinaddr,pubkey33); + printf("%s has total outputs %.8f from %d bundles %.3f millis\n",coinaddr,dstr(total),n,OS_milliseconds()-startmillis); + getchar(); + } + } + int32_t i,numretries = 5; + for (i=0; i 2 ) + //printf("write.%d of %d worked!\n",i+1,numretries+1); + break; + } + fseek(fp,startfpos,SEEK_SET); + } + } +#else + //printf("call _iguana_chainlink\n"); + /*for (i=coin->blocks.hwmchain.height%coin->chain->bundlesize; ichain->bundlesize; i++) + { + if ( (bp= coin->current) != 0 && (block= bp->blocks[i]) != 0 ) + { + //printf("i.%d %s main.%d txvalid.%d\n",i,bits256_str(str,block->RO.hash2),block->mainchain,block->txvalid); + if ( _iguana_chainlink(coin,block) == 0 ) + iguana_blockQ("mainchain",coin,bp,-i,block->RO.hash2,1); + //iguana_realtime_update(coin); + } + }*/ + /*int32_t numrmds,minconf=0,maxconf=0,m = 0; uint8_t *rmdarray; cJSON *retjson; + retjson = cJSON_CreateArray(); + if ( (minconf= juint(params[0],0)) > 0 ) + { + m++; + if ( (maxconf= juint(params[1],0)) > 0 ) + m++; + } + if ( minconf == 0 ) + minconf = 1; + if ( maxconf == 0 ) + maxconf = 9999999; + rmdarray = iguana_rmdarray(coin,&numrmds,array,m); + iguana_unspents(myinfo,coin,retjson,minconf,maxconf,rmdarray,numrmds); + if ( rmdarray != 0 ) + free(rmdarray); + return(jprint(retjson,1));*/ + char *iguana_payloadsave(char *filename,cJSON *wallet) + { + FILE *fp; + if ( (fp= fopen(filename,"wb")) != 0 ) + { + if ( fwrite(payloadstr,1,strlen(payloadstr),fp) != strlen(payloadstr) ) + { + fclose(fp); + return(clonestr("{\"error\":\"couldnt save wallet backup\"}")); + } + fclose(fp); + return(0); + } else return(clonestr("{\"error\":\"couldnt save wallet backup\"}")); + } + + /*struct iguana_waddress *iguana_waccountadd(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waccount **wacctp,char *walletaccount,char *coinaddr,char *redeemScript) + { + struct iguana_waccount *wacct; struct iguana_waddress *waddr = 0; + if ( (wacct= iguana_waccountfind(myinfo,coin,walletaccount)) == 0 ) + wacct = iguana_waccountcreate(myinfo,coin,walletaccount); + if ( wacct != 0 ) + waddr = iguana_waddresscreate(myinfo,coin,wacct,coinaddr,redeemScript); + return(waddr); + }*/ +#ifdef testing + char *bitcoin_cltvtx(struct iguana_info *coin,char *changeaddr,char *senderaddr,char *senders_otheraddr,char *otheraddr,uint32_t locktime,uint64_t satoshis,bits256 txid,int32_t vout,uint64_t inputsatoshis,bits256 privkey) + { + uint64_t change; char *rawtxstr,*signedtx; struct vin_info V; bits256 cltxid,signedtxid; + int32_t cltvlen,len; uint32_t timestamp; char ps2h_coinaddr[65]; cJSON *txobj; + uint8_t p2sh_rmd160[20],cltvscript[1024],paymentscript[64],rmd160[20],secret160[20],addrtype; + timestamp = (uint32_t)time(NULL); + bitcoin_addr2rmd160(&addrtype,secret160,senders_otheraddr); + cltvlen = bitcoin_cltvscript(coin->chain->p2shtype,ps2h_coinaddr,p2sh_rmd160,cltvscript,0,senderaddr,otheraddr,secret160,locktime); + txobj = bitcoin_createtx(coin,locktime); + len = bitcoin_p2shspend(paymentscript,0,p2sh_rmd160); + bitcoin_addoutput(coin,txobj,paymentscript,len,satoshis); + bitcoin_addinput(coin,txobj,txid,vout,locktime); + if ( inputsatoshis > (satoshis + 10000) ) + { + change = inputsatoshis - (satoshis + 10000); + if ( changeaddr != 0 && changeaddr[0] != 0 ) + { + bitcoin_addr2rmd160(&addrtype,rmd160,changeaddr); + if ( addrtype == coin->chain->pubtype ) + len = bitcoin_standardspend(paymentscript,0,rmd160); + else if ( addrtype == coin->chain->p2shtype ) + len = bitcoin_standardspend(paymentscript,0,rmd160); + else + { + printf("error with mismatched addrtype.%02x vs (%02x %02x)\n",addrtype,coin->chain->pubtype,coin->chain->p2shtype); + return(0); + } + bitcoin_addoutput(coin,txobj,paymentscript,len,change); + } + else + { + printf("error no change address when there is change\n"); + return(0); + } + } + rawtxstr = bitcoin_json2hex(coin,&cltxid,txobj); + char str[65]; printf("CLTV.%s (%s)\n",bits256_str(str,cltxid),rawtxstr); + memset(&V,0,sizeof(V)); + V.signers[0].privkey = privkey; + bitcoin_verifytx(coin,&signedtxid,&signedtx,rawtxstr,&V); + free(rawtxstr); + if ( signedtx != 0 ) + printf("signed CLTV.%s (%s)\n",bits256_str(str,signedtxid),signedtx); + else printf("error generating signedtx\n"); + free_json(txobj); + return(signedtx); + } +#endif + + char *refstr = "01000000\ + 01\ + eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2\ + 01000000\ + 8c\ + 4930460221009e0339f72c793a89e664a8a932df073962a3f84eda0bd9e02084a6a9567f75aa022100bd9cbaca2e5ec195751efdfac164b76250b1e21302e51ca86dd7ebd7020cdc0601410450863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b23522cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6\ + ffffffff\ + 01\ + 605af40500000000\ + 19\ + 76a914097072524438d003d23a2f23edb65aae1bb3e46988ac\ + 00000000"; + + cJSON *bitcoin_txtest(struct iguana_info *coin,char *rawtxstr,bits256 txid) + { + struct iguana_msgtx msgtx; char str[65],str2[65]; bits256 checktxid,blockhash,signedtxid; + cJSON *retjson,*txjson; uint8_t *serialized,*serialized2; uint32_t firstvout; + struct vin_info *V; char vpnstr[64],*txbytes,*signedtx; int32_t n,txstart,height,n2,maxsize,len; + rawtxstr = refstr; + len = (int32_t)strlen(rawtxstr); + maxsize = len + 32768; + serialized = calloc(1,maxsize); + serialized2 = calloc(1,maxsize); + len >>= 1; + V = 0; + vpnstr[0] = 0; + memset(&msgtx,0,sizeof(msgtx)); + if ( len < maxsize ) + { + decode_hex(serialized,len,rawtxstr); + txjson = cJSON_CreateObject(); + retjson = cJSON_CreateObject(); + if ( (n= iguana_rwmsgtx(coin,0,txjson,serialized,maxsize,&msgtx,&txid,vpnstr)) < 0 ) + { + printf("bitcoin_txtest len.%d: n.%d from (%s)\n",len,n,rawtxstr); + free(serialized), free(serialized2); + return(cJSON_Parse("{\"error\":\"cant parse txbytes\"}")); + } + V = calloc(msgtx.tx_in,sizeof(*V)); + { + //char *pstr; int32_t plen; + decode_hex(V[0].signers[0].privkey.bytes,sizeof(V[0].signers[0].privkey),"18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725"); + //pstr = "0450863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b23522cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6"; + //plen = (int32_t)strlen(pstr); + //decode_hex(V[0].signers[0].pubkey,plen,pstr); + } + if ( bitcoin_verifytx(coin,&signedtxid,&signedtx,rawtxstr,V) != 0 ) + printf("bitcoin_verifytx error\n"); + jadd(retjson,"result",txjson); + if ( (firstvout= iguana_unspentindfind(coin,&height,txid,0,coin->bundlescount-1)) != 0 ) + { + if ( height >= 0 ) + { + blockhash = iguana_blockhash(coin,height); + jaddnum(retjson,"height",height); + jaddnum(retjson,"confirmations",coin->longestchain - height); + jaddbits256(retjson,"blockhash",blockhash); + } + } + //printf("retjson.(%s) %p\n",jprint(retjson,0),retjson); + memset(checktxid.bytes,0,sizeof(checktxid)); + if ( (n2= iguana_rwmsgtx(coin,1,0,serialized2,maxsize,&msgtx,&checktxid,vpnstr)) < 0 || n != n2 ) + { + printf("bitcoin_txtest: n.%d vs n2.%d\n",n,n2); + free(serialized), free(serialized2), free(V); + return(retjson); + } + if ( bits256_cmp(checktxid,txid) != 0 ) + { + printf("bitcoin_txtest: txid.%s vs check.%s\n",bits256_str(str,txid),bits256_str(str2,checktxid)); + } + checktxid = iguana_parsetxobj(coin,&txstart,serialized,maxsize,&msgtx,jobj(retjson,"result")); + if ( bits256_cmp(checktxid,txid) != 0 ) + { + printf("bitcoin_txtest: txid.%s vs check2.%s\n",bits256_str(str,txid),bits256_str(str2,checktxid)); + } + if ( msgtx.allocsize != 0 ) + { + txbytes = malloc(msgtx.allocsize*2 + 1); + init_hexbytes_noT(txbytes,&serialized[txstart],msgtx.allocsize); + if ( strcmp(txbytes,rawtxstr) != 0 ) + printf("bitcoin_txtest: reconstruction error: %s != %s\n",rawtxstr,txbytes); + else printf("reconstruction PASSED\n"); + free(txbytes); + } else printf("bitcoin_txtest: zero msgtx allocsize\n"); + free(serialized), free(serialized2), free(V); + return(retjson); + } + free(serialized), free(serialized2); + return(cJSON_Parse("{\"error\":\"testing bitcoin txbytes\"}")); + } + + + /*int32_t btc_priv2wif(char *wifstr,uint8_t privkey[32],uint8_t addrtype) + { + uint8_t tmp[128]; char hexstr[67]; cstring *btc_addr; + memcpy(tmp,privkey,32); + tmp[32] = 1; + init_hexbytes_noT(hexstr,tmp,32); + if ( (btc_addr= base58_encode_check(addrtype,true,tmp,33)) != 0 ) + { + strcpy(wifstr,btc_addr->str); + cstr_free(btc_addr,true); + } + //printf("-> (%s) -> wif.(%s) addrtype.%02x\n",hexstr,wifstr,addrtype); + return(0); + } + + cstring *base58_encode_check(uint8_t addrtype,bool have_addrtype,const void *data,size_t data_len) + { + uint8_t i,buf[64]; bits256 hash; cstring *s_enc;//,*s = cstr_new_sz(data_len + 1 + 4); + buf[0] = addrtype; + memcpy(buf+1,data,data_len); + hash = bits256_doublesha256(0,buf,(int32_t)data_len+1); + //bu_Hash4(md32,buf,(int32_t)data_len+1); + for (i=0; i<4; i++) + { + buf[data_len+i+1] = hash.bytes[31-i]; + //printf("(%02x %02x) ",hash.bytes[31-i],md32[i]); + } + //printf("hash4 cmp\n"); + s_enc = base58_encode(buf,data_len+5); + return s_enc; + } + */ + +#endif #endif diff --git a/field.html b/field.html old mode 100644 new mode 100755 diff --git a/footer.html b/footer.html old mode 100644 new mode 100755 diff --git a/formfooter.html b/formfooter.html old mode 100644 new mode 100755 diff --git a/formheader.html b/formheader.html old mode 100644 new mode 100755 diff --git a/header.html b/header.html old mode 100644 new mode 100755 diff --git a/help.json b/help.json new file mode 100755 index 000000000..fe51488c7 --- /dev/null +++ b/help.json @@ -0,0 +1 @@ +[] diff --git a/help/.tmpmarker b/help/.tmpmarker new file mode 100755 index 000000000..e69de29bb diff --git a/iguana/Makefile b/iguana/Makefile old mode 100644 new mode 100755 index 26c323a8c..c6c016bad --- a/iguana/Makefile +++ b/iguana/Makefile @@ -11,7 +11,8 @@ NACL_SDK_ROOT ?= $(abspath $(CURDIR)) TARGET = iguana -EXTRA= -D__PNACL -DNN_DISABLE_GETADDRINFO_A=1 -DNN_USE_LITERAL_IFADDR=1 -DNN_HAVE_STDINT=1 -DNN_HAVE_MSG_CONTROL=0 -DNN_HAVE_SEMAPHORE=1 -DNN_HAVE_POLL=1 -DNN_HAVE_SOCKETPAIR=1 -DNN_USE_POLL=1 +#EXTRA= -D__PNACL -D__PNACL__ -DNN_DISABLE_GETADDRINFO_A=1 -DNN_USE_LITERAL_IFADDR=1 -DNN_HAVE_STDINT=1 -DNN_HAVE_MSG_CONTROL=0 -DNN_HAVE_SEMAPHORE=1 -DNN_HAVE_POLL=1 -DNN_HAVE_SOCKETPAIR=1 -DNN_USE_POLL=1 +EXTRA= -D__PNACL -D__PNACL__ -DHAVE_CONFIG_H #include $(NACL_SDK_ROOT)/tools/common.mk include tools/common.mk @@ -24,7 +25,8 @@ DEPS = nacl_io #LIBS = curl ssl crypto z glibc-compat nacl_spawn ppapi nacl_io ppapi_cpp ppapi_simple # cli_main #LIBS = crypto777 curl ssl crypto z pthread ppapi nacl_io #DEPS = nacl_io -LIBS = crypto777 curl ssl crypto z glibc-compat nacl_spawn ppapi nacl_io ppapi_simple # cli_main ppapi_cpp ppapi_simple +#LIBS = crypto777 curl ssl crypto z glibc-compat nacl_spawn ppapi nacl_io ppapi_simple # cli_main ppapi_cpp ppapi_simple +LIBS = crypto777 z glibc-compat nacl_spawn ppapi nacl_io ppapi_simple CFLAGS = -Wall -O2 -fno-strict-aliasing $(EXTRA) LFLAGS = libs diff --git a/iguana/Readme.md b/iguana/Readme.md new file mode 100755 index 000000000..596952081 --- /dev/null +++ b/iguana/Readme.md @@ -0,0 +1,193 @@ +#SuperNET Client "iguana" + +[![Join the chat at https://gitter.im/jl777/SuperNET](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/jl777/SuperNET?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + +> #TL;DR# +> +> ```sudo apt-get update; sudo apt-get install libcurl4-gnutls-dev libssl-dev; git clone https://github.com/jl777/SuperNET; cd SuperNET; ./m_onetime m_unix; ./m_unix; agents/iguana``` +> +> The above one line gets SuperNET installed, built and launched for unix. +> +> After that ```./m_unix``` updates to latest. +> *Continue below at "Running".* + +**iguana is easy to build. Start by cloning (or downloading) this repository.** + +#DEPENDENCIES# +##for native (unix, osx)## +Just make sure you have the dev versions of openssl and curl installed: + +```sudo apt-get install libcurl4-gnutls-dev libssl-dev``` + +##For native (win32, win64)## +TOOL_DIR := /usr/local/gcc-4.8.0-qt-4.8.4-for-mingw32/win32-gcc/bin +MINGW := i586-mingw32 +The above two definitions need to be changed to match the mingw install on your system. m_win32 and m_win64 just invokes the makefile in mingw32 and mingw64 + +##For chrome app## +You need to make sure the nacl sdk is properly installed and you are able to build the examples. +Now you will need to get the external libs, which can be built from scratch using naclports or there use the reference builds of libssl.a, libcrypto.a, libcurl.a and libz.a in the SuperNET/crypto777/pnacl_libs. You can just copy those over into $(NACL_SDK_ROOT)//lib/pnacl. + + +#ONETIME# +Now you are ready to build. +I try to make the build process as simple as possible, so there are no `autoconf`, `autoreconf`, `configure`, `cmake`, `make`, to get properly installed and running and run, etc. You do need a C compiler, like gcc. + +The **first time** you need to build libcrypto777.a and to do that you need to run: + +For unix: ```./m_onetime m_unix``` + +For osx: ```./m_onetime m_osx``` + +For win32: ```./m_onetime m_win32``` + +For win64: ```./m_onetime m_win64``` + +#(RE)BUILD + +Once libcrypto777.a is built, you can build the agents. + +For pnacl: ```cd crypto777; make clean; make; cd ../iguana; make clean; make``` + +For unix: ```./m_unix``` + +For osx: ```./m_osx``` + +For win32: ```./m_win32``` + +For win64: ```./m_win64``` + + +The m_(OS) is a standard I follow and should be self explanatory. within each is usually just a few lines, ie compile all the .c files and link with the standard libs. + +To build just iguana, you can ```cd``` into SuperNET/iguana and do ```./m_unix``` (or ```./m_osx```, ...). + +```./m_clean``` will remove the files created from the building + +#RUNNING# + +The native versions are command line applications: agents/iguana {JSON} +The chrome app pexe requires that the chrome is launched with a command line parameter (tools/chrome.localhost) and then browse to *http://127.0.0.1:7777* to see the pexe + +#SUPERUGLYGUI# + +Once iguana is running, you can see the superuglyGUI at *http://127.0.0.1:7778/?method* +by submitting API calls using the forms, you will see it go to some specific URL. You can also do a programmatic GET request to ```http://127.0.0.1:7778/api/``` + +*http://127.0.0.1:7778/ramchain/block/height/0* -> full webpage + +*http://127.0.0.1:7778/json/ramchain/block/height/0* -> JSON only + +```curl --url "http://127.0.0.1:7778/ramchain/BTCD/block/height/0"``` --> full webpage returned (probably not what you want) +```curl --url "http://127.0.0.1:7778/api/ramchain/BTCD/block/height/0"``` --> returns just the json object from the api call + +Internally, all paths convert the request into a standard SuperNET JSON request. you can use a POST command to directly submit such JSON requests: +```curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"ramchain\",\"method\":\"block\",\"coin\":\"BTCD\",\"height\":0}"``` + +Another approach is to use the bitcoin RPC syntax via: + curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"method\":\"getinfo\",\"params\":[]}" +the params:[] array is where the standard bitcoin parameters go, the only change that is needed is to specify the coin +alternatively {"agent":"SuperNET","method":"bitcoinrpc","coin":"BTCD"} will set the coin +to use for bitcoin RPC calls. this will suffice in single coin environments + +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana",\"method\":\"test\"}" +curl --url "http://127.0.0.1:7778/iguana/test" -> html page with results +curl --url "http://127.0.0.1:7778/api/iguana/test" -> just json text +http://127.0.0.1:7778 -> superugly GUI +http://127.0.0.1:7778/iguana/test +http://127.0.0.1:7778/api/iguana/test +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":"", ... } + "apikey", "apisecret", "userid", "tradepassword" these are as expected + "pollgap" -> gap between each access to exchange for getting prices + +###### +The goal for iguana is to create a scalable bitcoin core implementation that is backward compatible and a drop in replacement, so all the RPC needs to be implemented in addition to peer messaging, blockchain, scripts, wallet, etc. + +The first thing you notice when looking at the raw blockchain is that there is a LOT of redundancy, so by mapping the high entropy hashes to a 32bit integer, you get a 28 byte savings for each use. For a txid with N outputs, that is up to N*28 bytes that would be saved as each vin refers to the txid. + +Since the blockchain has an implicit ordering, it is possible to create a canonical numbering for the txid, vouts, vins, and this will allow syncing the iguana files to save gobs of bandwidth. However both endian formats need to be put into the bittorrent network as the iguana files are designed to be directly memory mapped. This allows skipping of serialization/deserialization of each and every multibyte field. Since the files are less than half the size, even with the doubling due to both endian forms, it is still less overall data than the raw blockchain. + +bitfields are used, so that means a standard way of allocating the bits needs to be used by each compiler. gcc and clang use the same method, so as long as it is compiled with those or one with compatible bitfield allocation, the memory mapped files should work. + +The most space is used by the vout, vin, pkhash structures, as there are a lot more vouts than txids. The txid structure has not been fully optimized, but since it is less than 1% of overall space, I felt it was not worth making it more complicated to save few bytes. The pkhash is the pubkey hash rmd160(sha256(pubkey)) and this is the most efficient way to index the blockchain as all vout scripts generate a rmd160[20] either implicitly for the scripts with pubkey, pay to pubkey hash standard script and all the new p2sh scripts. Another reason to use rmd160 is that it makes it easy to convert to the equivalent addresses for other coins, ie. all coins have the same rmd160 even if the coin addresses are different due to the address type byte added to the base58 conversion. + +The following are the second pass data structures that are created from a batch of raw structures in groups of 2000 (the size of the getheaders). The design needs to meet many constraints, primarily to be as small as possible without sacrificing speed and to be able to work in a parallel sync. That means that each block or bundle needs to be as self-contained as possible, but have external references that can be resolved. This is similar to object files and linkers. The main thing that has these external references are the vins. + +I tried quite a few variations before settling on this. Earlier versions combined everything into a single dataset, which is good for making searches via hashtable really fast, but with the ever growing size of the blockchain not very scalable. The maximum size of 2000 blocks is 2GB right now and at that size there is no danger of overflowing any 32bit offset, but for the most part, the 32bit indexes are of the item, so it can represent much larger than 4GB. + +iguana doesnt use any DB as that is what causes most of the bottlenecks and since the data doesnt change (after 20 blocks), a DB is just overkill. Using the memory mapped file approach, it takes no time to initialize the data structures, but certain operations take linear time relative to the number of bundles. Achieving this performance requires constant time performance for all operations within a bundle. Since most bundles will not have the hash that is being searched for, I used a bloom filter to quickly determine which bundles need to be searched deeper. For the deeper searches, there is a open hashtable that always has good performance as it is sized so it is one third empty. Since the total number of items is known and never changes, both the bloom filters and hashtable never change after initial creation. + +What this means is that on initialization, you memory map the 200 bundles and in the time it takes to do that (less than 1sec), you are ready to query the dataset. Operations like adding a privkey takes a few milliseconds, since all the addresses are already indexed, but caching all the transactions for an address is probably not even necessary for a single user wallet use case. However for dealing with thousands of addresses, it would make sense to cache the lists of transactions to save the few milliseconds per address. + +You might be wondering how is it even possible to have an append only dataset that allows traversing the entire blockchain and searching for all transactions from a specific address. Note that by indexing at the rmd160 level, there is no difference between a multisig address and a normal address and so all the operations work equally for any address, be it pubkey, pubkeyhash, multisig or p2sh. + +With 200 bundles and millions of unspents per bundle recently, it would be easy to have things take a long time to iterate through and find all references to a specific address. What I realized was that during a single pass I can update an arbitrary number of linked lists, one for each rmd160. However it needs to work backwards so you never need to change any previous entry. As soon as an unspent is created, it is final and never changes. It does require a single dynamic data structure for the account which keeps track of the balance (just the sum of outputs) and the last unspentind. As new unspents are made to the same address, it links back to the prior one and updates the total balance. + +To get the list of all transactions, all bundles need to be queried. For each bundle, constant time hash lookups find the last access and then iterating backwards to the first occurance finds all unspents in the bundle. So it is linear time relative to the total number of unspents that an address has with a small 200 constant time operations overhead. As the number of bundles grows, this will continue to increase, but it is always possible to make a single lookup table that spans the entire set of bundles, so I am not worried about scaling things up. Note that the parallel nature of all the bundles makes using multiple cores for all the searches relatively easy, so speedups of N using N cores is not much work. + +I could probably get rid of the firstunspentind in the pkhash struct, but it is there to provide an error check when iterating backwards on the linked list. the pubkeyoffset is also optional, but I find it handy to be able to know what pubkey maps to the rmd160 for a variety of use cases and I am on the fence as to whether to make it purgeable or not. + +I had to make the signatures from the vinscripts purgeable as I dont seem much use for them after a node has validated an input other than relaying the raw block to other nodes. Without the sigs, a node can still be totally self-sufficient when creating new transactions and the sigs are high entropy and unique and is approx equal to the uncompressed size of everything else! The pubkeys are much smaller, especially due to address reuse within a bundle, which only takes up 4 bytes. It is probably worth adding a way to purge the pubkeys at some point, but the method I used to enable signature pruning was to create a stack that grows down to put the signatures into during processing the each block. There is also a forward growing data store where all the things that cant be encoded in the baseline structures are put into. + +It is necessary to used an upfront memory allocation as doing hundreds of millions of malloc/free is a good way to slow things down, especially when there are many threads. Using the onetime allocation, cleanup is guaranteed to not leave any stragglers as a single free releases all memory. After all the blocks in the bundle are processed, there will be a gap between the end of the forward growing data called Kspace and the reverse growing stack for the sigs, so before saving to disk, the sigs are moved to remove the gap. At this point it becomes clear why it had to be a reverse growing stack. I dont want to have to make another pass through the data after moving the signatures and by using negative offsets relative to the top of the stack, there is no need to change any of the offsets used for the signatures. + +Most of the unspents use standard scripts so usually the script offset is zero. However this doesnt take up much room at all as all this data is destined to be put into a compressed filesystem, like squashfs, which cuts the size in about half. Not sure what the compressed size will be with the final iteration, but last time with most of the data it was around 12GB, so I think it will end up around 15GB compressed and 25GB uncompressed. + +Each bundle file will have the following order: +[ ][nonstandard scripts and other data] ... gap ... [signatures] +after saving it the gap goes away. Since the signatures are at the end, it is possible to truncate each bundle file to dramatically reduce its size. It would save a lot of time compressing the files without the signatures as they are high entropy and dont compress, but having them in a different file would really complicate the code. Not that it isnt already quite complicated. + +I realize totally replace all the DB is rather radical, but it was the only way possible to achieve a parallel sync that streams data in at bandwidth saturation speeds. In order to validate the dataset, which is clearly required before any production use of a DB replacement, I decided to put in the extra effort to make iguana able to act as a lossless codec. This would allow verification at the rawtx bytes level with a simple loop that iterates across all blocks and all tx within a block to verify that all txbytes match against what bitcoind returns. + +Of course, since bitcoind wont be able to even calculate balances for all addresses without enabling watching all addresses, I dont know a practical way to verify that all the balance calculations are correct. + +Here are the fundamental data structures and the total size for each is not a typo, it really is 64 bytes for txid, 28 bytes per unspent, 12 bytes per spend and 32 bytes per pkhash and 12 bytes for account balance and end of linked list. But things are even smaller! Each unspent has a unique unspentind within each bundle, so you can have a list of all the unspents that takes up 4 bytes per unspent + 4bytes per bundle it appears in. + +I havent optimized the utxo handling yet, but the plan is to calculate an overlay vector of all unspents that are spent for each bundle. This too is a static dataset, but it cant be calculated until all prior bundles are present due to all external references needing to be resolved. This final step would happen as the mainchain is validated linearly as the parallel sync is proceeding. For simplicity I will also verify all the signatures during this last pass. + +At that point, to create the current utxo at any bundle boundary, it is a matter to OR all the spend vectors. That brings all the data current to the most recent bundle, which might be 1 or 1999 blocks in the past. So the final block will need to be special cased to allow it to be searched before it is in final form. + +I think that covers most of the basics. + +struct iguana_txid // 64 bytes +{ + bits256 txid; + uint32_t txidind,firstvout,firstvin,locktime,version,timestamp,extraoffset; + uint16_t numvouts,numvins; +} __attribute__((packed)); + +struct iguana_unspent // 28 bytes +{ + uint64_t value; + uint32_t txidind,pkind,prevunspentind,scriptoffset; + uint16_t hdrsi:12,type:4,vout; + } __attribute__((packed)); + +struct iguana_spend // 12 bytes +{ + uint32_t spendtxidind,scriptoffset; + int16_t prevout; + uint16_t numsigs:4,numpubkeys:4,p2sh:1,sighash:4,external:1,sequenceid:2; + } __attribute__((packed)); + +struct iguana_pkhash // 32 bytes +{ + uint8_t rmd160[20]; + uint32_t pkind,firstunspentind,pubkeyoffset; +} __attribute__((packed)); + +// dynamic during bundle creation +struct iguana_account // 12 bytes +{ + uint64_t balance; uint32_t lastunspentind; +} __attribute__((packed)); // pkind + diff --git a/iguana/SuperNET.c b/iguana/SuperNET.c old mode 100644 new mode 100755 index 959fb74fd..15d6e50c0 --- a/iguana/SuperNET.c +++ b/iguana/SuperNET.c @@ -15,6 +15,13 @@ #include "iguana777.h" #include "../includes/tweetnacl.h" +#include "../crypto777/OS_portable.h" +#include "../includes/libgfshare.h" +#include "../includes/utlist.h" +#include "../includes/uthash.h" +#include "../includes/curve25519.h" +#include "../includes/cJSON.h" + cJSON *SuperNET_argjson(cJSON *json) { @@ -564,9 +571,9 @@ 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\"}")); - } + } else SuperNET_hexmsgadd(myinfo,categoryhash,subhash,hexmsg,tai_now(),0); jsonstr = jprint(json,1); if ( broadcastflag != 0 || destipbits == 0 ) { @@ -579,7 +586,7 @@ char *SuperNET_DHTsend(struct supernet_info *myinfo,uint64_t destipbits,bits256 addr = &Coins[i]->peers.active[j]; if ( addr->usock >= 0 && addr->supernet != 0 && (broadcastflag != 0 || category_peer(myinfo,addr,categoryhash,subhash) >= 0) ) { - char str[65]; printf("BROADCAST[%d] %s SEND.(%ld) to %s\n",j,bits256_str(str,categoryhash),strlen(jsonstr),addr->ipaddr); + char str[65]; printf("BROADCAST[%d] crc.%x %s SEND.(%d) to %s\n",j,calc_crc32(0,jsonstr,(int32_t)strlen(jsonstr)),bits256_str(str,categoryhash),(int32_t)strlen(jsonstr),addr->ipaddr); iguana_send_supernet(Coins[i],addr,jsonstr,maxdelay==0?0:(rand()%maxdelay)); } } @@ -639,15 +646,16 @@ int32_t SuperNET_destination(struct supernet_info *myinfo,uint32_t *destipbitsp, return(destflag); } -char *SuperNET_JSON(struct supernet_info *myinfo,cJSON *json,char *remoteaddr) +char *SuperNET_JSON(struct supernet_info *myinfo,cJSON *json,char *remoteaddr,uint16_t port) { char hexbuf[8192]; bits256 category,subhash; - int32_t hexlen,destflag,maxdelay,flag=0; uint32_t destipbits,timestamp; cJSON *retjson; + int32_t hexlen,destflag,maxdelay,flag=0,newflag=0; uint32_t destipbits,timestamp; //cJSON *retjson; char *forwardstr=0,*retstr=0,*agent=0,*method=0,*message,*hexmsg=0,*jsonstr=0; uint64_t tag; //printf("SuperNET_JSON.(%s)\n",jprint(json,0)); if ( remoteaddr != 0 && strcmp(remoteaddr,"127.0.0.1") == 0 ) remoteaddr = 0; - agent = jstr(json,"agent"); + if ( (agent = jstr(json,"agent")) == 0 ) + agent = "bitcoinrpc"; method = jstr(json,"method"); if ( agent != 0 && strcmp(agent,"pangea") == 0 && jobj(json,"categoryhash") == 0 ) { @@ -670,7 +678,7 @@ char *SuperNET_JSON(struct supernet_info *myinfo,cJSON *json,char *remoteaddr) //printf("SuperNET_JSON.(%s) remote.(%s)\n",jprint(json,0),remoteaddr!=0?remoteaddr:""); destflag = SuperNET_destination(myinfo,&destipbits,&category,&subhash,&maxdelay,json,remoteaddr); //printf("destflag.%d\n",destflag); - if ( (hexmsg= jstr(json,"hexmsg")) == 0 && (message= jstr(json,"message")) == 0 ) + if ( method != 0 && (hexmsg= jstr(json,"hexmsg")) == 0 && strcmp(agent,"bitcoinrpc") != 0 && (message= jstr(json,"message")) == 0 ) { jsonstr = jprint(json,0); hexlen = (int32_t)strlen(jsonstr); @@ -683,9 +691,10 @@ char *SuperNET_JSON(struct supernet_info *myinfo,cJSON *json,char *remoteaddr) { if ( hexmsg != 0 ) { - //printf("check.(%s)\n",hexmsg); if ( SuperNET_hexmsgfind(myinfo,category,subhash,hexmsg,0) < 0 ) { + //printf("add.(%s)\n",hexmsg); + newflag = 1; SuperNET_hexmsgadd(myinfo,category,subhash,hexmsg,tai_now(),remoteaddr); forwardstr = SuperNET_forward(myinfo,hexmsg,destipbits,category,subhash,maxdelay,juint(json,"broadcast"),juint(json,"plaintext")!=0); } @@ -693,21 +702,20 @@ char *SuperNET_JSON(struct supernet_info *myinfo,cJSON *json,char *remoteaddr) } if ( (destflag & SUPERNET_ISMINE) != 0 && agent != 0 && method != 0 ) { - if ( hexmsg != 0 && SuperNET_hexmsgfind(myinfo,category,subhash,hexmsg,0) < 0 ) + if ( strcmp(agent,"bitcoinrpc") != 0 && newflag == 0 && hexmsg != 0 && SuperNET_hexmsgfind(myinfo,category,subhash,hexmsg,0) < 0 ) SuperNET_hexmsgadd(myinfo,category,subhash,hexmsg,tai_now(),remoteaddr); - if ( (retstr= SuperNET_processJSON(myinfo,json,remoteaddr)) != 0 ) + if ( (retstr= SuperNET_processJSON(myinfo,json,remoteaddr,port)) != 0 ) { //printf("retstr.(%s)\n",retstr); - if ( remoteaddr != 0 && (retjson= cJSON_Parse(retstr)) != 0 ) + /*if ( retstr[strlen(retstr)-1] != '\n' && (retjson= cJSON_Parse(retstr)) != 0 && is_cJSON_Array(retjson) == 0 ) { - if ( jobj(retjson,"result") != 0 || jobj(retjson,"error") != 0 || jobj(retjson,"method") == 0 ) + if ( jobj(retjson,"result") == 0 || jobj(retjson,"error") != 0 || jobj(retjson,"method") != 0 ) { - //printf("it is a result, dont return\n"); free(retstr); retstr = 0; } free_json(retjson); - } + }*/ } else printf("null retstr from SuperNET_JSON\n"); } if ( flag != 0 && hexmsg != 0 && hexmsg != hexbuf ) @@ -779,13 +787,14 @@ char *SuperNET_p2p(struct iguana_info *coin,struct iguana_peer *addr,int32_t *de if ( method != 0 && strcmp(method,"stop") == 0 ) { addr->dead = (uint32_t)time(NULL); + addr->rank = 0; free_json(json); if ( ptr != 0 ) free(ptr); //return(clonestr("{\"result\":\"peer marked as dead\"}")); return(0); } - retstr = SuperNET_JSON(myinfo,json,ipaddr); + retstr = SuperNET_JSON(myinfo,json,ipaddr,addr->A.port); //printf("p2pret.(%s)\n",retstr); *delaymillisp = SuperNET_delaymillis(myinfo,maxdelay); senderpub = jbits256(json,"mypub"); @@ -880,7 +889,7 @@ 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; + uint8_t rmd160[20],pub[33]; uint64_t nxt64bits; bits256 pubkey; char str2[41],wifbuf[64],addr[64],str[128]; cJSON *retjson; pubkey = acct777_pubkey(privkey); nxt64bits = acct777_nxt64bits(pubkey); @@ -889,36 +898,48 @@ cJSON *SuperNET_rosettajson(bits256 privkey,int32_t showprivs) RS_encode(str,nxt64bits); jaddstr(retjson,"RS",str); jadd64bits(retjson,"NXT",nxt64bits); - btc_priv2pub(pub,privkey.bytes); + bitcoin_pubkey33(0,pub,privkey); 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 ) + if ( bitcoin_address(addr,0,pub,33) != 0 ) { jaddstr(retjson,"BTC",addr); - if ( flag != 0 ) + if ( showprivs != 0 ) { - btc_priv2wif(wifbuf,privkey.bytes,0x80); + bitcoin_priv2wif(wifbuf,privkey,128); jaddstr(retjson,"BTCwif",wifbuf); } } - if ( btc_coinaddr(addr,60,str) == 0 ) + if ( bitcoin_address(addr,60,pub,33) != 0 ) { jaddstr(retjson,"BTCD",addr); - if ( flag != 0 ) + if ( showprivs != 0 ) { - btc_priv2wif(wifbuf,privkey.bytes,0xbc); + bitcoin_priv2wif(wifbuf,privkey,188); jaddstr(retjson,"BTCDwif",wifbuf); } } - if ( flag != 0 ) + if ( showprivs != 0 ) jaddbits256(retjson,"privkey",privkey); return(retjson); } #include "../includes/iguana_apidefs.h" +STRING_ARG(SuperNET,addr2rmd160,address) +{ + uint8_t addrtype,rmd160[20]; char rmdstr[41]; cJSON *retjson; + bitcoin_addr2rmd160(&addrtype,rmd160,address); + init_hexbytes_noT(rmdstr,rmd160,sizeof(rmd160)); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result",rmdstr); + jaddnum(retjson,"addrtype",addrtype); + jaddstr(retjson,"address",address); + return(jprint(retjson,1)); +} + HASH_AND_INT(SuperNET,priv2pub,privkey,addrtype) { cJSON *retjson; bits256 pub; uint8_t pubkey[33]; char coinaddr[64]; @@ -927,7 +948,7 @@ HASH_AND_INT(SuperNET,priv2pub,privkey,addrtype) retjson = cJSON_CreateObject(); crypto_box_priv2pub(pub.bytes,privkey.bytes); jaddbits256(retjson,"curve25519",pub); - pub = bitcoin_pubkey33(pubkey,privkey); + pub = bitcoin_pubkey33(myinfo->ctx,pubkey,privkey); jaddbits256(retjson,"secp256k1",pub); bitcoin_address(coinaddr,addrtype,pubkey,33); jaddstr(retjson,"result",coinaddr); @@ -1190,11 +1211,11 @@ TWO_STRINGS(SuperNET,subscribe,category,subcategory) TWO_STRINGS(SuperNET,gethexmsg,category,subcategory) { - bits256 categoryhash,subhash; struct category_msg *m; char *hexstr; cJSON *retjson; + bits256 categoryhash,subhash; struct category_msg *m; char *hexstr; cJSON *retjson; struct category_info *cat; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); categoryhash = calc_categoryhashes(&subhash,category,subcategory); - if ( (m= category_gethexmsg(myinfo,categoryhash,subhash)) != 0 ) + if ( (m= category_gethexmsg(myinfo,&cat,categoryhash,subhash)) != 0 ) { hexstr = calloc(1,m->len*2+1); init_hexbytes_noT(hexstr,m->msg,m->len); @@ -1221,7 +1242,7 @@ THREE_STRINGS(SuperNET,announce,category,subcategory,message) 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"))); + return(SuperNET_categorymulticast(myinfo,0,categoryhash,subhash,message,juint(json,"maxdelay"),juint(json,"broadcast"),juint(json,"plaintext"),json,remoteaddr)); } THREE_STRINGS(SuperNET,survey,category,subcategory,message) @@ -1230,13 +1251,13 @@ THREE_STRINGS(SuperNET,survey,category,subcategory,message) 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"))); + return(SuperNET_categorymulticast(myinfo,1,categoryhash,subhash,message,juint(json,"maxdelay"),juint(json,"broadcast"),juint(json,"plaintext"),json,remoteaddr)); } STRING_ARG(SuperNET,wif2priv,wif) { bits256 privkey; char str[65]; uint8_t privkeytype; cJSON *retjson = cJSON_CreateObject(); - if ( btc_wif2priv(&privkeytype,privkey.bytes,wif) == sizeof(privkey) ) + if ( bitcoin_wif2priv(&privkeytype,&privkey,wif) == sizeof(privkey) ) { jaddstr(retjson,"result","success"); jaddstr(retjson,"privkey",bits256_str(str,privkey)); @@ -1245,9 +1266,32 @@ STRING_ARG(SuperNET,wif2priv,wif) return(jprint(retjson,1)); } -ZERO_ARGS(SuperNET,myipaddr) +STRING_ARG(SuperNET,priv2wif,priv) +{ + bits256 privkey; char wifstr[65]; uint8_t wiftype; cJSON *retjson = cJSON_CreateObject(); + if ( strlen(priv) == sizeof(bits256)*2 && is_hexstr(priv,(int32_t)sizeof(bits256)*2) == sizeof(bits256)*2 ) + { + wiftype = coin != 0 ? coin->chain->wiftype : 0x80; + decode_hex(privkey.bytes,sizeof(privkey),priv); + if ( bitcoin_priv2wif(wifstr,privkey,wiftype) > 0 ) + { + jaddstr(retjson,"result","success"); + jaddstr(retjson,"privkey",priv); + jaddnum(retjson,"type",wiftype); + jaddstr(retjson,"wif",wifstr); + } else jaddstr(retjson,"error","couldnt convert privkey"); + } else jaddstr(retjson,"error","non 32 byte hex privkey"); + return(jprint(retjson,1)); +} + +STRING_ARG(SuperNET,myipaddr,ipaddr) { cJSON *retjson = cJSON_CreateObject(); + if ( myinfo->ipaddr[0] == 0 ) + { + if ( is_ipaddr(ipaddr) != 0 ) + strcpy(myinfo->ipaddr,ipaddr); + } jaddstr(retjson,"result",myinfo->ipaddr); return(jprint(retjson,1)); } @@ -1288,6 +1332,7 @@ ZERO_ARGS(SuperNET,logout) memset(myinfo->handle,0,sizeof(myinfo->handle)); memset(myinfo->myaddr.NXTADDR,0,sizeof(myinfo->myaddr.NXTADDR)); myinfo->myaddr.nxt64bits = 0; + myinfo->expiration = 0; return(clonestr("{\"result\":\"logged out\"}")); } @@ -1299,35 +1344,104 @@ ZERO_ARGS(SuperNET,activehandle) retjson = SuperNET_rosettajson(myinfo->persistent_priv,0); jaddstr(retjson,"result","success"); jaddstr(retjson,"handle",myinfo->handle); + jaddbits256(retjson,"persistent",myinfo->myaddr.persistent); + if ( myinfo->expiration != 0 ) + { + jaddstr(retjson,"status","unlocked"); + jaddnum(retjson,"duration",myinfo->expiration - time(NULL)); + } else jaddstr(retjson,"status","locked"); + SuperNET_MYINFOadd(myinfo); return(jprint(retjson,1)); } +struct supernet_info *SuperNET_accountfind(cJSON *json) +{ + int32_t num; char *decryptstr; struct supernet_info M,*myinfo; struct iguana_info *coin = 0; + char *password,*permanentfile,*passphrase,*remoteaddr,*perspriv; + myinfo = 0; + if ( (password= jstr(json,"password")) == 0 ) + password = ""; + if ( (permanentfile= jstr(json,"permanentfile")) == 0 ) + permanentfile = ""; + if ( (passphrase= jstr(json,"passphrase")) == 0 ) + passphrase = ""; + remoteaddr = jstr(json,"remoteaddr"); + if ( (passphrase == 0 || passphrase[0] == 0) && (decryptstr= SuperNET_decryptjson(IGUANA_CALLARGS,password,permanentfile)) != 0 ) + { + if ( (json= cJSON_Parse(decryptstr)) != 0 ) + { + memset(&M,0,sizeof(M)); + if ( (perspriv= jstr(json,"persistent_priv")) != 0 && strlen(perspriv) == sizeof(bits256)*2 ) + { + M.persistent_priv = bits256_conv(perspriv); + SuperNET_setkeys(&M,0,0,0); + if ( (myinfo = SuperNET_MYINFOfind(&num,M.myaddr.persistent)) != 0 ) + { + printf("found account.(%s) %s %llu\n",myinfo!=0?myinfo->handle:"",M.myaddr.NXTADDR,(long long)M.myaddr.nxt64bits); + return(myinfo); + } + } + else if ( (passphrase= jstr(json,"result")) != 0 || (passphrase= jstr(json,"passphrase")) != 0 ) + { + SuperNET_setkeys(&M,passphrase,(int32_t)strlen(passphrase),1); + if ( (myinfo= SuperNET_MYINFOfind(&num,M.myaddr.persistent)) != 0 ) + { + printf("found account.(%s) %s %llu\n",myinfo!=0?myinfo->handle:"",M.myaddr.NXTADDR,(long long)M.myaddr.nxt64bits); + return(myinfo); + } + } else printf("no passphrase in (%s)\n",jprint(json,0)); + free_json(json); + } else printf("cant parse.(%s)\n",decryptstr); + free(decryptstr); + } + return(SuperNET_MYINFO(0)); +} + FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase) { - char *str,*decryptstr = 0; cJSON *argjson; + char *argstr,*str,*decryptstr = 0; cJSON *argjson; //uint32_t expire = myinfo->expiration; //savehandle[1024],savepassword[1024],savepermanentfile[1024] 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(savehandle,myinfo->handle,sizeof(myinfo->handle)); + //safecopy(savepassword,myinfo->secret,sizeof(myinfo->secret)); + //safecopy(savepermanentfile,myinfo->permanentfile,sizeof(myinfo->permanentfile)); + //if ( bits256_nonz(myinfo->persistent_priv) != 0 && (str= SuperNET_logout(IGUANA_CALLARGS)) != 0 ) + // free(str); + //myinfo->expiration = expire; + if ( handle != 0 && handle[0] != 0 ) safecopy(myinfo->handle,handle,sizeof(myinfo->handle)); - if ( (passphrase == 0 || passphrase[0] == 0) && (decryptstr= SuperNET_decryptjson(IGUANA_CALLARGS,password,permanentfile)) != 0 ) + else memset(myinfo->handle,0,sizeof(myinfo->handle)); + if ( password != 0 && password[0] != 0 ) + safecopy(myinfo->secret,password,sizeof(myinfo->secret)); + else if ( passphrase != 0 && passphrase[0] != 0 ) + safecopy(myinfo->secret,passphrase,sizeof(myinfo->secret)); + //else memset(myinfo->secret,0,sizeof(myinfo->secret)); + if ( permanentfile != 0 ) + safecopy(myinfo->permanentfile,permanentfile,sizeof(myinfo->permanentfile)); + //else memset(myinfo->permanentfile,0,sizeof(myinfo->permanentfile)); + if ( (decryptstr= SuperNET_decryptjson(IGUANA_CALLARGS,myinfo->secret,myinfo->permanentfile)) != 0 ) { if ( (argjson= cJSON_Parse(decryptstr)) != 0 ) { - printf("decrypted.(%s)\n",decryptstr); - free(decryptstr); - if ( (passphrase= jstr(argjson,"result")) != 0 ) + if ( jobj(argjson,"error") == 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\"}")); - } + //printf("decrypted.(%s) exp.%u pass.(%s)\n",decryptstr,myinfo->expiration,password); + if ( myinfo->decryptstr != 0 ) + free(myinfo->decryptstr); + myinfo->decryptstr = decryptstr; + if ( (passphrase= jstr(argjson,"passphrase")) != 0 ) + { + SuperNET_setkeys(myinfo,passphrase,(int32_t)strlen(passphrase),1); + free_json(argjson); + myinfo->expiration = (uint32_t)(time(NULL) + 3600); + return(SuperNET_activehandle(IGUANA_CALLARGS)); + } + else + { + free_json(argjson); + return(clonestr("{\"error\":\"cant find passphrase in decrypted json\"}")); + } + } else free_json(argjson); } else { @@ -1338,8 +1452,18 @@ FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase) 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 ) + if ( myinfo->decryptstr != 0 && (argjson= cJSON_Parse(myinfo->decryptstr)) != 0 ) + { + if ( jobj(argjson,"passphrase") != 0 ) + jdelete(argjson,"passphrase"); + if ( jobj(argjson,"error") != 0 ) + jdelete(argjson,"error"); + } else argjson = cJSON_CreateObject(); + jaddstr(argjson,"passphrase",passphrase); + argstr = jprint(argjson,1); + if ( (str= SuperNET_encryptjson(IGUANA_CALLARGS,myinfo->secret,myinfo->permanentfile,argstr)) != 0 ) free(str); + free(argstr); return(SuperNET_activehandle(IGUANA_CALLARGS)); } else return(clonestr("{\"error\":\"need passphrase\"}")); diff --git a/iguana/SuperNET.h b/iguana/SuperNET.h old mode 100644 new mode 100755 index 9493cae20..4a963b279 --- a/iguana/SuperNET.h +++ b/iguana/SuperNET.h @@ -19,7 +19,7 @@ #define SUPERNET_MAXHOPS 7 #include "../crypto777/OS_portable.h" #include "../includes/cJSON.h" -#include "../crypto777/nanosrc/nn.h" +//#include "../crypto777/nanosrc/nn.h" #define SUPERNET_GETPEERSTR "{\"agent\":\"SuperNET\",\"method\":\"getpeers\",\"plaintext\":1}" #define SUPERNET_STOPSTR "{\"agent\":\"SuperNET\",\"method\":\"stop\",\"plaintext\":1}" @@ -75,19 +75,20 @@ struct supernet_address struct supernet_info { - char ipaddr[64],transport[8]; int32_t APISLEEP; int32_t iamrelay; + char ipaddr[64],transport[8]; int32_t APISLEEP; int32_t iamrelay; uint32_t expiration,dirty; 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; char secret[2048],NXTAPIURL[512]; + bits256 privkey,persistent_priv,BTCmarkerhash; char secret[2048],NXTAPIURL[512],permanentfile[1024]; 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; + uint16_t LBport,PUBport,reqport,subport,rpcport,publicRPC,argport; + //struct nn_pollfd pfd[SUPERNET_MAXAGENTS]; //struct relay_info active; struct supernet_agent agents[SUPERNET_MAXAGENTS]; queue_t acceptQ; int32_t numagents,numexchanges; struct exchange_info *tradingexchanges[SUPERNET_MAXEXCHANGES]; - char handle[1024]; + struct iguana_waccount *wallet; void *ctx; + char handle[1024],*decryptstr; }; /*struct supernet_endpoint @@ -100,21 +101,31 @@ struct supernet_info struct category_chain { - bits256 *weights,*blocks,category_hwm,cchainhash; + bits256 *weights,*blocks,category_hwm,genesishash,hwmhash; 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); + int32_t (*blockhash_func)(struct category_chain *catchain,void *blockhashp,void *data,int32_t datalen); + int32_t (*payment_func)(struct category_chain *catchain,void *src,void *dest,uint64_t amount); + bits256 (*stake_func)(struct category_chain *catchain,void *addr,int32_t addrlen); + bits256 (*hit_func)(struct category_chain *catchain,int32_t height,void *prevgenerator,void *addr,void *blockhashp); + bits256 (*default_func)(struct category_chain *catchain,int32_t func,int32_t height,void *prevgenerator,void *addr,void *blockhashp,bits256 heaviest); + int32_t (*ishwm_func)(struct category_chain *catchain,int32_t prevheight,void *prevblockhashp,void *blockhashp,void *prevgenerator,void *addr); }; +struct crypto777_msghdr +{ + struct acct777_sig sig __attribute__((packed)); + bits256 prevhash,btchash; + uint8_t cmd[8]; + uint8_t serialized[]; +} __attribute__((packed)); + struct category_info { UT_hash_handle hh; queue_t Q; - char *(*processfunc)(struct supernet_info *myinfo,void *data,int32_t datalen,char *remoteaddr); - struct category_chain *cchain; + char *(*processfunc)(struct supernet_info *myinfo,struct category_info *cat,void *data,int32_t datalen,char *remoteaddr); + struct category_chain *catchain; bits256 hash; void *info; struct category_info *sub; }; extern struct category_info *Categories; @@ -127,12 +138,12 @@ struct endpoint calc_epbits(char *transport,uint32_t ipbits,uint16_t port,int32_ struct supernet_info *SuperNET_MYINFO(char *passphrase); void SuperNET_init(void *args); -char *SuperNET_JSON(struct supernet_info *myinfo,cJSON *json,char *remoteaddr); +char *SuperNET_JSON(struct supernet_info *myinfo,cJSON *json,char *remoteaddr,uint16_t port); -char *SuperNET_jsonstr(struct supernet_info *myinfo,char *jsonstr,char *remoteaddr); +char *SuperNET_jsonstr(struct supernet_info *myinfo,char *jsonstr,char *remoteaddr,uint16_t port); char *SuperNET_DHTencode(struct supernet_info *myinfo,char *destip,bits256 category,bits256 subhash,char *hexmsg,int32_t maxdelay,int32_t broadcastflag,int32_t plaintext); char *SuperNET_parser(struct supernet_info *myinfo,char *agent,char *method,cJSON *json,char *remoteaddr); -char *SuperNET_processJSON(struct supernet_info *myinfo,cJSON *json,char *remoteaddr); +char *SuperNET_processJSON(struct supernet_info *myinfo,cJSON *json,char *remoteaddr,uint16_t port); char *SuperNET_DHTsend(struct supernet_info *myinfo,uint64_t destipbits,bits256 category,bits256 subhash,char *hexmsg,int32_t maxdelay,int32_t broadcastflag,int32_t plaintext); uint16_t SuperNET_API2num(char *agent,char *method); int32_t SuperNET_num2API(char *agent,char *method,uint16_t num); @@ -143,9 +154,9 @@ cJSON *SuperNET_argjson(cJSON *json); 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,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 SuperNET_hexmsgprocess(struct supernet_info *myinfo,cJSON *retjson,cJSON *json,char *hexmsg,char *remoteaddr); +struct category_info *category_processfunc(bits256 categoryhash,bits256 subhash,char *(*process_func)(struct supernet_info *myinfo,struct category_info *cat,void *data,int32_t datalen,char *remoteaddr)); +char *pangea_hexmsg(struct supernet_info *myinfo,struct category_info *cat,void *data,int32_t len,char *remoteaddr); void pangea_queues(struct supernet_info *myinfo); int32_t SuperNET_str2hex(uint8_t *hex,char *str); @@ -154,21 +165,32 @@ void SuperNET_hexmsgadd(struct supernet_info *myinfo,bits256 categoryhash,bits25 int32_t SuperNET_hexmsgfind(struct supernet_info *myinfo,bits256 category,bits256 subhash,char *hexmsg,int32_t addflag); void category_posthexmsg(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash,char *hexmsg,struct tai now,char *remoteaddr); void *category_subscribe(struct supernet_info *myinfo,bits256 category,bits256 subhash); -struct category_msg *category_gethexmsg(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash); +struct category_msg *category_gethexmsg(struct supernet_info *myinfo,struct category_info **catptrp,bits256 categoryhash,bits256 subhash); char *SuperNET_htmlstr(char *fname,char *htmlstr,int32_t maxsize,char *agentstr); +queue_t *category_Q(struct category_info **catptrp,bits256 categoryhash,bits256 subhash); -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); +char *SuperNET_categorymulticast(struct supernet_info *myinfo,int32_t surveyflag,bits256 categoryhash,bits256 subhash,char *message,int32_t maxdelay,int32_t broadcastflag,int32_t plaintext,cJSON *argjson,char *remoteaddr); 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) +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,void *ishwm_func,void *payment_func); +#define category_default_latest() (*catchain->default_func)(catchain,'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); -bits256 bitcoin_pubkey33(uint8_t data[33],bits256 privkey); +char *InstantDEX_hexmsg(struct supernet_info *myinfo,struct category_info *cat,void *data,int32_t len,char *remoteaddr); +bits256 bitcoin_pubkey33(void *ctx,uint8_t data[33],bits256 privkey); char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey,int32_t len); +uint8_t *cards777_recover(uint8_t *shares[],uint8_t *sharenrs,int32_t M,int32_t numcards,int32_t N); +int32_t cards777_calcmofn(uint8_t *allshares,uint8_t *myshares[],uint8_t *sharenrs,int32_t M,bits256 *xoverz,int32_t numcards,int32_t N); +int32_t init_sharenrs(unsigned char sharenrs[255],unsigned char *orig,int32_t m,int32_t n); +struct supernet_info *SuperNET_MYINFOfind(int32_t *nump,bits256 pubkey); +void SuperNET_MYINFOadd(struct supernet_info *myinfo); +struct supernet_info *SuperNET_accountfind(cJSON *argjson); +int32_t SuperNET_MYINFOS(struct supernet_info **myinfos,int32_t max); +FILE *myfopen(char *fname,char *mode); +int32_t myfclose(FILE *fp); +cJSON *SuperNET_rosettajson(bits256 privkey,int32_t showprivs); #endif diff --git a/iguana/SuperNET_category.c b/iguana/SuperNET_category.c old mode 100644 new mode 100755 index 0aaff35e6..c56bce779 --- a/iguana/SuperNET_category.c +++ b/iguana/SuperNET_category.c @@ -15,6 +15,16 @@ #include "iguana777.h" +#include "../includes/tweetnacl.h" +#include "../crypto777/OS_portable.h" +#include "../includes/libgfshare.h" +#include "../includes/utlist.h" +#include "../includes/uthash.h" +#include "../includes/curve25519.h" +#include "../includes/cJSON.h" + + + bits256 calc_categoryhashes(bits256 *subhashp,char *category,char *subcategory) { bits256 categoryhash; @@ -47,11 +57,15 @@ struct category_info *category_find(bits256 categoryhash,bits256 subhash) return(0); } -queue_t *category_Q(bits256 categoryhash,bits256 subhash) +queue_t *category_Q(struct category_info **catptrp,bits256 categoryhash,bits256 subhash) { struct category_info *cat; + *catptrp = 0; if ( (cat= category_find(categoryhash,subhash)) != 0 ) + { + *catptrp = cat; return(&cat->Q); + } else return(0); } @@ -74,10 +88,10 @@ void *category_infoset(bits256 categoryhash,bits256 subhash,void *info) return(0); } -struct category_info *category_processfunc(bits256 categoryhash,char *(*process_func)(struct supernet_info *myinfo,void *data,int32_t datalen,char *remoteaddr)) +struct category_info *category_processfunc(bits256 categoryhash,bits256 subhash,char *(*process_func)(struct supernet_info *myinfo,struct category_info *cat,void *data,int32_t datalen,char *remoteaddr)) { struct category_info *cat; - if ( (cat= category_find(categoryhash,GENESIS_PUBKEY)) != 0 ) + if ( (cat= category_find(categoryhash,subhash)) != 0 ) { cat->processfunc = process_func; return(cat); @@ -85,169 +99,19 @@ struct category_info *category_processfunc(bits256 categoryhash,char *(*process_ return(0); } -int32_t category_default_blockhash(struct category_chain *cchain,void *blockhashp,void *data,int32_t datalen) -{ - 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) ) - { - printf("unsupported hashlen.%d or addrlen.%d\n",cchain->hashlen,cchain->addrlen); - return(zero); - } - 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); -} - -int32_t category_default_ishwm(struct category_chain *cchain,int32_t prevheight,void *prevblockhashp,void *blockhashp,void *prevgenerator,void *addr) -{ - bits256 checkhash,prevwt,oldhit,hit,heaviest; static bits256 zero; - checkhash = category_default_blockfind(prevheight); - if ( memcmp(checkhash.bytes,prevblockhashp,cchain->hashlen) == 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_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_chain *cchain = calloc(1,sizeof(*cchain)); - if ( (cat= category_find(categoryhash,subhash)) != 0 ) - { - 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); -} - -struct category_msg *category_gethexmsg(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash) +struct category_msg *category_gethexmsg(struct supernet_info *myinfo,struct category_info **catptrp,bits256 categoryhash,bits256 subhash) { queue_t *Q; //char str[65]; printf("getmsg.(%s) %llx\n",bits256_str(str,categoryhash),(long long)subhash.txid); - if ( (Q= category_Q(categoryhash,subhash)) != 0 ) + if ( (Q= category_Q(catptrp,categoryhash,subhash)) != 0 ) return(queue_dequeue(Q,0)); else return(0); } void category_posthexmsg(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash,char *hexmsg,struct tai now,char *remoteaddr) { - int32_t len; struct category_msg *m; queue_t *Q = 0; - if ( (Q= category_Q(categoryhash,subhash)) != 0 ) + int32_t len; struct category_msg *m; queue_t *Q = 0; struct category_info *cat; + if ( (Q= category_Q(&cat,categoryhash,subhash)) != 0 ) { len = (int32_t)strlen(hexmsg) >> 1; m = calloc(1,sizeof(*m) + len); @@ -311,9 +175,9 @@ int32_t category_broadcastflag(struct supernet_info *myinfo,bits256 category,bit return(broadcastflag); } -char *SuperNET_categorymulticast(struct supernet_info *myinfo,int32_t surveyflag,bits256 categoryhash,bits256 subhash,char *message,int32_t maxdelay,int32_t broadcastflag,int32_t plaintext) +char *SuperNET_categorymulticast(struct supernet_info *myinfo,int32_t surveyflag,bits256 categoryhash,bits256 subhash,char *message,int32_t maxdelay,int32_t broadcastflag,int32_t plaintext,cJSON *argjson,char *remoteaddr) { - char *hexmsg,*retstr; int32_t len; + char *hexmsg,*retstr; int32_t len; cJSON *retjson = cJSON_CreateObject(); len = (int32_t)strlen(message); //char str[65]; printf("multicast.(%s)\n",bits256_str(str,categoryhash)); if ( is_hexstr(message,len) == 0 ) @@ -325,8 +189,16 @@ char *SuperNET_categorymulticast(struct supernet_info *myinfo,int32_t surveyflag broadcastflag = category_broadcastflag(myinfo,categoryhash,subhash,broadcastflag); maxdelay = category_maxdelay(myinfo,categoryhash,subhash,maxdelay); retstr = SuperNET_DHTsend(myinfo,0,categoryhash,subhash,hexmsg,maxdelay,broadcastflag,plaintext); + //if ( 0 && argjson != 0 ) + // SuperNET_hexmsgprocess(myinfo,retjson,argjson,hexmsg,remoteaddr); if ( hexmsg != message) free(hexmsg); + if ( retjson != 0 ) + { + if ( retstr != 0 ) + jaddstr(retjson,"result",retstr); + retstr = jprint(retjson,1); + } return(retstr); } @@ -336,7 +208,7 @@ void category_init(struct supernet_info *myinfo) 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); + category_processfunc(pangeahash,GENESIS_PUBKEY,pangea_hexmsg); + category_chain_functions(myinfo,pangeahash,GENESIS_PUBKEY,sizeof(bits256),sizeof(bits256),0,0,0,0,0,0); exchanges777_init(myinfo,0,0); } diff --git a/iguana/SuperNET_hexmsg.c b/iguana/SuperNET_hexmsg.c old mode 100644 new mode 100755 index 2ce8c3fd6..b03701a9c --- a/iguana/SuperNET_hexmsg.c +++ b/iguana/SuperNET_hexmsg.c @@ -40,7 +40,7 @@ int32_t SuperNET_hexmsgfind(struct supernet_info *myinfo,bits256 category,bits25 } else if ( Packetcache[i] == packethash.txid ) { - printf("SuperNET_DHTsend reject duplicate packet.%llx\n",(long long)packethash.txid); + //printf("SuperNET_DHTsend reject duplicate packet.%llx\n",(long long)packethash.txid); return(i); } } @@ -73,9 +73,9 @@ void SuperNET_hexmsgadd(struct supernet_info *myinfo,bits256 categoryhash,bits25 //printf("HEXMSG.(%s).%llx -> %s\n",hexmsg,(long long)subhash.txid,str); } -void SuperNET_hexmsgprocess(struct supernet_info *myinfo,cJSON *json,char *hexmsg,char *remoteaddr) +void SuperNET_hexmsgprocess(struct supernet_info *myinfo,cJSON *retjson,cJSON *json,char *hexmsg,char *remoteaddr) { - int32_t len,flag=0; char *str; 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,subhash; struct category_info *cat; if ( hexmsg != 0 ) { len = (int32_t)strlen(hexmsg); @@ -86,12 +86,19 @@ void SuperNET_hexmsgprocess(struct supernet_info *myinfo,cJSON *json,char *hexms buf = malloc(len); decode_hex(buf,len,hexmsg); categoryhash = jbits256(json,"categoryhash"); - if ( (cat= category_find(categoryhash,GENESIS_PUBKEY)) != 0 ) + subhash = jbits256(json,"categoryhash"); + if ( bits256_nonz(subhash) == 0 ) + subhash = GENESIS_PUBKEY; + if ( (cat= category_find(categoryhash,subhash)) != 0 ) { if ( cat->processfunc != 0 ) { - if ( (str= (*cat->processfunc)(myinfo,buf,len,remoteaddr)) != 0 ) - free(str); + if ( (str= (*cat->processfunc)(myinfo,cat,buf,len,remoteaddr)) != 0 ) + { + if ( retjson != 0 ) + jaddstr(retjson,"processfunc",str); + else free(str); + } flag = 1; //printf("PROCESSFUNC\n"); } @@ -107,3 +114,277 @@ void SuperNET_hexmsgprocess(struct supernet_info *myinfo,cJSON *json,char *hexms } } } + +int32_t category_default_blockhash(struct category_chain *catchain,void *blockhashp,void *data,int32_t datalen) +{ + 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 *catchain,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 *catchain,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,catchain->addrlen,addr,catchain->addrlen); + hit = (*catchain->stake_func)(catchain,addr,catchain->addrlen); + rawhit.txid = hash.txid % ((uint64_t)1 << 42); + if ( rawhit.txid != 0 ) + hit.txid /= rawhit.txid; + return(hit); +} + +#define category_default_heaviest() (*catchain->default_func)(catchain,'H',0,0,0,0,zero) +#define category_default_latest() (*catchain->default_func)(catchain,'L',0,0,0,0,zero) +#define category_default_setheaviest(height,blockhashp,heaviest) (*catchain->default_func)(catchain,'S',height,0,0,blockhashp,zero) +#define category_default_weight(height) (*catchain->default_func)(catchain,'W',height,0,0,0,zero) +#define category_default_blockfind(height) (*catchain->default_func)(catchain,'B',height,0,0,0,zero) + +bits256 category_default_func(struct category_chain *catchain,int32_t func,int32_t height,void *prevgenerator,void *addr,void *blockhashp,bits256 heaviest) +{ + static const bits256 zero; + if ( catchain->hashlen != sizeof(bits256) || catchain->addrlen != sizeof(bits256) ) + { + printf("unsupported hashlen.%d or addrlen.%d\n",catchain->hashlen,catchain->addrlen); + return(zero); + } + if ( height > catchain->maxblocknum + (func == 'S') ) + { + printf("error func.%c setting heaviest. skipped %d -> %d?\n",func,catchain->maxblocknum,height); + return(catchain->category_hwm); + } + if ( func == 'H' ) + return(catchain->category_hwm); + else if ( func == 'L' ) + { + if ( catchain->maxblocknum < 0 ) + return(catchain->genesishash); + else return(catchain->blocks[catchain->maxblocknum]); + } + else if ( func == 'S' ) + { + catchain->category_hwm = heaviest; + if ( height > catchain->maxblocknum ) + { + catchain->weights = realloc(catchain->weights,(catchain->maxblocknum+1) * sizeof(*catchain->weights)); + catchain->blocks = realloc(catchain->blocks,(catchain->maxblocknum+1) * sizeof(*catchain->blocks)); + } + catchain->maxblocknum = height; + catchain->weights[height] = heaviest; + if ( blockhashp != 0 ) + memcpy(&catchain->blocks[height],blockhashp,sizeof(catchain->blocks[height])); + } + else if ( func == 'B' ) + { + if ( height <= catchain->maxblocknum ) + return(catchain->blocks[height]); + else + { + printf("error: illegal height.%d vs max.%d\n",height,catchain->maxblocknum); + return(zero); + } + } + else if ( func == 'W' ) + { + if ( height >= 0 && height < catchain->maxblocknum ) + return(catchain->weights[height]); + else printf("error getting weight for height.%d vs maxblocknum.%d\n",height,catchain->maxblocknum); + } + return(catchain->category_hwm); +} + +int32_t category_default_ishwm(struct category_chain *catchain,int32_t prevheight,void *prevblockhashp,void *blockhashp,void *prevgenerator,void *addr) +{ + bits256 checkhash,prevwt,oldhit,hit,heaviest; static const bits256 zero; + checkhash = category_default_blockfind(prevheight); + if ( memcmp(checkhash.bytes,prevblockhashp,catchain->hashlen) == 0 ) + { + heaviest = category_default_heaviest(); + prevwt = category_default_weight(prevheight); + oldhit = category_default_weight(prevheight+1); + hit = (*catchain->hit_func)(catchain,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); +} + +int32_t category_default_payment(struct category_chain *catchain,void *src,void *dest,uint64_t amount) +{ + //uint32_t srcind=0,destind=0; + // catchain->balances[destind] += amount; + // catchain->balances[srcind] -= amount; + return(0); +} + +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,void *ishwm_func,void *payment_func) +{ + struct category_info *cat; struct category_chain *catchain = calloc(1,sizeof(*catchain)); + if ( (cat= category_find(categoryhash,subhash)) != 0 ) + { + catchain->maxblocknum = -1; + catchain->myinfo = myinfo, catchain->subinfo = cat->info; + if ( bits256_cmp(subhash,GENESIS_PUBKEY) == 0 ) + catchain->categoryinfo = cat->info, catchain->genesishash = categoryhash; + else catchain->categoryinfo = category_find(categoryhash,GENESIS_PUBKEY), catchain->genesishash = subhash; + if ( catchain->myinfo == 0 || catchain->categoryinfo || catchain->subinfo ) + { + printf("error with catchain pointers\n"); + return(0); + } + if ( (catchain->addrlen= addrlen) <= 0 || (catchain->hashlen= hashlen) <= 0 ) + { + printf("error with catchain lens.%d %d\n",addrlen,hashlen); + return(0); + } + if ( (catchain->blockhash_func= hash_func) == 0 || (catchain->stake_func= stake_func) == 0 || (catchain->hit_func= hit_func) == 0 || (catchain->default_func= default_func) == 0 || (catchain->ishwm_func= ishwm_func) == 0 || (catchain->payment_func= payment_func) == 0 ) + { + if ( addrlen == sizeof(bits256) && hashlen == sizeof(bits256) ) + { + catchain->blockhash_func = category_default_blockhash; + catchain->stake_func = category_default_stake; + catchain->hit_func = catgory_default_hit; + catchain->default_func = category_default_func; + catchain->ishwm_func = category_default_ishwm; + catchain->payment_func = category_default_payment; + } + else + { + printf("no category chain functions and addrlen.%d hashlen.%d not 32\n",addrlen,hashlen); + return(0); + } + } + cat->catchain = catchain; + return(catchain); + } + return(0); +} + +struct crypto777_msghdr *crypto777_msgcreate(struct supernet_info *myinfo,struct crypto777_msghdr *msg,int32_t datalen) +{ + bits256 otherpubkey; uint64_t signerbits; uint32_t timestamp; uint8_t buf[sizeof(msg->sig)],*data; + memset(&msg->sig,0,sizeof(msg->sig)); + datalen += (int32_t)(sizeof(*msg) - sizeof(msg->sig)); + data = (void *)((long)msg + sizeof(msg->sig)); + otherpubkey = acct777_msgpubkey(data,datalen); + timestamp = (uint32_t)time(NULL); + acct777_sign(&msg->sig,myinfo->privkey,otherpubkey,timestamp,data,datalen); + if ( (signerbits= acct777_validate(&msg->sig,acct777_msgprivkey(data,datalen),msg->sig.pubkey)) != 0 ) + { + //int32_t i; + //char str[65],str2[65]; + //for (i=0; i>>>>>>>>>>>>>>> validated [%ld] len.%d (%s + %s)\n",(long)data-(long)msg,datalen,bits256_str(str,acct777_msgprivkey(data,datalen)),bits256_str(str2,msg->sig.pubkey)); + memset(buf,0,sizeof(buf)); + acct777_rwsig(1,buf,&msg->sig); + memcpy(&msg->sig,buf,sizeof(buf)); + return(msg); + } else printf("error validating crypto777_msgcreate msg\n"); + return(0); +} + +void crypto777_catchain(struct supernet_info *myinfo,struct category_info *cat,bits256 *prevhashp,bits256 *btchashp) +{ + *btchashp = myinfo->BTCmarkerhash; + *prevhashp = cat->catchain->hwmhash; +} + +char *crypto777_sendmsg(struct supernet_info *myinfo,bits256 category,bits256 subhash,uint8_t *data,int32_t datalen,int32_t hops,char cmdstr[8]) +{ + char *hexstr,*retstr; int32_t i; struct crypto777_msghdr *msg; bits256 prevhash,btchash; struct category_info *cat; + msg = calloc(1,datalen + sizeof(*msg)); + for (i=0; icmd); i++) + if ( (msg->cmd[i]= cmdstr[i]) == 0 ) + break; + cat = category_info(category,subhash); + crypto777_catchain(myinfo,cat,&prevhash,&btchash); + iguana_rwbignum(1,msg->prevhash.bytes,sizeof(bits256),prevhash.bytes); + iguana_rwbignum(1,msg->btchash.bytes,sizeof(bits256),btchash.bytes); + memcpy(msg->serialized,data,datalen); + if ( crypto777_msgcreate(myinfo,msg,datalen) != 0 ) + { + printf(">>>>>>>>>>>> crypto777_send.(%s) datalen.%d allocsize.%d crc.%x\n",cmdstr,datalen,msg->sig.allocsize,calc_crc32(0,(void *)((long)msg + 8),datalen-8)); + hexstr = malloc(msg->sig.allocsize*2 + 1); + init_hexbytes_noT(hexstr,(uint8_t *)msg,msg->sig.allocsize); + retstr = SuperNET_categorymulticast(myinfo,0,category,subhash,hexstr,0,hops,1,0,0); + free(hexstr), free(msg); + return(retstr); + } + else + { + free(msg); + printf("cant crypto777 msgcreate datalen.%d\n",datalen); + return(clonestr("{\"error\":\"couldnt create crypto777 message\"}")); + } +} + +char *crypto777_hexmsg(struct supernet_info *myinfo,void *ptr,int32_t len,char *remoteaddr) +{ + struct crypto777_msghdr *msg = ptr; int32_t slen,datalen,newlen,flag = 0; bits256 prevhash,btchash; + uint8_t *serdata; uint64_t signerbits; uint8_t tmp[sizeof(msg->sig)]; cJSON *argjson = 0; + datalen = len - (int32_t)sizeof(msg->sig); + serdata = (void *)((long)msg + sizeof(msg->sig)); + acct777_rwsig(0,(void *)&msg->sig,(void *)tmp); + memcpy(&msg->sig,tmp,sizeof(msg->sig)); + /*if ( remoteaddr != 0 && remoteaddr[0] == 0 && strcmp("127.0.0.1",remoteaddr) == 0 && ((uint8_t *)msg)[len-1] == 0 && (argjson= cJSON_Parse((char *)msg)) != 0 ) + { + printf("string crypto777_hexmsg RESULT.(%s)\n",jprint(argjson,0)); + free_json(argjson); + return(clonestr("{\"error\":\"string base packets deprecated\"}")); + } + else*/ if ( (signerbits= acct777_validate(&msg->sig,acct777_msgprivkey(serdata,datalen),msg->sig.pubkey)) != 0 ) + { + flag++; + iguana_rwbignum(0,msg->prevhash.bytes,sizeof(bits256),prevhash.bytes); + iguana_rwbignum(0,msg->btchash.bytes,sizeof(bits256),btchash.bytes); + printf("crypto777_hexmsg <<<<<<<<<<<<< sigsize.%d VALIDATED [%ld] len.%d t%u allocsize.%d (%s) [%d]\n",(int32_t)sizeof(msg->sig),(long)serdata-(long)msg,datalen,msg->sig.timestamp,msg->sig.allocsize,(char *)msg->serialized,serdata[datalen-1]); + newlen = (int32_t)(msg->sig.allocsize - ((long)msg->serialized - (long)msg)); + serdata = msg->serialized; + if ( (argjson= cJSON_Parse((char *)serdata)) != 0 ) + { + slen = (int32_t)strlen((char *)serdata) + 1; + serdata = &serdata[slen]; + newlen -= slen; + free_json(argjson); + } + } + return(clonestr("{\"result\":\"test packet\"}")); +} + +/* + Consensus rules: + 0. Valid burn protocol or new issuance with small fee to crypto777 account -> OP_RETURN on BTCD with txid of payment/burn + Ti boundary - Balances reconciled and signed by issuer or super majority vote. Only amounts marked as frozen eligible for atomic swaps. + tx via p2p, signed payment to dest acct, based on balance. no outputs to double spend + payment valid during Ti and Ti+1 + atomic cross chain: both sides freeze trade amount, wait for this to be confirmed in BTC OP_RETURN, then a joint swap tx is signed by both and submitted to both chains + + valid tx must be accepted and sig added with Ti slippage. It is valid if signed, and balance is available. + + When Ti boundary changes, all online nodes reconcile the submitted tx to make sure all are confirmed and balances updated. Special tx like freezing, atomics, etc. + +Top PoS account publishes balance changes and majority stake approves. Next trade period starts at Ti+2 + + Split into odd/even offset periods to allow nonstop tx + + 1. all nodes must ntp and all tx must be timestamped within 50 seconds in the past and cant be more than 10 seconds from the future. + 2. tx spends cannot exceed available balance/2 as of prior Ti. + 2. all tx must refer to the latest BTC.Ti and BTCD.Ti and BTC.RTblock. any tx received that has older BTC.Ti is rejected. + 3. +*/ diff --git a/iguana/SuperNET_keys.c b/iguana/SuperNET_keys.c old mode 100644 new mode 100755 index efd6bb6b6..a9a95a422 --- a/iguana/SuperNET_keys.c +++ b/iguana/SuperNET_keys.c @@ -14,6 +14,14 @@ ******************************************************************************/ #include "iguana777.h" +#include "../includes/tweetnacl.h" +#include "../crypto777/OS_portable.h" +#include "../includes/libgfshare.h" +#include "../includes/utlist.h" +#include "../includes/uthash.h" +#include "../includes/curve25519.h" +#include "../includes/cJSON.h" + bits256 SuperNET_wallet2shared(bits256 wallethash,bits256 wallet2priv) { @@ -70,7 +78,10 @@ char *SuperNET_parsemainargs(struct supernet_info *myinfo,bits256 *wallethashp,b 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); + myinfo->expiration = (uint32_t)(time(NULL) + 600); + } } exchanges = jarray(&n,json,"exchanges"); if ( jobj(json,"coins") != 0 ) @@ -115,36 +126,48 @@ bits256 SuperNET_linehash(char *_line) return(hash); } -int32_t SuperNET_savejsonfile(char *fname,bits256 privkey,bits256 destpubkey,cJSON *json) +int32_t SuperNET_savejsonfile(char *finalfname,bits256 privkey,bits256 destpubkey,cJSON *json) { - char *confstr,*ciphered; FILE *fp; + char *confstr,*ciphered; char destfname[1024]; FILE *fp; int32_t retval = -1; + strcpy(destfname,finalfname); + if ( (fp= fopen(finalfname,"rb")) != 0 ) + strcat(destfname,".tmp"); 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 ) + //printf("ciphered.save (%s) <- (%s)\n",fname,confstr); + if ( (fp= fopen(destfname,"wb")) != 0 ) { - fwrite(ciphered,1,strlen(ciphered)+1,fp); + if ( fwrite(ciphered,1,strlen(ciphered)+1,fp) == strlen(ciphered)+1 ) + retval = 0; fclose(fp); } free(ciphered); - } else printf("error ciphering.(%s) (%s)\n",fname,confstr); + } else printf("error ciphering.(%s) (%s)\n",destfname,confstr); } else { //sprintf(fname,"confs/iguana.conf"); - //printf("save (%s) <- (%s)\n",fname,confstr); - if ( (fp= fopen(fname,"wb")) != 0 ) + //printf("save (%s) <- (%s)\n",destfname,confstr); + if ( (fp= fopen(destfname,"wb")) != 0 ) { - fwrite(confstr,1,strlen(confstr)+1,fp); + if ( fwrite(confstr,1,strlen(confstr)+1,fp) == strlen(confstr)+1 ) + retval = 0; fclose(fp); } } free(confstr); - return(0); + if ( retval == 0 && strcmp(destfname,finalfname) != 0 ) + { + char oldfname[1024]; + strcpy(oldfname,finalfname), strcat(oldfname,".old"); + OS_renamefile(finalfname,oldfname); + OS_renamefile(destfname,finalfname); + } + return(retval); } int32_t SuperNET_userkeys(char *passphrase,int32_t passsize,char *fname2fa,int32_t fnamesize) @@ -165,9 +188,9 @@ int32_t SuperNET_userkeys(char *passphrase,int32_t passsize,char *fname2fa,int32 return(-1); } -cJSON *SuperNET_decryptedjson(char *passphrase,int32_t passsize,bits256 wallethash,char *fname2fa,int32_t fnamesize,bits256 wallet2priv) +cJSON *SuperNET_decryptedjson(char *destfname,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]; + long allocsize; cJSON *filejson,*msgjson=0,*json=0; char *confstr=0,*deciphered,str[65]; bits256 wallet2shared,wallet2pub; int32_t first,second; msgjson = 0; first = (bits256_nonz(wallethash) != 0 && bits256_cmp(wallethash,GENESIS_PRIVKEY) != 0); @@ -189,16 +212,17 @@ cJSON *SuperNET_decryptedjson(char *passphrase,int32_t passsize,bits256 walletha 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 ) + sprintf(destfname,"confs/%s",bits256_str(str,wallet2pub)); + //printf("fname.(%s) wallet2pub.%s < [%s, %s]\n",destfname,bits256_str(str,wallet2pub),passphrase,fname2fa); + if ( (confstr= OS_filestr(&allocsize,destfname)) != 0 ) { if ( (filejson= cJSON_Parse(confstr)) != 0 ) { + //printf("confstr.(%s)\n",confstr); 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); + printf("cant decipher (%s) [%s]\n",destfname,confstr); else { if ( (msgjson= cJSON_Parse(jstr(json,"message"))) == 0 ) @@ -208,16 +232,16 @@ cJSON *SuperNET_decryptedjson(char *passphrase,int32_t passsize,bits256 walletha } free_json(filejson); } - } else printf("couldnt load (%s)\n",fname); + } else printf("couldnt load (%s)\n",destfname); } else { - sprintf(fname,"confs/iguana.conf"); - if ( (confstr= OS_filestr(&allocsize,fname)) != 0 ) + sprintf(destfname,"confs/iguana.conf"); + if ( (confstr= OS_filestr(&allocsize,destfname)) != 0 ) { if ( (json= cJSON_Parse(confstr)) != 0 ) msgjson = json; - } else printf("couldnt open (%s)\n",fname); + } else printf("couldnt open (%s)\n",destfname); } if ( msgjson != 0 ) msgjson = jduplicate(msgjson); @@ -235,10 +259,11 @@ int32_t _SuperNET_encryptjson(char *destfname,char *passphrase,int32_t passsize, 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)); + //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("SAVE ARGJSON.(%s) [%s, %s] -> destfname.(%s)\n",jprint(argjson,0),passphrase,fname2fa,destfname); //printf("shared.%llx -> pub.%s\n",(long long)wallet2shared.txid,bits256_str(str,wallet2pub)); SuperNET_savejsonfile(destfname,wallethash,wallet2pub,argjson); return(0); @@ -246,7 +271,7 @@ int32_t _SuperNET_encryptjson(char *destfname,char *passphrase,int32_t passsize, void SuperNET_setkeys(struct supernet_info *myinfo,void *pass,int32_t passlen,int32_t dosha256) { - char pubkeystr[128]; uint8_t pubkey33[33]; bits256 hash; + uint8_t pubkey33[33]; bits256 hash; if ( dosha256 != 0 ) { memcpy(myinfo->secret,pass,passlen+1); @@ -260,10 +285,11 @@ void SuperNET_setkeys(struct supernet_info *myinfo,void *pass,int32_t passlen,in 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); + bitcoin_pubkey33(myinfo->ctx,pubkey33,myinfo->persistent_priv); + //btc_priv2pub(pubkey33,myinfo->persistent_priv.bytes); + //init_hexbytes_noT(pubkeystr,pubkey33,33); + bitcoin_address(myinfo->myaddr.BTC,0,pubkey33,33); + bitcoin_address(myinfo->myaddr.BTCD,60,pubkey33,33); } void SuperNET_parsemyinfo(struct supernet_info *myinfo,cJSON *msgjson) @@ -306,7 +332,7 @@ char *SuperNET_keysinit(struct supernet_info *myinfo,char *argjsonstr) 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 ) + if ( (msgjson= SuperNET_decryptedjson(destfname,passphrase,sizeof(passphrase),wallethash,fname2fa,sizeof(fname2fa),wallet2priv)) != 0 ) { SuperNET_parsemyinfo(myinfo,msgjson); free_json(msgjson); @@ -360,7 +386,27 @@ char *SuperNET_keysinit(struct supernet_info *myinfo,char *argjsonstr) #include "../includes/iguana_apidefs.h" #include "../includes/iguana_apideclares.h" -THREE_STRINGS(SuperNET,encryptjson,password,permanentfile,anything) +TWO_STRINGS(SuperNET,decryptjson,password,permanentfile) +{ + char pass[8192],fname2[1023],destfname[1024]; cJSON *retjson; 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); + if ( (retjson= SuperNET_decryptedjson(destfname,pass,sizeof(pass),wallethash,fname2,sizeof(fname2),wallet2priv)) != 0 ) + { + printf("decrypt pass.(%s) fname2.(%s) -> destfname.(%s)\n",pass,fname2,destfname); + //obj = jduplicate(jobj(retjson,"payload")); + //jdelete(retjson,"payload"); + //jadd(retjson,"result",obj); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"couldnt decrypt json file\"}")); +} + +THREE_STRINGS(SuperNET,encryptjson,password,permanentfile,payload) { char destfname[4096],pass[8192],fname2[1023]; cJSON *argjson,*retjson = cJSON_CreateObject(); safecopy(pass,password,sizeof(pass)); @@ -381,27 +427,6 @@ THREE_STRINGS(SuperNET,encryptjson,password,permanentfile,anything) 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" diff --git a/iguana/app/coin_mgmt.js b/iguana/app/coin_mgmt.js old mode 100644 new mode 100755 index fdeef78aa..a7077faf1 --- a/iguana/app/coin_mgmt.js +++ b/iguana/app/coin_mgmt.js @@ -369,7 +369,7 @@ var startCoin = function (id) { var addExistingCoin = function (id) { var isactive=0; - var maxpeers=16; + var maxpeers=SPNAPI.settings.maxpeers; var services=128; var index = coinManagement.GetCoinIndex(id); console.log('# coin add called '+index); diff --git a/iguana/app/common.js b/iguana/app/common.js old mode 100644 new mode 100755 diff --git a/iguana/app/startup.js b/iguana/app/startup.js old mode 100644 new mode 100755 index fe252ba32..08f379de1 --- a/iguana/app/startup.js +++ b/iguana/app/startup.js @@ -20,15 +20,15 @@ $(function () { pauseCoin(e.getAttribute('data-id')); } else if (e.className && e.className.indexOf('addPeerToFav') != -1) { - addPeerToFav(e.getAttribute('data-id'),e.getAttribute('data-coin')); + update_favourite(e.getAttribute('data-coin'),e.getAttribute('data-ip'),e.getAttribute('data-id'),true); } else if (e.className && e.className.indexOf('removePeerFromFav') != -1) { - removePeerFromFav(e.getAttribute('data-id'),e.getAttribute('data-coin')); + update_favourite(e.getAttribute('data-coin'),e.getAttribute('data-ip'),e.getAttribute('data-id'),false); }else if(e.className && e.className.indexOf('disconnectPeer') != -1){ - disconnectPeer(e.getAttribute('data-ip'),e.getAttribute('data-coin')); + disconnectPeer(e.getAttribute('data-ip'),e.getAttribute('data-coin'),e.getAttribute('data-id')); }else if(e.className && e.className.indexOf('connectPeer') != -1){ - connectPeer(e.getAttribute('data-ip'),e.getAttribute('data-coin')); + connectPeer(e.getAttribute('data-ip'),e.getAttribute('data-coin'),e.getAttribute('data-id')); }else if(e.className && e.className.indexOf('coinRPCactive') != -1){ callBlockEXPRPC(e.getAttribute('data-value')); @@ -137,14 +137,42 @@ $(function () { InstantDEX_allpairs(); } - // + + else if(e.className && e.className.indexOf('saveConfFiles_onclick') != -1){ + reset_conf_files(); + + } + else if(e.className && e.className.indexOf('connect_to_peers_from_conf') != -1){ + + if(peers_pool.peers.length==0) + load_peers_from_conf(); + + } + else if(e.className && e.className.indexOf('update_allpeer_status') != -1){ + update_allpeer_status(); + + } + else if(e.className && e.className.indexOf('save_peersdata_to_conf') != -1){ + save_peersdata_to_conf(); + + } + else if(e.className && e.className.indexOf('deletePeertabFile_onclick') != -1){ + deletePeertabFile_onclick(); + + } + else if(e.className && e.className.indexOf('TradeIntegrationTest') != -1){ + TradeIntegrationTest(); + + } + }; $("div .btn-primary").on("click",function(){ $("div .btn-primary").each(function(){ $(this).removeClass('btn-raised'); }); - $(this).addClass("btn-raised"); + if(! $(this).hasClass( "_not_pressed" )){ + $(this).addClass("btn-raised");} }); }); \ No newline at end of file diff --git a/iguana/btcd b/iguana/btcd new file mode 100755 index 000000000..a2ad9d596 --- /dev/null +++ b/iguana/btcd @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"prefetchlag\":-1,\"poll\":1,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"BTCD\",\"startpend\":100,\"endpend\":100,\"services\":128,\"maxpeers\":64}" diff --git a/iguana/confs/.tmpmarker b/iguana/confs/.tmpmarker old mode 100644 new mode 100755 diff --git a/iguana/confs/BTCD_hdrs.h b/iguana/confs/BTCD_hdrs.h new file mode 100644 index 000000000..591a99b77 --- /dev/null +++ b/iguana/confs/BTCD_hdrs.h @@ -0,0 +1,2118 @@ +char *BTCD_hdrs[][4] = { +{ "0", "0000044966f40703b516c5af180582d53f783bfd319bb045e2dc3e05ea695d46", "a5d211145f8e6ba0920b2893d307c5d7c207ae0800a80955299678d1706ea8ac", "000000000c4682089c916de89eb080a877566494d4009c0089baf35fe94de22f"}, +{ "500", "000000000680a9a697eb71155b18a5827e0889fca28afb81fcbb46469ed7877e", "79f80a8f54c6762d6408347c6dd7dfd2f8b8c191077c1d7881dfc5b7ec6a408e", "0000000002b868fe717dc60b8d146de4d9aecf779b7314224908566e01847769"}, +{ "1000", "0000000000000cf908c887020f8970b7fe952f8b81164d83a87621dfdb581d08", "3356ec4296ff2f04281492b0dedbaed80edeb6dd9170b87230ff79f6b0daade7", "0000000000001e7c6d28962a03b3d75ffa1355ecc6d3021893b2727a1ccfc669"}, +{ "1500", "00000000000010e39eaa987e695caed67aa0f3c33576fd2621422c7c09152ca2", "e9d31ec9f5dd4dc2688791edd4cd1abc964a7f843c59b948903c3492940e459a", "00000000000008c67c2e1a3dd564c1effa5ac4edb11b8326e790b01d215b10a9"}, +{ "2000", "000000000000029e318c44be8a5e1d5bc8f7823907bad160aa63fd6121dd0ba0", "15e2439021c4563c7eab5b91c916a0c9c24c3fb374b49ea24a4e2aec241ab099", "0000000000000477e2b3fe268246df89cc66d4df5ded6eb1339f46fc3d41e637"}, +{ "2500", "0000000000000b813b136f623f85155cad3069031cde918b4079e907e1a9fd58", "76ef339392ae45dbfeb2c6263e4e88b4cf888264d7ce8d0361258a81061fadb6", "000000000000219c3f912aedf5899b545ad237a1bdc16fc4111e092dba394e00"}, +{ "3000", "00000000000000e5ac27d3bb729f5c8a4312f69b28c9cefbb18b8fb55ee42c87", "dee1d4ef373897e52847416837485706f5c0fe29245eccb0819ea5d32f594051", "0000000000000858c1d9330cbe0318d79ec09d00d8b020245f4ebf7e304cc2d4"}, +{ "3500", "000000000000123b4e50db3f3706974f7e3593c2897bb545177d5c8a5a11fd35", "75c65538d4fd33e5a77d5b9e5d756587f45a7cdf55646f1cd72f2da2b7ae5772", "e0fc6aa659df9d7d095a90cdb67637df1d2802227242b139e988d5202669030d"}, +{ "4000", "000000000000013e3c1513a7ffd71ba89d7440fcacef6bb39a76527815a71043", "6ca70d4bd86a4dabdf5312a88a99aeb874d851df717879049d8d91b464109adc", "00000000000007a831e09844b26f357a1476bf9e99959ac3dbb92447e938835f"}, +{ "4500", "00000000000006e6d70e292394dd1f4aaf1ba3ea7313ae981a0b2f38ec4b0503", "e97f1c03d9e0445a00c160c648d2f4920845502e788f5c3f2a5a392544e18d0f", "00000000000008c83a46958c24fca62b35237889269858a639c7a659ad8dc031"}, +{ "5000", "0000000000000278ac01346559ded91fc585defc88bbaa9d7f111b199e516779", "45f12a1790418c3e9000bca11394719138f398232fd62ed3c801b5eb1e9199c5", "1a022cc6d920c078509ee34069e3671e195d7a906d0a2c7cf78dd2849d53a85e"}, +{ "5500", "0000000000000284e3d2455f09d9613ff71c49144823f882b003ed3177c1abab", "149ab9c582053c69b64d9b3c3041f04527bcd47c572d600947d0f737d675f953", "00000000000012ec069ab657694add0d888db799ec7c108c6de58b71da884f10"}, +{ "6000", "0000000000000bd43190ec79e54ba203c9387abcc8c1c03c52452a44466f24b9", "ab0f1f81aaf4000295bec7b21ad5c272aecf7dee60c451bcbfafb0beddabd2be", "0000000000000ecd84126d8a476fe76920ccd8ed29f4a2273a345eaa489f7722"}, +{ "6500", "000000000000029e27c331ad9865fee87dd19e5ed0e526f9974510649616cc1b", "9ee7b5e21984f8e3ceaa88aba5ab2d88dda10cf28c57b826e3bc8401d0bac0cd", "00000000000009a940eb271c38622190df017bb472da54a9a1aa218c5bf6cbd3"}, +{ "7000", "000000000000034bfd6bd049678a41563af84a9581d1ccaeb4952c954e327918", "e09213923b66de743cf8edc0389ab1b6c07c0c79a175b3e93364ed73c2efeb69", "0000000000000b7d67e13d24448ae494f169723a215e0d5c2f712af1e8e8b7fe"}, +{ "7500", "00000000000003c5a246cab977e3f339041bc95aec5cddcc3d459d3d2cd546a7", "4f26360f00347667d1c2f108ad3e2b2f599a599cb77b1ba9936988664ac53d4d", "00000000000005ffe9c2f6517f0e04151c40e9d8cddefccd34b71e0d4d35fb34"}, +{ "8000", "34d2ddf9aa94d6e02224588d3d6585028a22f05f53529a19a202f41ceb36cefc", "8bc3244b74f884ae355598fe0200a7f09bfab53de1b3e122020c4e2daf08fb63", "920cc777b15af320bdd69029399e2632bdfd8b741de509f2517ffb8feadf9493"}, +{ "8500", "87ddea52f5073e5283ecaf0efc637da3a47986396ad30b3adec8ea2ba5f6a09b", "65ae81f7094626494fe8b984141c265f689f4d6abd33a3a74eb491c31c5d02eb", "4349cc0c4c3040b098d7f6bcf5f98b47ce1057505800e7126f080024dad8d377"}, +{ "9000", "000000000000016845387841c3d5a584d82763471d4b84af3921ee2832715e4e", "11b2851886bc2208cd41c8381ff7bd6350379f6c0224f9608450fb0da56a59d0", "00000000000002e96fe9805c42c0bc4b6a8811ba63fa835f2cc2883635d8c98e"}, +{ "9500", "e64e3a10f2daca17836d2bb5868e76290da1fd3e0574da496b06182033fc70ac", "5d6ac130a3a5cbbf28cf389cda08aabe9cd5bd9a4da2d0ecd19c27d9ab2320fa", "0000000000000040b3de6fb9627d96a86bac4cd28e20cd2356724a9604fd5e55"}, +{ "10000", "00000000000001634bb95749a866092348aef266f9169c3ddbcf226d4807ba09", "986b59e97d259c74881bec99d68adad8e219a0fcaaff6af3fa31b0b5a89e1b33", "0000000000000069574ac2e1558be068e9f0306b79d0812476002ce7f17febf2"}, +{ "10500", "9a98c541a5e55bcfc8eb6d887d83dc6049a33381fe0aa3f4766006c1fb066905", "3dc29b2469167c07aab94fcd87c03e0bad1a99d47c3594d80b700b05190eb526", "00000000000002d53a0ae3c22c4424fd877c898dc08cc90860b382c68e4c8e45"}, +{ "11000", "54bafbe72c3547248f553615eacb2254fefe5a4d4cdcc66a2efde3e1ad9f3354", "7113b80a2fd13692c85f39cf494ba0d30285981b4829caaa92b4b748df134346", "000000000000025e9a743a9023c5edb762b776d61569e374b82accf5a78a95ff"}, +{ "11500", "9d6f0308699be5bed63c54a2518b7a69aa2e7f5076202ec077d3d53159b291e2", "32f1b2236a56fbbfac8b1a72e3e3cfe24531bdb2c38c2619828d11c1474df677", "c3c477b83ffe98338aeea638c538d0ce0f12486695dfed554ba6b7b9c1c68db9"}, +{ "12000", "00000000000000734778db2ce455744e1a50745ff4d10ad3d787e49c9c2913ba", "712f312d18d3c817c33e522dc5b7b50b9a16c0dbac13e56ce817e8b6d7f75ccd", "0000000000000136e3a5599beaaab0b3a4d61e88c79b859be81dcf94ef9c9e7d"}, +{ "12500", "00000000000001209c8fe742d1a45c5fa9689f8622217ace049fa3864ae24321", "0c4bf64e0024dde945ddad558a13bb180d931ed8d6ca79c13112a154db415794", "805c869dc4a5e69debd0ac3b9ed943839f89b4e75ad9e0129e29919656344ff1"}, +{ "13000", "0000000000000064fade9e75fa24d1d1974f5ca69e84e8688ef0a58b9dd2dad2", "b3411ebcf6385fb575beaac292c70d4e79686d832d6138ff3b68cac8fb8e96c4", "00000000000000ff65f8b119f936e985947155cc1dce87a01ca201f5808bbccf"}, +{ "13500", "000000000000012cdd1996be2f29e14c0654b11476e254e4ba4c6829c6887ac6", "054f36fdd7e83ed836fa5c6ca63ee54929fe3549b45da07a1efd1cbfca73188f", "87ac07eb5721f5c903e1f30e1082ece5aa619e403f3267f3a4ce0d061fb258c1"}, +{ "14000", "00000000000000b930521b5956b17943d5dcf001b4d319ba7157bd7fee6a6fa1", "80ed5287e00bf627a20e525cacd1b6ebc2077a3e2c71a400bec64eb7b80046f5", "b11909221a9f3cb0cd4e5edfb6024d1ac49ada7c08a77c0ebdc129b05747fb0b"}, +{ "14500", "225abc3eacd079cc0949cd8d0eb8978b5bb00720da7178ef5652e70754914d88", "c87e7237cadf805554ab3f259bc89eecda51149fdff0ffb29925712a218f76f8", "4daa8b7d1d927bfb346a7314e891a986bd793b17985722bac72223a15869eafb"}, +{ "15000", "000000000000001f08d59b246a225efd70b813c3df8e468bc9d99d7d686fedc6", "2ec038bb14816230448f041cae3a9ab64f4e237a53cdb0416dff8a2e062586b5", "e874af931cde446e73ca568e2d367e777e799a4bba62573373d36ca7c7f00bf0"}, +{ "15500", "1181e59d86d7026c523659c152db3732c69e56a04ead32a0617be36ad3f2f0ad", "a2511b8ee2e0158dc668e0de527e71455b7245c01f41ad66e296118715aa33a5", "000000000000009e8b780ae68208f996543f46c2580ea3bd12fb75d01093498c"}, +{ "16000", "0000000000000015155b08a0f074b1ae3c960bb90e96549a16d0b3eb20a4353a", "05409419f76edb4ecdaba62aa65195063865344c93cfa1e35bd41931201830dd", "b3f2857fbea121637598c8f7460fa13da33cd224af1373cabb2e6b2581ea0983"}, +{ "16500", "91d0e76a759d19aed57d2657cea4dbe861e849b57602a4c5c69028d24f795fb5", "767a41f042292ccf2acdb0b91163b18dd6b59aae25ba60a8557a01f02a5db8d9", "0000000000000078da7ba00aa57c04dd563cb07989d2c329a6913b7736ff9044"}, +{ "17000", "000000000000009f949c3d1a6eb1d50cbe5a3638acc49987902526df0d4c3eee", "dc090785300641d04d64f572fa7d645faa11c4677d74ff356bd8d51f50c0517a", "3074c34dbe4aa0c81eee8b20f475f4adf1f31e0711057caa2394e46f3b0490c5"}, +{ "17500", "00000000000000376f6a1ca86680e16d0127507a1182507e502c6cb85cb6719d", "89dd74d7a8b4f5ee127e7b4aebe54f4cb2c91c79fbc3045a59e5f94227ac6b12", "b128c00df0413a021711fb36ca2fdc1f27a5357ca63ce93ff5d1b40e2683cdf8"}, +{ "18000", "a02b59af01d4fc762d8a5708b22be769b7ef651afa88ecada21eec58dfd53cdd", "42abadc5ef27ee4c954518ed1a1e865a3b2bff3683baad8fb35589f8953ac5e4", "00000000000000a77265a8b139651c098948666521ff2f23b494e78e1dfd384d"}, +{ "18500", "00000000000000dc2e6182da1a35d916b98a4778fc35c50de27a770b9f63daeb", "7a44c2603b3d31b23a607a40cd63f9ce9486a7a3de507bb26f6ad7c1e0e75466", "0000000000000031466bf69a5d20f11e97c1a2f96bd3e77bc632924c589d32cc"}, +{ "19000", "00000000000000017207a368616b26632bf68e16984c098be64d2fb064d3a2dc", "190ef6e670cda631380598333765702648c55bbc0c92d68d3c2bb5f76bc546d6", "6f2c3f758ce2e2ef7fca1fbc0d043164db325f4a886001d369af7feee1acba53"}, +{ "19500", "00000000000000ab3d7e8810b7ca9f8b61f630ec6e596ee105cbeffe80c41d4e", "5bb4af1b5c912873e90a93c0d2c998b367768f05fa8650246bce8dd4e8b5f0a8", "000000000000006f4d9713879fd57d7237f1050507bc3dae8aeaed8debd3bda5"}, +{ "20000", "000000000000003adb97f0d6976b906982f3272ae0d656e1c593406b05bae17c", "fdf85ac01a396b796ee5dfdf3c7869dd3f7eac36a61bc7a30a5c7e8a9c5dea1e", "11afb3010b72d18ea6b84d2a33ef5801110ca44a0f504ce7aedd5f67443b261d"}, +{ "20500", "dabee81d7aeb87b59d94c497ebe1552b3f5a5ee1e366ce64143e9fa426a6462b", "017e99080b6064d5f8852f6cda7563f8bf299dd15370a64ac74f89f22bb42220", "78c46faa3aae5ce7ca25ef0ca634750514f4a06d6c956d39b8cd3be8e68a8ac0"}, +{ "21000", "7b549feae0c08f58c44ece421b89b0626d15547fd1199ff172704a51476e17a3", "50e176972bbd1528d333c01501e05baf97876b8a51030cc3dced40c1bfd852fe", "1892435e8046922f475512ec827d870ee9f4429a0ba4a10a920e44eb7a960443"}, +{ "21500", "4d7df2acdfee2592ee66f6498c2b0de972ca6e0c8e2ab38eb641dfbbce8aca04", "e10aafa5c02a56181cc6ed4b48ddf1a52370d95c99678bcf5fc6a106df343bd2", "3a708e4a34101e701039b240614fcbea2f334a54e0bd1921257ce7a202635349"}, +{ "22000", "1f2cd2094e85ba89286a183da2b9135d94b2be2c5b3f31bafe89ab3f631c5791", "b97f1ff53a6a11d6ad3b0ff270ed2bcf70500069ab5651b8466110d472a1651b", "e29e5a1ddf2f66ddcb413df0582977b27d7f4bb4e66b3a2b0ecb1348c0f54bc3"}, +{ "22500", "e797c4b4ed2720b494a3501a32a247f7acc38f526245ff89c8f148babbbf0cdf", "a5b1353f344534e8a9ef6365be58040355391297cde74c723c6a5465e39f727d", "2602265eb704fb881dc85d8ce28752b8c46e2ce6ddfe6fa9c6303189ee6be09f"}, +{ "23000", "50b9f76effc822c9f1051b1c0ce25bba6112a31d32a055520d84ca0f1fc39b8c", "e12e33c6b273416adbf598ccec93ce0dd6a3fc817c6f8e4753064e9ef78e89a2", "b1790f4379c3fc9ed1b2a9429ee58a7f186ea7fd2b0fad8a784f4f7d2f771e38"}, +{ "23500", "fcf644a9930ec30bb933cc37061a17d0edc29bb16a04ea4bbf8b27444d442415", "d5a23580de1505a7df77130fda147aa774abfa1f16468a55b542f69bb6199019", "f670d4586d3b84f836bb9d6a81dfcae930072b3b4f665a2ce6ec769b2ab4b8a6"}, +{ "24000", "144f4d11b3a867d17560ef3ef04362efc715c89c30082882df0692a214cdbd75", "add23a1feaf6ae651d6d322142bed5998f2d3345fc767082817ca86139d2de71", "231d9a803ad8076ff5c2039720e154723bf6673a00fc6a44841b8ef89e3d4afb"}, +{ "24500", "8d8fa5a290cae00be37053ee99cf2ae70b37b4806b41575a09b7a948545215eb", "ce758bf937c83d93671078985a70493b6bc1ab33e680143c6e93c2c5aa3674b6", "3257b67e00dff0255bd4a03e9d09ea6400096e44320ce0a7f28a4cbfedf47d0f"}, +{ "25000", "b5c67f326ffd5481bdd18f140c03ac34a9d467bee8116c7a559a8777c688ee18", "2e618ba056f201573ae6222928d56fc3321a3b16c32681dcba8c07587ce581b5", "c7cfa101584cfd837d9c3d6d0067f9ebf9ce8857abd0c508e3f1cf7a25c1970e"}, +{ "25500", "80d41cb90ce050cb9db84205aad00db5761a465b000b8b3a74bdf57e7bc272c4", "fa5e727492c4a83fe816724e80c54ef2add090d60c3fdd788c44721b67331726", "5e151a04afa93b9e1c38040bbcde89080e66dbe99409eee73ed21ededd300d54"}, +{ "26000", "de58126ac82bebb58f841f75602b4307ceafa0d9aad7271567ec69d734b3422e", "3931c58b417157cbfa4e990ceb75e8f2aaef945922962b671c17fc9076be9c7c", "31e3b4e3c88d910ea31f6ee7c23d5fa185b43aea4ec9e18fb210882a3804df6f"}, +{ "26500", "857f050c1a4a323b2f9d808bf2da8e11a9d691517cb0189ed2f7f103794bcad1", "a7ea3d0c368fe526c8a1a79c9ce3b5cba52634c324271b3982c70e2ec1698800", "540c63627ad9dc26a6cf2b26a739404e4d07e76fe8e9a2cbcdc8bc18a60f3d23"}, +{ "27000", "43b14fcd1424ed78b3cf03615ba16c8fdb53c414e894a6fe555b5a0221053ca9", "6719c5530a1c6579dc00a6d6bc26c59900d5437d4bef8d03fc47cc018937a52e", "ec17180090117c4560874b64677be3f2dbdaf6840d050887f719a16338d1f755"}, +{ "27500", "503b22cd2997d3ff79a7857530f975798fe48a3b46bad0a38a3f83653beb8d1a", "e013d7f398f337d83d758e6af4eec6ecce14d080ab95f037e8c4354b1e4265b3", "e2bf10a3bf1aa3cd6ab411d8eb2af0d50bbf21c7ca24a4e6c873f4d14ebba287"}, +{ "28000", "85e03383bd64b7cde88467bfd7973ad219d635708a69f925316e958d524c1b2a", "112902560ea7fe15351297834affe49c0a8e768b587d1a8e6574ae89903d8143", "e04c436fc9403ffb3716e49fbfd18cac060350742ad2031e07af778b5dd9f847"}, +{ "28500", "57c1ce655a20e5d4639e934776edbbc5ad099c383b62c7bfc623368a2c3368a0", "c3e03e5754ed76153656787b565a0143d538298277c55ac0ca79e99b0ea134ff", "1742f2919898d186151f39cbe3adc53c7d3bf3377674af4bb27eb3aad00c54f5"}, +{ "29000", "d9963c1d22e68c2492bef7a33f34bb7bda7b326b4256104ac1ef7d6421862c5b", "91dce271c5fcec2b60e9e9a7d1670f191be7f8e76d3d13e75eecbad77dce8173", "ba82a0879da29a77ac7e402693bc183897acde32a327066933e15b108ad28ac9"}, +{ "29500", "43f543efd477664f84ee78bac095d5413449e552ef90204f79bb8463ecbd5e89", "4e93e04161f98d745707c6c7a85bd4b223f124c6dad64aa7080dc612526329f3", "2ff134e1f184f488057bd12cc4482364d1e15da2caf46c65bb924a05b18f1fff"}, +{ "30000", "23da6267be7a1511a4f9892875bd61bc1ae5d1b35063d78a7a448379db07c40d", "760c525285ec0731ff71deed949476248fde392c8bb15f100af786b7d7e60642", "949a3e5c3fa9e4347e193891a994db3d631577fa519243b5c6085ce21a246795"}, +{ "30500", "199d170a784a96d70fd6421057653141b423cb730e577bbe490c4d9d5b31621c", "f836756815de2b187d68e2729bc667522ac6f00379759c5a7815c728d52fdd6b", "ea22c401b1a3717ccf1ccdacf25b41b305d19e1d109a9dcc0e459f7472268464"}, +{ "31000", "a2f6774be3decd68c4fc0d55249a61d73333358b03a5d7f48f19ff53c6eca193", "a72c7c5328570231dfa7e3b7fb68ed42e4b4f9f4e05505ea4526779d279b6045", "a51ea6dddb667211fbf69dc697d9061d05448d3c9be461d18362ae977c8db721"}, +{ "31500", "ead2b784815b474f24a12e57068086c7cd2b59051e4570eb4eff43c00079120a", "cdfb920e73fa2ab6278a84292a23123bc921782c7b9648c137ea3b5d936838a8", "e8b8f3d2f6c037a46a617533bdca57edb609ac7526b7f025caa96b180025f4f7"}, +{ "32000", "51690f90531b33b61489e34c805c7d1235708691163d0b25a9afe161b5bde918", "44ba77a723c883778528e872d4cc6779c6485e4274ceb2ee7c1f219274c74297", "9a85fd835a31d057ade3ba18680d0e79a328b3632fc16a302cd782889f52d193"}, +{ "32500", "b8f881e8f20864ef1db26eccd81bc46ce2b5dff8359ab86cc0b915bd6d1437e9", "f390ac467135ddb1d88617c29db574c34ee51a4a79cf041bf7444c522229f8f5", "c4c06a639a920b8f6b788d9481f45d8dcb2e5284127837cf52edbc5447a22903"}, +{ "33000", "8c8c61289e79ec3e22d294ab824743c29194740fca09ab44d460291599a33186", "24bf35eb0ef662470b75fe38c332729ec8cdfa122a52be3d81a97bb9cad009d5", "01cfa5ba001b9497b25ba9226f0ccb17f24d7e948d384ba9bc993c4362827dc8"}, +{ "33500", "958755e9cf4e957d0471cfbeec0913140759fb3219aa74096c26cba2536579ae", "e88ae01956031b06310eb260b95a76e2e4e9b66d40df56300ecf108cb4579c4f", "095cd89a4e4c95283fa2438c6d031ca1b0422816f67168a499f5bb3320c65ede"}, +{ "34000", "d4effcfa7746bab24f9c3d12bf94680770ecc8405b5b0a17bfd0b33c2f4f475c", "9e5f3f87097c229ec5011c8ce05cc12a81dfd166741ad2762a0f156a8d3b3928", "9398fcc470c7c81ac2160660b5dbbc134e4ac35b60255bfae5e07a4635224000"}, +{ "34500", "7f971e1a0d2e94dd8cd0ccabc451fef38429ddbf2400bd45278fe000210d5f87", "8b08d83e6bebcb12ae7b2b9fc1de91a0566ed33f2c40125d7810e2a97566a28a", "70b251ad75de6ab61987951c3d5cad249ea12e6e820f8d935793739cad30d4bf"}, +{ "35000", "90e4d16dd67369b4b5795571fe0cfe63be8c1796ecf5870cad20798a752d92f2", "619428a018aadf7a144b3981ecf018bfffa7975819a58cfc0e16f9ef0ba274e9", "724316079c231a8a8ac11edaa2652aa127160a355df35b6e8ca40054b29ffc75"}, +{ "35500", "03aad5e354d5019e2cecb5a44c4ab79c7120543370cce9830b1d41590a59706b", "d94a9fa2f0ef62b409348c56bc376733e50fcab89ecd7fe711845f66c03a8409", "a153f111a3d9d4d98d06f1eaa3660efc2ab84bf4d8525e7c41cfd1f1cabbfa22"}, +{ "36000", "5659c47e9c1b006ddb991b7b0163777977d04d70b4b52f4e3b87bc3aae6fba2c", "b1cb79822ef346bdfbcaacb59b7a289bd07b5cc02c8c6f9c9b1c5d27111c892b", "7daa94c5b2e044db9e991868d953c7df2cf48fbe15bb04af59916a6f4a444733"}, +{ "36500", "166c22d2278b5d4960af665a6dcb8c4718ca3c489fb12f6744a60337a6ea4a97", "b55d2820c96584bb049d4f57766a2fb7b21ac2998038d1dad3c39dd553309a5d", "cce95178fe08033f16dd7e6bb1f1a57ff8aaca69441747ac339cbf5c6ada01f4"}, +{ "37000", "0c73b35172fd5a08dad4570ade1ae552008a801be8f2df85e52ae71957cc8bf1", "66fceda7365584ca4e28a192d4716cd0bc61da166e5c6036bd2dad1ba0f034f2", "75bf71b04fee9102f680ac069773adca193420ddf477af36e71dcafd129c46be"}, +{ "37500", "e25729880903dd4f6562deb2c3e076c00d29e08e9c531518b2920b3e747ba6ce", "886750b60b53c72b8d9bd1cf744d74fd3947ea62b878fd186618a46f1ae114af", "21c5623b70151d13d93303599698d825c9fb8080af8c74bb812b086074287297"}, +{ "38000", "fd1aa8f0791fca7ab540a37b8fe5a6a23a84d0bf372ee35d6b12fe540b53f746", "3bb81e40ce808ad93fd0057fe4c8c111478857f8ee143a27383a4d64f7c9cce7", "37daa6c75e80010969a1c65d80c8eced5080cfc70b3bc023e90ae0789f458cad"}, +{ "38500", "73dc7035d76f11e288a04b87036996efbce8dc6233d00a1238f40ccd95a4ddc2", "b8f0d99842fa481e5b0e6011ddd8abed25c9073b259e37ee7bf2f451d4ad2c92", "34ccab36126ddd68197efc40b27eef83462084a914f61953f297b14db3460f8d"}, +{ "39000", "f0e3715e1a7b82521f8d39fb490f261c5b8684008f5b52fbca7e5f7b204ddecb", "2851428725cdcc924d42f907200a50ec708342cc1025ad035dbd7f84c0818340", "290a3f59a71d2af6b93a0c00d93fb1852b1d564d59a4766be690c0c85769ebfd"}, +{ "39500", "16693e3a20a6c2d2d823b7c3020af1a20d555401ab098f94ea8a83b7a2a9af4c", "400ac0ebe9428f526123f90c8bccf69a6835ad322affdfcfda314ea795e1a1b1", "24ceaf357c22d83a9a66ce1da14ae06e18bd1271b5478f3402b64d60d848a613"}, +{ "40000", "fbe5242823fe378d36335366cf45b3309e8fad0df3f9dd542e10eab3b7a296fb", "f73a533f1c917595a88ca8058bcf54b2d8e3c8cf8c46a165c84ef124fb07d15f", "2c4922f36ba63458af37d6ad62138ef67479aec2036f7224b131899b72536045"}, +{ "40500", "448e82eebd5d00a7ed11123f43f8ee955790cab17cfad0fb4f1ba154b20cd1d4", "f6c092a7945bdf4ce8bbb08645a349b208b054925376821f469309fcf46cb4de", "9b365c24bf635d86b8e0506e21683ebb1c6f588c6f3dcbd22b4358dfd2bb9581"}, +{ "41000", "42e29e0fc3e8fb2c517bf4b7d24175f7467980d793bb18d4b1903fec0292d0a0", "b8d88a3f3968b88b98e51232a0304506821c7c83f405515d2acf89a6a39a7048", "1d10fd930aacab4a063e39d302c2f8cc041cc1bd1591dcee998181970c05bf5e"}, +{ "41500", "fce90b09826a8120907462a95aef4b8dd9487efa4b0b2cb7e90a4d6d3d40e4a8", "2a4319200375bf38a272bba432cb62054c4863db024e4a30c5bd20bdd569b939", "fd08240c46d9c5424c44850720b857ac2f3ce88e509476d40eab2291f72cb232"}, +{ "42000", "f0815d389fe88bfbf5c361762efc5bd1264dd9256bf895b8dc6f39128e130154", "b26d951f8be8ab9091f1e6c56a539d1d7a01b50c265ae1c025b698f3edde5b6c", "fc414c310ea4cbcdbe701ee801c384dbf953c002341efb9295760899ec66ef24"}, +{ "42500", "97171a32bd838c19f12586fb03992387b4b4c8d1342a0ddf3397e44b7c9b432a", "04737e3fefb938c73100a32ccea93455aa0a564e41e608a1772ffdd2e0d10033", "514d6f0e769246a01deb8043720d9ebc343a30061dff74b8c2931309ea70a177"}, +{ "43000", "a1ae4df09a7e3f060a6693d9bd75af599a658f501b0a5583442aed2bd0393dff", "b6290ff23b70623802b15c12dfe3e19111ce081bedd2f24a0c6b4ead9d8989ba", "49730c987540a895c5cbdc00a5964f893213269f8086e01764bf83d73674a4d2"}, +{ "43500", "85e2d7b7fda1433ec964d4ea6cb4fa7af661d38f761877bb9b0aa0acead5e437", "8dcd8aa4dd692a271a4e6efe7b8314f2fc5adc4b96bdd932e2ffe76b496f1347", "7bde02816df1ae3710696092c464b82d2d6948ce7268f85b500f2fad7b59bf49"}, +{ "44000", "7526450969b0254a66686dd28d61c10d0bffafd0bbb623d0ac71f6c45048b195", "7c626106e228c853ba6d6c9d63f934e51661ebd7ecaa02d66608bc2f1da0877e", "6ece98559c2f3e6e595e5650230092cf482f3362ce00a0b5a8a598a3df11bb2f"}, +{ "44500", "313c4a7250c92bf888dbbbe977f119854876d877cd7ebad97da3e793e4167084", "e1da8d161f08c6e7cbff74ccfcb80644b571747988ada991c4982625e59d1a0b", "c6511fbcd73f38d607677d10f5ebb270b78bd392b83907c58b4a44e84477b859"}, +{ "45000", "9fde3334234a707dee9c6a2e3ef6069a30c0bb4293555f59ac70ec398c818e94", "987db78e383fd57efd0a1b0b0b8fe38c50dbcd648da9a1eaf5d5f59d0c15235d", "5664ee540251229a71cd2ad5913a8a4e8165fee2ba960a4bf092fb3dd6623856"}, +{ "45500", "30f5524584e0e3016ea738b1984cc7fdbac63956d6a154ac474ff28c873eaf02", "2a6909db1ed2d684bae8cacedac0453a13e37ef1485760b0ef6329228a71bccd", "dfdc3b0ccadc42a812d9777a6023ef1dc9143c81a2b1ffa11e57743b96597da4"}, +{ "46000", "b79943e9ccbd2513710f58b3a5ac822bdcd6f390afc8258ce7fa1ea6822daf2c", "1db10c590ef1fb219c3b98c707fa294e263bf95a4ad26c2c214ebb19d4236297", "7a680be9d04c8bbba564af82f08007abb0e3528c35e5fc3cfab68a69ec47df76"}, +{ "46500", "9680afcbae2cdf4712605c9d592ddaeb87f9e8c522c6b5f0beb219e71de389b8", "75ab5e40232ac575b25c0b892af025d5405aafe1f808551e7bd33abdca9a86cc", "a625bfad95b8b109ac2717201cb5e5988418cd26471771706a797b59fd0be320"}, +{ "47000", "1deba95895fa7fa09760b2b6f12395e6a40dc7ed3b14e629b7d85875e6913eda", "e735fd2aefe57540d02327e774c7069d08a3ec5b35e6ba939b1609d98a29a245", "e955c958f1444bd9c6f6ec1f3c081bc37e2e4f8bc554ae806df4570adddd04b8"}, +{ "47500", "400b71a80cf5c7a408363c4a88a6f17b9fee56830f9639bf682cca7f6a1b9ef4", "179f44d13af45605ea60c9fa6e0030b5de6c274104649283e5929abda3cabd0b", "7e15cf3d27b7fb311eaa8e5be6a16f66df730fcd917206b04944bb7efbc0662b"}, +{ "48000", "b62fdb21ede8c1760346b4325be6d08852ea3944fb0adea0b408742977fe122a", "8ff82f9540381a20ba68681f6e5442df8852cf38b2476d0a6bc61162d6eeabf3", "f9590291e90b1145409aafc4b35b003c3226a54b865299168fdc55ad056e6cae"}, +{ "48500", "baf6f61655d7a53726d313806841300c1d729f7206f62a267c1b4c351b365763", "fde6fd7055e1f6e03b9d327b3c502fc02bac00738ae0fb079f128e2774d0078a", "7bf98929914e719c43f044b8bf5bd0cb23c1dc197682fd0e62e517d426cdc1ac"}, +{ "49000", "854ab5b99aa89fc7d03f0b2d7f8a54aa7c98b23957520ebc8f4e6305902cf2cd", "f39213ce4a4fb7c2de3088ffcef3712113958562638395dcfda8ff6da621a09d", "82dae721c7e522a846a3964961366f428d60788ebe25f8f649ecd605fefcf2c1"}, +{ "49500", "c964b7057db84d6b9282baff7f2f09dd72fff06dec110201904bfc3846923bdc", "51261dc44b1299e50eb364ca4d236b9b5074606928ecc6acae0eec2b6352376d", "39f54442526f11b0c232276a00372762bd2481def4502b9db2413e0ecbe42ed6"}, +{ "50000", "fab7500f5f0b1694a9c65a4b02e84dff228af92fa447d810200a3b14c35242cb", "194fd02a69a66e9293a06d354206757e2bc23484e3e8cd80522ff71feffbdff2", "4da797c00b7fff361aeda31e847b2e8675c4061d1cc87e02a040c7ac34bd198d"}, +{ "50500", "ed4e556f251680672e442c00cf6a48f3a787acc589ef3e83019851808ffd05a5", "b51a4252fdbf12378dae10ac1c94690365e096f786feadb8e75cbad87c8f8a99", "5a366c4316e15730fdc118fa8c910850d3f43ab2534023892dee2c1834c4595c"}, +{ "51000", "2410005ccfce88835da97372f39ba6708e7eb10f97a4428ba2cd51e8ee87f7dc", "64e4a8d5a545ffb1af7a5dc66be6ff2aa517a99c7bc5d7b2d1d1afafc1b93a84", "574faa5def6045f6a923539b36bd27d5f92fc7043c3d6fd783cd3721ac604c4b"}, +{ "51500", "ae13af1cc26f53deaa57482111239bd24f99814dae1e01580a1957f11aa49a63", "4a0c54d391ad8bdc303e226fa1aca24cce0ba24370424396bec9917804f0bce7", "0849cb255103b5a13e30455f5666a79873a4ea09dd8dc06d628f2812d8460133"}, +{ "52000", "163e369cecd2362ecebef4717e206124e3bd47dd40104efcbbc8610fb48dbe46", "3b68edeaf66e8bf1e1b187fc0a5e0424b6cc896661e2a4f44882cb060f9815f9", "8ef8dcd02588600e7235ec512d10ac2753b1d0d9bca850de6479f20f678757a3"}, +{ "52500", "c3e5334bfa7c8d5d577b1a74df2deb553a006f68b384ebd44eb7bdd7aca3a297", "fa5cd9249e7b39e2aef8bb19e83e214d77a45b4c67c4504522f94baeec2241f1", "c3208eed6877bb901a5c104dc7f6829e8f21d26381f04dc9913cae3354b52cca"}, +{ "53000", "3a790689d0f51fe7dd6115b7f0e5f5265a3aeb912692596d2611050a17795705", "23b602a52f2e393f2cedd9c8ea0597931f6abd7b4f4f1d85f1de8d6382c03ec4", "22e3b57a04499e2821002a0e4bc9e81bd4f49b0455ff1a369a84317b53de5e8e"}, +{ "53500", "70a1da282b26b9dffe0b36a6dcdfc0c4bf218a86164adfbe7df4cc9c0b978969", "f6ffbf0fc14817b41ce42831d14add2f8ec22307e5b6baaa9f07dad06c387e8c", "61244a97e0cea7e9f539d0b93a6f2b17be206a6191da6b96c6c8bab82bfc48f7"}, +{ "54000", "630d02d2f2a8889fe47a4c2235a60b2dfd31ca78e487860f59d24637a2032af3", "901287c9cb47c082b5329f422d94e71def436bd0979e939e7def8c60f99272bd", "c17de5403465843f5fc7e06ea68b3d45632391503ba6c3e08fef7e307efee627"}, +{ "54500", "4943f865d3e75ddd060f8145558ec7f57c10d186b3bbd3d90377be4713e1fd22", "26a8c618d328579faee0816d1d723736a249dda1e95647ce7775b0aae5b72854", "c55e2330f03cc18e461c27c80393abb8cb22e02809d2381e58ad9f72e44a576c"}, +{ "55000", "6e96c77b0964fc2077455aaa2067110351212e2ca707fda778c963fbbddc844c", "350612a0426a630a0b001ec51d875e2d1c87d20353a480539e5fddf91cb3097c", "818a9301476f02887da2af0daf9e7d06ad8b2129957706547ec766937cfa844e"}, +{ "55500", "cd718716c94cebd61eafac70f8562db8b48735765a8613aec79d901e0c5a05e6", "234209073d425564622dfa5268e7f2af5aac71a18e2b15d23ceff1da4d876563", "aba44d2b14d211b90829dffcdcbcbbd7705056e49f671290cd160a0b778787b3"}, +{ "56000", "04002106ca4da32c5c7889c8f17369d23a35bce62a8196477c8f8e0e0dbe4efc", "ac25f2042536f1a588ac6747b2ff3b45de9aed063b096ea59632b3aa45441ddd", "5ff02cd837efbf14a19c5a187db83c5406947178bbcaedcc4d1ca99aaf9e3796"}, +{ "56500", "6460fc580380db980f3b76e9480b2dd98f4fec5c9642b211f7258f50575522c3", "12c289cc82037f732305d895742cb703eaa35a4656faf84c6f7dd9a2783cd2a9", "ddfb3a3ff60a67bc60f19d00f0c63f1e97ef355c74ed1d85fbe4d5b1b214ed1f"}, +{ "57000", "7f1a59ac62a06df2d3d82226e03a1081fa9a8c72c5333ba485565f9215423362", "5363e6896a5eac3c62543b82b6260a18b07597b5963d038e728a9508ab55b181", "f0e932ed8ab5fc1e33872aba4976166e13b6d879d15dc3c87be2080ac8914b32"}, +{ "57500", "88bf14d568f5b9d8e88d27a92f2aa97a569f371850be3d6d1ec175fd9e1dee54", "56aa31dfeccbed31839cc2399397a826f2e64a16c4fd309ba87ebb2ae7e7f695", "015c08dd60a5eabf977e86e7e037c946299fb6cfea812374dad62fc8f8dc198a"}, +{ "58000", "0ab0e582e675d0ead1173cd65e71157f13841b22560251a2aace14ca86fd66f2", "bb20d53b616962e78610b02a60785252e90c54d78f33a3578172cde77075a776", "9baf4ea45dbf06d4508012d7b02fbfc4b56beadac64d579d65e86b2fdbfd9093"}, +{ "58500", "637d24d3f5e56f5481735d0853d74cc85c170dc95dba4eb733af11ec3ff048d4", "aa8d5505be6a30af2a0292fcd19800b0744acd87634bc49ce43b0d767117a5cb", "1f591f7deba103f980059330ab5579257932772930da3bd5cb92c4ed3a2e3d32"}, +{ "59000", "2d88b4676741afa7b183502fffd15bb1580f81b4b8631844be86bacaeec0524b", "fe841a70acbed4f52a83b35cf30c0cd5ad38b36b21b24da1a0ead110f5e7b2fa", "40171cabf3a46be3a3987f71fa7a969987191d9f53316919c098a4718923c4e6"}, +{ "59500", "e5b98e82ea2968293969b1da31bbb8e30dec3ab5cf10308d4a979e3264513bff", "17429be3ddc868c9e3662b5aa6223340d57b7284138db428c725c8fe69e1f89d", "4a351a969f3b5658c5ed9d91bd474827765b53b8346b4832d1dcbfb2f5a1be4c"}, +{ "60000", "98764fcdc2a2f8a740a4a1c891ad966b44062f64195effad2ba0aa4bb9c4370b", "55053a4d083f019f602ca159faef86ddf421c4c4c3bcef9f0849f45e1f8c1c44", "cbe42ad4b0adeab094db6fd8374b6e3d6696664f583a8720ce1bb15650cb9647"}, +{ "60500", "24bdb847b0ae121363eb0d2a7ab69d672627b4d68195fee18df5ab5c076ba3ed", "be197241a0c377fa6982b5c24af043034024f889cd3ebe42d4a9b3fa5dd18953", "a2955e0abc57b88a148cb41f22fded072fd04da5197fd62677951cf86b73d9cd"}, +{ "61000", "54222686316d912f144e6d0bbaee1b3fa50549e9da65ffc21b04c5beb3ec6daf", "6c5a388a8dd7f9d104377e1f5b2817b50f9269145da48dd0d71f48e2af8b8731", "b8a43a400ee3bab44c6d5340395f0e1f92d394d577fbfb58ed7bbccd2cffc10f"}, +{ "61500", "f14bee1d7d3830f8c316f448ca36fd0591371a63fb9d04596c657051ab4c2ff8", "86c9232b738073c671adec011771072c92ed0616c361bcb6e9af6074d09bd6ff", "54fe8b0e5998f386356388ef8bb5454e1c2526ebcfae9b677e08f208f678be56"}, +{ "62000", "5903eccbe3d0442fabf30748705e88e9cd83128a0bbfbef66841f590b5011bdc", "4de78ca5e16fc438337a8d5f7aefd2cbbc66790d019a1bbc5de082a79e39c303", "8a85e0a258f4cb99dc4f83cc28a30721618cd33fab70ebae4695c5c097debcfd"}, +{ "62500", "35db59c0b059705518e07b3beab25716c9fa347a1fdf7bfa0089d011e2586419", "961e208bd356ecb07f838ec1d1cba0eddd79d5e026ae350f0945cc321dec970c", "4a38f7b73e53602754a6dfa97d9ae5d289f190c3cad7748f7879821d204177e3"}, +{ "63000", "5fb6db58962ea9eabcc50dde4f473a0adf58eb9a409665d57cea3b2d3d2f44ea", "b673d848fb79ad142be92514c27dad64fbf98d26e1e4f5957376bcb2f8542288", "9056ec83e8dcee1f4fba1482124215868e1fe542699560acb750083a63f77259"}, +{ "63500", "92e31a33e15bb677aed01f2ed669a2700223a34fa7342270275561ed5b88eac7", "7932d5bdbb9c2fd7f172a79a9e93f73aa3703c284afa98e7530ea4ebbb4ce7fa", "471d2a03dbf58e74f50681d6dfcaa42b2fe579c9669b40fc7f0c608d99744e5f"}, +{ "64000", "065c7297e545fd1739d04c6ed41da4a82a24404c7b3573bbacca0c266c4cb716", "912632c93e91f5f539b2f9d6ff8b16a1817c8eca88b6d579dab56bf4d48eb31f", "45cf6e550b32597e97193b7904c3c8c4fd709fb9fbbf00bcb178393d4b0071bc"}, +{ "64500", "a011434ee029b50acdd49262a91b0767a897a5dfa7f5c22dda0a32aca9ff334a", "37993dc2223b292109f02e9eda7db4178f6602aae957b80eee7cf94dfdcbf020", "30367b1daa375bc234f8ac0495facba100246d643e308ce11351a9d090e23791"}, +{ "65000", "5144e900145e481fb1e569b1b522143348a38052d35452dc7d97e2140b812e26", "217530b550c589b0de7d145fc8b1059215bf5c124be7e79b5854acc200b511a0", "26ba9b125f161c2d53ab6665f343e060134303e77dba1cbf22a9822a59cc4b87"}, +{ "65500", "6db49e04b2c1ed108caba28d4de98628fc786f5224b098de1636a697ddbd6e6c", "5cc92190d39119982836cd5b0759902c4c61517aebaba16e6515cfca53bbcba2", "0278b2431cb9eb97bc1b003994e371f9bde5a602452443a91791f1ebca9406b4"}, +{ "66000", "559d2603be7835ec386467221e23836803606f7fcd7068f6a42ac5054e48fe88", "68c9698e2684c3375d6b4d83b33155e15ff1d50aaa0fe61276a854f7c022e3c5", "13bb29b335c2c7d96c2c1ed7a7c797065c1d9ddbbddf5ca63836c903b799f23b"}, +{ "66500", "d724f78b706b6a58400a729586b050fcbe843a3e632376f24db6fd4cb9a44177", "968a75dc8e7e9128b5e7e00b22a78fb53553102b54247bf644247546a9db85e3", "10ccec92a6edea5d410279734abd7910dc5ac0c1e15ddf157d814cfc6d6777bc"}, +{ "67000", "8ddfa37cf395f7b4b8d6d09e29cb7f11e7d06f929d7ce7a77ced27c79011235b", "9cba1d323704f1b566fe4b639737ca2f6f96ab6f9f1373d95e1d8cfef0a0a1fd", "58670ec690d41bc890ae2b8238cd529068dd4a26d72cd3c953fe6c503b7b601a"}, +{ "67500", "2c5e2421936073eb47199fb03dc0023bf42572f507f484fd9181eb1a862e8972", "4928ddef10d983dccfdbcce08743afe2a0d1238fd84bb4b6e1781ca7847d6ff7", "80c4fa7ce15230b8e68ba5d72eaa7960d34f8045407ece0d3b1c4b31eed2c00d"}, +{ "68000", "cf49fb97e127593bcf3591390401803095f71ea86922369e573b1c6bf59ca692", "accdaba238ebdebdf85fcb74a46d17e5c29a996e3f1be6147a3f6027a13c8412", "0e50686f415f26137166d657c217b547dd943539dad26b19bbf746af7df6d8c3"}, +{ "68500", "eb68bd36c8212efaa20bcc2d1c17f17af6ce65b060ca7ef80dec2f44052defcf", "e04d8a45c474fb6ab8071cadd8fb14f5d208472089f6a22ff5c04904f7a01d55", "14da49cacd179812640740b70aabbf5b3518447f669024e44e0d3c49fff50e1a"}, +{ "69000", "03609399659eacd9b55c608e6f35195530a35358812bed13782f9d5df5da1ebe", "cf4d7449a4a7aebba820fc84f3dca2a48ada14feda094a425833d4a5aec834aa", "41ec9e81ab7bc3532110cdbdc77b8b8e7827f0302b2e53439d1e079fb6a6e63d"}, +{ "69500", "1d23b15a2484a71d270170f32918f36fb87e80cf4020f6a3e6d61907276fb3a5", "2a218f285edae9995b3334352864684c66f4a919c92031ee3b24510b568f6246", "16ebeab13ce1ce77819913c4c6866628c4541e3548f242a90f2d034fa0cba0b6"}, +{ "70000", "5667dd2604c90cb15f49a75456b0bcc2a0098bc025592d48379f4360844b79c5", "1b6966e82886048d64879d2b76663fd70689c7dee808cb42352f57af598f9bca", "40226bcffdf6f4ca816a09f4f8b19ab1fb245b506648ef481dbaa9f0f3c78a92"}, +{ "70500", "745715d010b5ab51456342b8772a53b95ef0cd409980df39c443531f2f6c2346", "a1ca05cd11e6f3d9eb2f0498b8a4743defe546c7602c3fe06642f0226cd22719", "2d34067c353b61a32c8c6231f77f6d50c4d95598cd3101532a3a02e80cda7113"}, +{ "71000", "c622f3d2de9a6aa2d649f10532164082ff6ac21da796b037f2b2a210fd2910ad", "3c24535ccd8328940b86980f1797d0c4e0dd0fed2ada72a0d9ce7927f4e3b040", "0fcc88b5927ded864afc1ce561cb814d9e26a21b053ff81e7201cb06432b6472"}, +{ "71500", "c4350561b063c19326afb0b38b7aa70a65a928ecbe3a545f26f1dfba40d16599", "7167266f09bc1b259fc6dc6ddd1c4e03514e4b4e5a985ce79cc320d80f376e9b", "f6e1408b9924b633079efcbf87a6d58ada9b92de902e1cf06dfde2aedebcdf8d"}, +{ "72000", "df857691f4e2d2ad6a7de6a3fd77cd3e1ee19be220f7f92006e30c4cab62eb8a", "1e962f15a4472d511bc049be123041f357376d95df56677c32ebf69640fa5459", "6238d0f58374c120051c6df5ad197884fe673daa41fb9744ad261e3b102be59c"}, +{ "72500", "affa0299a9d64d61176179cb14978c6dfd116b0350638b5e2633c5a73bb9e5ba", "b04e559b1ff6d04f2fdd2693c384bc89f05ee28f5ba8cee49cd057c575b0acf4", "a19593b0eb1c2af96cc2b8d2a51d1dfc01e8f3199fd034a3166d5f2b3744b06e"}, +{ "73000", "a50964b3523aaffcbcfd0be0a6fda32ceb87018450ad2ff81f1ba61de5fa20b7", "e3301d1249deb8b1065c59ddf02c4480af9208ca0fe70f0b94f7135e3baed857", "925258df26bd35c53566a703ddcebcd0736a83c02febadce41775c6a749e1ccc"}, +{ "73500", "629acc1dd038725bbad7598fc49a7178771332ca4f12372248da579ee5dbbe54", "8d2425646be01e20cf3554feec43cb91bdd92f0a6e8791c7f8fac4d21767b45e", "0cdd774880e4510e46ac772c74a1d7e9489ec661e385ab2a30c54d302073b69d"}, +{ "74000", "068954a253aa54239a0a4169f50ee7d37b0b5bdfcdfe9719ce9921a5917715eb", "722bb617216427a0cbbaa037d1234bb7d6765707108aaf171cbe14e24392a8d0", "a1d78d4187cf5554867bbcc68949c2998037c4be0a7cb3f3b0e3c4115089cf51"}, +{ "74500", "e688640c22b3c55fdd29e86a159e1cb665cb0937cd6a5591730a1b5de7c04b76", "4ed22bf35c9c19ccb01db47714af7f2ed0a7d2506f40a5e43b92b971edf62250", "9cf4fe5d63466b2a310c28107621a4e2ab34eddbd8593bb426f334b2bf9942be"}, +{ "75000", "31c015b503c6830b93948a51598beefedc78d8957af82aca6ccedb2aa592de8c", "b75f99a073680d704089e1a77cca65d027722aee3a4fd7c1f9578b535150d5e6", "b3081220431a4246895b22aad5fb257d09fd2ae1cdbd57aff483adf909a5495b"}, +{ "75500", "3eb906d2939c3f6ad815a51421f488025326b8cbdbe28c15ef32ba410b7b8ab4", "39ed4ea10fdb97d192dc03a86a397b24f6883439e7ff6e82d9e6738cb90ed5d0", "112ca7210993aa0fc5581f7819420bfd74dfa5b7b9e2a1bf3e0d2fb5708e28c7"}, +{ "76000", "d21f08b186c4d763e03ff71b1ae4e7c07a9dbd30c518242740c2c93119d8d96d", "3898b748f911a413cf66daf2e319b3e72ad25ceddb77f56a7de9165484405cd1", "c3a319de284ca1cf8fe3b8ef075d1ec77f9305f52c9651610d383993213a5dc2"}, +{ "76500", "5c8f54cbdc2f5f83621da3e57c28d8e19faca81a438cb5f4aa144a4c037a0055", "979a3726654c4e3bc195da85f13e24639650c2d65c460c91ff1b377e27a3b73e", "520b9b2d18e11c3aae19fdedfd75036c9035e115b287396dcd53f45fe063f812"}, +{ "77000", "e5e2e50e27fe46845384682b593999c03b4848a5912bb45d22974cccb551d125", "75be98b3706894389661b6e9c20057b55cdabfa26ffd74bcaac8fc01ba273340", "560695b5286f2a9b5f3a61891adbd806476ba326c9901d89a4144d25730382e3"}, +{ "77500", "be8371eaee6d9fbf2c550f71e9b41d135201b8b4657b94e6660c908f239f986c", "32b8f8fdb525510204119ba84666c0713d8f486328a98a130c166f36a2582523", "20cece5da3a52ed79ca9da8dfc49906e29abb2fd13277d8131ff41ed5116409f"}, +{ "78000", "2eff5feda9ab021f5afc380a7f931e7d52e7fe2ff3e2cf1ee7fdbde0eef82b64", "65fbc737d459fa4f14f34704e11ecd9adfd51078f45626671bc698ae18d849d6", "2864e1e45f74b90f0c7d05c88b86c31c0f6534a8a349f626fec3a58508814b1a"}, +{ "78500", "3018bc8d8b545e9ec88e936af13fee6bdf3ede83f61d2bab5f723803e53e0062", "7b2380f5e4d64db1aefd218b868cc51902a54d0a0db42cefed99c7e8de87a218", "92a0304a2442f4c9695f01d26aa2e8b5d34146c9b8a858c53de43d87e466b863"}, +{ "79000", "b0c165f1302d8f19256dc2e278a7a5ecb99eac7c998306a50c8b4686a077356d", "491242e8fb5fc40eb435f931bd11bc42428634a5b83abd1fb9f19059712b1ec5", "53e79c824e8c366f63f1d49a454053093c4572423c9c81f23b369cc9381feca4"}, +{ "79500", "68a1ec922af3091b3f2d59824979ab0f53a92198465ba557236cd41723deffb8", "fb4a299d949b55ea78834906a69ab9022a49d8de653310369fd8ba9af477b7ce", "b2e281683255d479875753fa7e28a8d4d18ff9e2a88efa3096ab74ef053c0a7f"}, +{ "80000", "3b7489d3c34d0848f031a2325269daeacd8d00cca588b2b0155a81bf5bead1a2", "9ec13567c8ceb32e9315afa4321f0a088d662f7853d492e8fea9aa0825f0c8ba", "2df863950a969a02053217306182378d8cf92e7d0d20261970edf99ef4f81e3e"}, +{ "80500", "a4bdbb1067263df39ae9c3fe98b7e436bfc29fb020ca4e0caedc4b92409cbabf", "5d94d51295cffe3419841c9aa1afe3a281863f571789ded22dbee32e03726946", "b28f04015449472163c3a2de60bc86a748344fc019737e96005a72b9cab30e54"}, +{ "81000", "ff01efad3f1d35001246db4167727135f57b0e2603185bd8f43310d2725b4da5", "41766254f9700bf8590b6bfa6993eb56e866af75377438b7b7ec4aecff1062e0", "4ca72d6d1f8416c9c1d62c0adacc2fa865386e2403c611151aa04a860aaed815"}, +{ "81500", "1e6d76e93daa7db4bef0b866414eb884b80193359343f7984cc4ad813f10a555", "87b53a2233125cc8b28fa7fce0ed9d4030665fe83b9e63a76e545f7eaf332fd9", "7020d3fb137061b452f9946ff2dc143ba7388863becce1b384a50481c63d75e7"}, +{ "82000", "f77522692699eaa7adfa876193ff59d445443d55389e9110c211d4892d0e4501", "a283d883a0705d2dba7c61cb45d6019a7e464aaaf297d8cb28103358c12e33db", "384ed0155684b2265e88923aa42ea92fef934e279d5c620be94078868d6bf789"}, +{ "82500", "ce6f78297eeeaaae876c2528e2620ee91005af068e45c079f16523772b1ad1ab", "f52cb36181b62da6142382debe8325153fa672ea2a82ae0f4f1f05d3945ab944", "57560eca2d832e2ab12c003beeefcc53a73d9af27c28c8af087ccc786ad1bbe3"}, +{ "83000", "fb926dce75fe0237ca38f35e58a77ce4ee8be04da61b16f360b029ccb889ff75", "28adc102bd9b8be9013e2400e65d2d57750e995bce1b03ecdf1cee59712f359a", "65ea426980d984b17394705620f3b309b68fc832a60b8ab81263ac84269fd795"}, +{ "83500", "f41912c2e881115560d9b957f91a8463c082efd4b887d3a9762fa7aa70d7dac0", "aca22527fa30f5d0e0a8f2505a12fad648526bf7c7a0012b2ea02ecdf55b6fa2", "28c9c97c6416a1a1566abf837b74612f3345849f6e0d20af3658eedb30c246c6"}, +{ "84000", "04c39ca3103cde71f02315b339936f58cb04aafe9990c46326733493897f848e", "cacfdbf9b2ae2aeee8bfc355d807badb9cc02835889a999e93c14ea7800d54c5", "a8a1f5a1cc75741b3597b9371c208013cd2e8d98b11a2895ef40954a8ff9495e"}, +{ "84500", "5f40a8c35de9dd97ecd7244e84a895deb4fffaeadc22ed8d206d303578471ad8", "e1c2dc0617f6e76b2ab84179c8bbc55c46d9732c6952beabec2d14babd7fd9c0", "f6a927e6e9c0f51c6819da1dbf55beab055f96c3732b6afcf60d603e7a96f232"}, +{ "85000", "b181b9521ee2b12c19c5db467c39855af3e1f636a4086e1c6a728e2b45165402", "8243d308e207fc44be4180ad0a63916aef3877e6278d30cb6f795d463541d26a", "c0abd81ab72aa7762ddfb2d2476324f5237705d8dd97542242dcb8c3e4752bcc"}, +{ "85500", "b010687cf83e100f2d398b3927659ca342b25e443147badc9be5f13331fde93c", "c635b1e609f40f3bbd4aaee0df1ea6b27f18094f1d00377f69430b6507012e88", "c47c926b3d18f1f2853fd5fd99e80c0cb9075b6fb333cefa64a0b8e6fee346d3"}, +{ "86000", "291fee34f060bf3d1c39be96f5ee8cf18c625515947c5495775924f5702abfad", "47e1684b5b4942e0719228e060af33e8f13389619e91925d58f86408ea149035", "b050f83dff11fb334541f21aa3f8248e3e88b055d4017babd998ad01ddb57415"}, +{ "86500", "bdaeabf298427c06e09a2e646e10ca3d17056bf1ba9619371327ccdb3f72c09a", "4eda2aae345266db3c1d7f8e49699c30e70c8675735a83972d0dbf0db2372c24", "2bc18aaed2b179c27204b8846637ff5917663850fd453ff16ff09f891d0f59b5"}, +{ "87000", "8f8fbadad337ea15f63bc845e472d58d4c6467a516d77d08fd603ddb3b98d823", "2d021df329f3c3bd4a39a5ecbae773b063f4baaf776f8ffb519b0fd4d803373b", "d6c50b050c32e92b6a9b462aec1fbc4ec26ac4d9ec9d1b26e84b495d66bf060b"}, +{ "87500", "109c6f62e3aa5e0ade745ab3544f8d055d4ee1bf27d217bcaa0815f8b31118f1", "1cf68acbbe94735132fe7929ae72e1fced6fc8cf569bfbc088a16c93c3e9e403", "b3b55622d8f81f35eaefd008e01a33e2a78697ee655c93d24866f618836ac65c"}, +{ "88000", "f46e00026587a254cd7a382218d9f2d61d37139d7c3c4f0ad76d35c76a2e8fd3", "fc2e809bba17e3198bb92edc5999820f19a4d7135330b2f7b055252ab91f4896", "6e1a58ff143797a81cadf49051e123bb3851028bf1a5ad1e8a41e5abdec89540"}, +{ "88500", "a048c5a363aaf55cee60a2a4286afc8199b7bd0d57d5e039027d3db2a6cfada8", "fcddf7448b220764d0452dacea67e5a91d537830349e307fdd20763143f92bc5", "0f39a201acad8ddb4f46cc03f59ec624d6d427e7c5f1180f09bab87e16cfe8c0"}, +{ "89000", "95e0fcbc78961eb79d44bd8e8055a26e77056036cb235779fe1ce22086a8705e", "3454b0857e99663789646a938c33241ff00e4f7f853870665767bfe04ffce0bd", "fbc9e1b12395084723c96867f18d41ef6e09a29378ae5005f69d47595077252f"}, +{ "89500", "8ed9d4f7f4c3ec8eaaa57d893a9464cafa4e2ea705756bc00c9b9719d51ee56c", "e836a5257dd6be6b167b7cf6c39b17a2433b07e86b2ceecc6886e57cddfa2a94", "39daa73bdfac0f7653179049450cf01387713ae121500d04fbdb0bdab729ac32"}, +{ "90000", "bd2cdc7f05511794992b0ce31ee8d58e428ddf12874905f102d2ca0a37adf8c8", "e182353321678e537290c24a2a9c09d226ecd91044cc139038dd134ec1ef1a73", "68188008335cc99621108f18feb5b958e7a78f40234e29b59af0892011a8c2af"}, +{ "90500", "a996f4865ec304be3972056e4fa5890baaa296db692f4442c5b0b7337e75054d", "98a91f31ee5cfdf960e1fcda3ff3d8d058471e2df6db7bea0e3937dd09baf06d", "89ecbedf84c494096914b7126d5837b8f98ff5594d0670dad7d0df04aaa235de"}, +{ "91000", "f6cb4c4b3fe3b7365cd9e05f757498cef6da8eb0e6730f4c569bcd3700ba1d2a", "91a792fa965f57abd8c8c95a37069682f68a3ad2112883779fd33fddf3cf7368", "94b75f07a61e22e43490bc799ed000ae3b9fffb955f63f2bf456954cd395d051"}, +{ "91500", "4421ef207f0a56fe208ecf3cc145cefe926784dc163500dd5018585c6bc4c0b0", "2870e9bbe0c6ae16f66d6255485d6c6c5c198e16b7a721c0a027df05bcbb46d0", "2c313cd244af86b7c34cf6a6a96a330589509974a5c1066241653a241bdd2c83"}, +{ "92000", "eb18cde79b36e5cfb7047d7ffd72374892d294d97b19965f67c264a42be981c2", "77ce5943ff19145cab30c4b25f762f1e93afbb25e284388f88b4078fb934db67", "d488ce3cee93a883d773acdd624b1686b74074035544625f494a7790f7f62a86"}, +{ "92500", "2a1e0986047c363c557e0719dc464f44cb2a5530f36ead6455caf22579fa728c", "3fc8941af430a2cbbe3a9e51ece9042410bce0c9eec2905109433485e8dc6eb6", "059825226e127fb3df58e84f2b060d82472347a37c67c6aef9a75b5daa5a2e8a"}, +{ "93000", "759bd6b0b243739d3d6c28227f3a9eeca8afc6d341d17da49751065ff6d9027c", "ff40f2c094d151ad356ff66fd39eaed507a78f9d3c4ed2ccde744d600d3ee843", "0ec4bc2e42e2782257d1f79a48365d5af74e82bf3b4829442bee0d3210cd8b2b"}, +{ "93500", "0c1648e1e670c38758befb41e8fc48f337f3b9c2aa8cf162c2856bfd44dfb4e6", "e417032b5b7a38c5a9812822810148a15818047c2e8364ec0766a33cba25ef34", "487bef320afe68cb94ca64269911d08cab750286cb79b06782a0dc27332bf62b"}, +{ "94000", "66cfc1f322a9971bc39ee18125a9464b9f82eef9c314670e51261402e50086d7", "34ddac2e7b943cd760ed4863497ce0ba2a723bad5afb6f391082f1f1603c5a51", "790de15153bcfc0e6ca17c286ac161e548c2361c689cc1e9a725e1140b97877c"}, +{ "94500", "0bf23f1c069fc47b2289bf52f8462229a39ace7afa517a43a52276f5cb8a0f00", "6d333049619b2fa4f612c1a6bc8bf82ab8a7db7cbedb51a258ea1bcc33b03f90", "dc932b2e5268500fe351bfd2759302bd1987faa6c486fd740e2424c8c911a021"}, +{ "95000", "1781fded2a4d5a2ab054b04de3935c97fd5f535f0bd109496aab9abbc6564dba", "18990d4e8be1e75e4e97a92e16bb4fbd805afa2d419629a5eec4d46a269438a1", "3ac8fee137a3e10fe18575baec6a598e3fb2cc7b1771c4044e8e079a3be7a1ba"}, +{ "95500", "ac453fe6cbfc81ed0c9b32241f121410d4caae7ab57c62ef99e08750f2d5f153", "e3c4ea5da181b0fbd82e45e106a9c3dde36c28382093708d8cebbb72d001960c", "3416c602f3620d5c1d3b1dde6b61b75e90bbe01f46ed14e0a73f737a8c20b10c"}, +{ "96000", "e464e4c5f135dcbdbe41de354730b1f633f00f458994d6ab3e7b272a5335e3b0", "093f11b3784b1ef794fb06db18424f84c6a1bea0b9038666ac5eb0d36b18258d", "4cc144ce8742ee482ad9e5e68aa7f51ef8de2bba485c4e7234cee76a87962477"}, +{ "96500", "82345f602aad0d7ff796eaddddda22958f4d3c9c41fb987378947be6ee12f808", "f6bb034032bc77c931558568182e10066932b5326940dfe562048d83dba4c126", "86c5337f6554d22573de1cb49573549633775ad3c236db26fdc53d91575c090b"}, +{ "97000", "eae3af1d8bfe6d1c40c118e0c78bae2bfb1800401d532b63a3c875fd3fc8a24f", "ea34ca2227308ab8818f085e7fefb2f140dfe9479558e6dae8c0dc049e09765d", "145e4ae1acc6cf254a5e21b6b002bc6f1eb0b5f870b80d3fd5215ccc3fcfe059"}, +{ "97500", "60dc3e9f055602d3673ddb11ab25d7c094057a0c71db2a327a491b3be93eb9a4", "186a25fa3609da954813d575a4128ff890d571f0c003f0e6d62a6322279125a1", "097db3da36ec7ac168d59915fd8dac8ad15e6d7e27273536d9d9c5f44255a44f"}, +{ "98000", "5124c9f250499786c2948dcf5e2be2c7c61b446be3972adbc0d65edc8ff87b0b", "7f5892932cd29e78d17fda5c3d15bba0a600f1e9ec2281dbaf0fb1dc67d5e8dc", "102458513889b0fe4946100a0d8d3091f46e7627c09a5b5c08a78f2cef987f25"}, +{ "98500", "6f507567f549b3b1e387f1bf80ec0fef03a9a1af73147dbbbae2134d6d1633c1", "60d73750b6ce4d508dc18cc64adc9e68b6bb7ea4828f09e8fb7419b56eb652dc", "93645d925bd3d878b65cdee59ac3349db5af2325abfd0fc696fa8a2831d33d77"}, +{ "99000", "64999aa405a2a2e5de34a4c3547ee525b503566532d82c35839a9e74a1389ffc", "20052d2448a28485dee72fe536fa8b6ffda1e8465af82491e87980c8f806c8ac", "783113c40eca4f0a067fca5ebfb7bf091561cf6751c3e4ebc3473c8c4c5c6400"}, +{ "99500", "3cd60a841f4913bfaf6183237ebd325b7baee3a5992f092118fa49817240a385", "e21adf8931f3ee5103fc1a3f8a92282e8bafa9fccd203acc2cb24dd0d28b6ca6", "c43bb024c7dd0865bb95082f5864746f7bb41f9c7feca9adfd50856834b50d11"}, +{ "100000", "f0394d3c54a8687b6090333aa03f93f9369846e7c142653524adaa9192b37b7b", "a739c2cc2c59123a161c9b9864a4c834dfd5021066198f51fde3ba9348d195d5", "2045168ef0fde83f218d83274f9bb7204356cee8ee0554bd6824cd9b720d5429"}, +{ "100500", "c5ad61c2da15ed8083a3d3dfd80d226b9977dc831c11e83b75b3ed68d2af0e25", "e3121bb1573ace63889a3fb9305fb95857bda6e889e9a88aa2ad4c76cc407386", "ccd1cfeb131dd0e478ba664886c27238e71ecfac2f3effe52e192ba370e5bb2b"}, +{ "101000", "27c2691b9e3e9cc2008da070c0af12d0997c895fea5c405347496c6a37570f95", "d465e2fcce8e1b4bf7355b4d87445d2557336354b86db40bc924752796aca840", "982d0e97bbd8caa7a1f02b9b2093354bcacbac1d02836a26f15af92f5dd9c7dd"}, +{ "101500", "80c3bf7835d6a11fcaa22931aae51bbc602af4412ee8ec0e8b96c3a9c7128f16", "1d7c3e519be3686c4b9f09708e225c8259c5ba6647fd78653b387539f58bdbdf", "9d7dfc1f142ad98c262face14a901620f92eaefadadaad38516bb5c7adc9eceb"}, +{ "102000", "52bf59cb7e10047df152f35bfb683611f084d444aac4301bd0284d3e458b6022", "7c8226cd17af258fd69631ce4cfdf204dab70dcf93bfed953d6cf488d576f56e", "3c7c8a26ce9a97f67d1428e098c42ed2afa0256e0d5eb226f359e7fd562f2d44"}, +{ "102500", "5dc7c42f2501c79ca5d610b8b69d408033bf0f7d16d036bea01e90e6c1ac9342", "403edaea352b4da33ec3269ccbae23c226a39961f457e5d3f84b806e517074fe", "3b9710ebfe1aae2e249cd9e7ecdbd09fed6b067b5271e391da4ca5092ed8d556"}, +{ "103000", "719c3b85ab62248c015de680a8fba158d0a336492668bc0b202ff9fae1b1b5e4", "d90dede7a044e1b11ae429bd313e841c12e8d0303aa6626db4c953d198b0f531", "acc9eeb7091adb2d2abdd03b650c540ec439b8d74b605dbe0f6d56acc0fdad6d"}, +{ "103500", "fa0bc10bbd112c733022783fa67cc4ba045bf93115654e1f25e680595024ef04", "e55422d2e8d2b8b6429ed85747a8ee57c549651eda0fcb2871ae5762862a86c9", "8010ad6ca7b744c25584f31bd0b389ed6ed204024d2a3d43085480025ca2c8e3"}, +{ "104000", "e63af7f5547bf8bc2f36058a43569a30f7edd8286ce44ea561e63a3bc11ea7d4", "939e2e2c30e66ae3b9077e947acda9b7dc0b9f326c55cef4e4d2e5025a0df9a0", "6a5a080ec382c2a1f1a7f7456bb1847239723fe6a836117b9aaae24d3a979050"}, +{ "104500", "d73f74f43bc0653041db94c60b0e68c194199041c830e4f90345c1dee78b9c23", "d1b14fe1a0631af85d0da1b0376a93ed925248fb2c5bc47d4284832d40fa318b", "f3b6dd22bce5f76f69b412b787be853833ec93c80be63d256745196c8175b628"}, +{ "105000", "460580489a262514f5414c1fdc95ef0d8290a23bdca4af93fd226d72ca79bb11", "11fedbb936fb27e227c2602d32f688f1d024a5fbc8d31823d273818ed142ae62", "79fe072ab0376188eb2502e46fe32dbd4a36151959975c65f907b3c7021e90cf"}, +{ "105500", "a461d00c1217d40b1774f631ce44e78c974be18cdefc160ec33e865b1c7805d5", "24f67d2f822429d89701691d7834c58593be43e7249530a9c1dae9aa12cde4d2", "4c7f21e6d5b6f0b86b0df017852e08e8317a7909f4ef8e9530c064f623e82cc6"}, +{ "106000", "70b95f002b31d55c7b523451d746df1ea1ab182f4e3d26a6a8146daa6b175f70", "f59d284adbc90a549c211187c55814e85b8343c7797ade9c5f761e5b4c5855c8", "15038f05ae2ec71ec3f88554f81aeab060849b24474194e70ebccdb89c802c10"}, +{ "106500", "5bcd8c94849d744d137dac85d734d893dea9963746e1d5adefc0852cc99c3c66", "67b4fb04c0780ac951d84e6779fafa76dae5d46e84ef41cf690cd33392c6f926", "5341b18362d34aa0f314dfb91efcc583fa160723051942c653b9c6621f8dab43"}, +{ "107000", "aa50a7001438cb8eab4442c4635453881df972b8707150275fac0867d7254341", "9e2451f91358f222b3934b24013be83c1fcc78415c12b4fab2cc5dd8a3d3c36a", "79250dadccf089c315b6a9929b1d1d0828fabc87be5424b7bf327faf08eb1b9e"}, +{ "107500", "f83ed835545b9320da20a1b2961c285adf11dcde168619a3e7e746f93cb93cb3", "e27c84ca437850f8aeb0cf3bd1a727caf91808663679f2dfca99f4c676a4cef6", "2c9755d38f916650e6a237d3c0e67534b0ee27dfe7da05c503cc01027e79d72d"}, +{ "108000", "d9cabd49da35be240bfaf8dc107e13fa3ead3029573f7711c51c874f09e2af83", "85f41c365756daf80d25256a132c25ced262eefd77547a42a51603fb98f0fac2", "b793aaab687ad533b67e99d954742be66a9d624e8f030cfdf4e1d7f03310f81f"}, +{ "108500", "e6f6bf4d75295e5dfff4f979fb12292736dfa7d4d8a7dc683f6238a4e00caf0d", "f294a30724f9d9ffcc244995acf528e501f6ffd0840f5ba8ecddbba1d1bbe250", "3e05c579dfaaa081ce6c61c4236685854acfec868568142ce188db8c0fc85407"}, +{ "109000", "154e12021e0e5198def8989a1d68326833d020409a76f980e4e41cb1662e0d47", "2e486aa0080740653141a5219ef25dc79777d3976bd9fad1a7c7bddc2fae858c", "410f3e29b17c1ba1714595fcd8697e13be3216b2747ec16b84523d612aeaae30"}, +{ "109500", "02a8b8fcee9f8a420ad024de30fb8f4b2db683b4f93e37d5a7936728ad1bc1a9", "f9c26724d2d6e8398a66e8ac080c8aadfc5155ce4be3521b3ae5aff95fca7541", "1354ab334c8590c339ff2f674497925320c95dab6d70fd0bd28bce9417e1228a"}, +{ "110000", "587654021f4afef0e863df85d5c48c1da57af439c890cd7c82f57112b523e567", "41299bbc731c54c00252ac8506c5671a019c2f24117534a52a6dc243de19e60c", "f68cdac1bcaf2c5b1d309a18816faf79533d8200b369505e74e88d996b520824"}, +{ "110500", "1b144103a2729d255d2c79223dc4804e9ec38bbd07105eda2eda5d350933c8e0", "47988c8a2b50a19d5c4cfd5c657b3bdb19848828866e762f5fe40f8ed3b0fc5d", "a8de7b91c00f0dccc29a832d4e278a2a788065a3d491e566be37563e0ad932c3"}, +{ "111000", "d2dfeee7017ce245109d6fd20d439a58fba318eb0853369ad740a4c7d8cb3679", "89d0671f5c51cc5e682fde76759bf130bde74a8c3d0334013165cdc74df67a35", "a81b3e0f2b3ccf04a60d59e048fbc01f591da5425bfd9643220ce97b03bca914"}, +{ "111500", "7bad9ae95d958cfdfe5f6f1ab0692c74023e9676aebf77696f0dd92f272484ee", "8711ac67cfc650bcc9a9a3b170896959954dce728667035278b865e843c5f5d2", "a59bc8880cda0f7f950577ffd851a18acb7c750440510209f6f56ab31dfbe591"}, +{ "112000", "aaa6a01ee0e8be04b54950e9fc47308bea161476fd9e5f7d931a9ac7a177c6b1", "cfbf8e1b380186cdd7dff5b1775e68857e0144a6cff5c699cda0df8a9b755879", "f43fe907a5c313040e43adf015a98d0b9c936971c9d85e639e92c180b1196a38"}, +{ "112500", "856c253a4ff511cde2cd1138cc415c15fc4601a9cf20f97a40a3ed5a8e4bd28a", "2418313d86bc12dd0b7ae5246d70c5c95ddc342c5f522d33a4faa38677b1cf74", "3802e55d5625b66deb5cf658a3a498de6dcb6a286ed67ca855799e25e52a8255"}, +{ "113000", "d39c76ff2213efb6aaf21e1831e8dfd86e82851311214222cacd1065e5f442f5", "7027dd65582113bd83834da3b8feb6f5e724156d8653689be02acecf664ed8b5", "60ad7e5a8a6aa36da5c85fdbd95a1fad66955a25ad7bf051c740dca3ecc0d80f"}, +{ "113500", "072de8c792fb777438dae0fe6605d05f84c05c478cf045595236439ed614c869", "66e29b9bcaa1beaa8d901e8227510190b64b665c427147e79fbb03f4c7560df3", "9f43ac28a04dee975b9b3dcbff3ede4eb7040d5dbc8d9fc79bcaa432464017d3"}, +{ "114000", "2727f22d9d9b83d232fb91cf7fef9923d998166a632e104da344aa5b2c33f963", "afb687e99a9ef1e794a049e78417ff2b0a15bf3c0f0a01b5c04e381dfd3eced0", "93fc7bc539d464859ce7d3ea47c7789a64ddee4155ddaf0d7be6891c7aa6939d"}, +{ "114500", "fda2f80a90dd787eb236d38096e1f73b7ee1b54d067c53ee62d4201004df7f96", "434c6e214b4120e3df23c820dfbf7ecf3facaf2f30b55fcce4dc094d0d052ff3", "9aa0f3861ad62b5e80fa6c255adad3b7366b90b2535baac36aa890fede0cd494"}, +{ "115000", "f8642fb7ecc176c23e6919e2a5f9a3f69d60c1bf10329e853b94141d7eecec79", "02a4953482c2887d0dc4d2980de20cf75b73ec8d81d5b3d6ca6df741a3f3fc7c", "41838982adc609b176d3dca2460d01603b07fc794d907a314b7844692e3d2a7c"}, +{ "115500", "96be8c04c6533cf914499dfa780622f64e3362ee67b888c3d187c7cd167c124f", "d160418c73e78f1f75972ff6fce579d50f936678a03b8e3e2e8eec885c8e7f97", "2ac87fa3abaca2b37705ce9fab3334309ab49d40892f1c2e5389164f5f9c7cbc"}, +{ "116000", "6efc2af9311adf3ae7cefcd558b25335048a0344d0fcca48f4a8302e0c2f4e4c", "5bd32d67887dbdc6482620b347a1ad8eb9c8d124ecf4e6966269a1ee537f7562", "b6f3154843cc3d1fa7a91b65008d690c66e21e9d1fa97eddb66442b77a1f06b5"}, +{ "116500", "d2fca2b2bf347959eda9a08e76c269d1e00d475d90ed02ec7d5d537e542c648b", "9476a9957e44fe4de208e4c707f0b6d1a2c0c0b3a32dabd912707ea86823f62f", "2dbdd08eb831f98085b217f3523857d434ae7eb9fc883c163f59ee6e1aa27cc9"}, +{ "117000", "5ac65e76af1b75c9aee7eb49b22ff2fee88a1bda49287fc5dc7762b2c5b8768f", "d357d64072327f9db3d73ea738abdf89f5bd20ed4b56733bc9df37d200b6db39", "a40c37148ebeab7a231c90ad9d5f832f2a50a7fa60c0633098ac7fc58aa74ccb"}, +{ "117500", "3d7e8e1235d8f137cd5661125cc0627dcb3c18945254e9676e21f2a445ab8b9f", "0f9c97626569303b76ebbd2cb960341f2297f69ae140cc84a40a83695993605f", "8755a33fd86f9497f14cf0f47e4729d735bbdbc609068c09712f1fd7146bb2d3"}, +{ "118000", "be2144efc3b4ccf0d4d3d7b66c5f6ba253d1fff069b89a69f8eb2cc4ff44fe34", "9bffc6fa6a4cf35486018721652d5358be0bbeeef8b98398c9373c352cacd4be", "c3efd174ed8698f182b4e7839ee78549e91b42fd05537150c2b9f49e3b75d1cd"}, +{ "118500", "58ca03280dfb1e73dfe8ae35f67b60087586b36823e7fcdfb0509bed23c0f9d3", "58ce09f4189a7f9263ee9292d7cafb880bb3676175c7553a04e25bc261ca21f8", "f1551f00755727e4c81091c294c0fbb99c7f45cfe091334cbb3708b8c3997ff3"}, +{ "119000", "907a0fea05eed4572602c76515bfa03d5cc79da72496d41d84afb4ce4098be07", "32779d699cd1abba0d653a332f07727b9a2094a4149fb66cb11f16df7c68d34f", "4eca044e4c6e854a875f634e37677102a876195019a9ab868506f33850a4bd54"}, +{ "119500", "ee7317e1516104041197ebb0bba085bb14932972d5bf4ce305a3bacb9ce17dbf", "6c779c5b384b94c7649ed90936688e83762407a89643aa89f730c6c399abcade", "b4cb0f26597d60b510022272b256861dc541c5df07d45ba11f81548b6665c98a"}, +{ "120000", "7105703f4cfd592d639e0b5bf6f2d25380a1787346f24331401eeed04f146130", "2a44b6fc864aac66301c1b20def1cafb0704830fb07e2684651513a6f8a89843", "8b843486a87af20a9cc7c7950b9b0406ef462f24d25becbd36433f7c005647b7"}, +{ "120500", "1dc347ca251ff3eda0a459a85d9df212ed27b9e7521bcb8445d5a377e23da48a", "3da9eaf002870bd0bc46688093150e254cbc0171abafafacb2c03f6381a532b1", "58991cbe89cb2e1bcd00dad869d9d93cda1269e4ca917b44d9b92e21ce40a4a2"}, +{ "121000", "7b8f755c93b69f842a1f9ab68f67e597f0fce31b94e0cfed7f3847662dd1a401", "f175a7b245645b0f769638a6ceeec460e87782994586ff8be749cee06da716a4", "96fdb34452cda7bb2904119d24c006fb9b4c44563a0e3be36acdc7c034dcf88b"}, +{ "121500", "2e5aa2e8bd0b018cc58a7d1cfc18d19903cd57882ed5ae8f2d6eedf72efab59c", "daa4a0635304dda991bc047ed1e075a9bfce603bd3bc1dcf93da809f82b0c5de", "cc2f0ced896193b19fe01f8aeb16ddb1256cf7ebf311f30d8dd5ca680313d98b"}, +{ "122000", "9c662917653809b60484673f8f223f3ccc52f9288b8598b6414bef79181de9aa", "c8c62e402da8ff36b5833ba9327dd92a501367be811157fca1f0b80ee49a4ef2", "5df9ed5e6769b16609fae4dcd7b7d3357dc5f496cdb9c02a9a1fab3bc8e4727d"}, +{ "122500", "74a15173b1a78cb7e95f220178205db14c5bb67dcc64f8a1e4feb2cb5b2a6e28", "f480c746a1436fb843e7f5935f2a8eb79007857b4c110a9348d4391302537110", "0ae1ab7f7adbb725c581632172d514e33a82dbc410c709d0d654f1a0d4d7de55"}, +{ "123000", "38b438bda7e108f97112d984725fab27d277a08b1a72affda99b79654c21e0f7", "b1bfac6a48327a4005f79408df343adb7c9cb22d2b70ebf2ad79121cbbfddfde", "605d68df65abb13b0b19301fb134674efae08e35be4b80d00e4124118e2f7a6d"}, +{ "123500", "ec7a4edbed36c3d7a0eb4098e6c6bca397bf08cbc0e0b190a4cfd506df0ac656", "7700c27d9c2e7a0360bfa2426fb3688bc8b3ca935de69d15b6dce9ca6b31a4fd", "df19951e635cc5ed4fc8c1b89b25e72949eec677b0a08b9f4bb1a2d04a00c99a"}, +{ "124000", "c3d8229a44faa337d05e0b5311a5dda37b91babcf95e5a8ccefbe872af0bd2fa", "793481678c778e8653890f1145e178e42effa2ea7f8e50522187ab298ec6b512", "76327e3f2c09f87ca41a12c67941a5caea3779a1c84f0d37a8c6d530d21f626a"}, +{ "124500", "1510db798814caabdc90f2b18282456d1b1be40948ba43fdc68e2da017c2dedd", "df6d64ca6cc492e32e22a218af5a3b802ae452d66ebb018c5d87ccd35489322f", "3f12f0e3189266aba9532c078df96b9f6db6c9f4105057feee13485af445451a"}, +{ "125000", "82460aef9d1133d30707bd416b3afc2929a388ec8d1431e92699aa625a4cc3e9", "8ac7f7dd700d26de62506f88cf117282a7840236bd66aeb148cde751ee3f7dbe", "fdc651d228df5a66e58c4e8566034b13fc7c5b9d6e8ba6e7ad0ed1047e0c3533"}, +{ "125500", "cf883230f6afd44caf802508a9bce39adeae83cfdaea0ca10c5eeb7e6e0f7abd", "269f3d0cfa2df454579a4b7bc758970ffb853aaa7600808071ff130b994adfc8", "cc6f34524eeb81b4d04f506e63828603973ec28f2f6eec8fbcc89178f3bf5f29"}, +{ "126000", "e36d486bbf7eed518a2a1b1668b516daf85bcfb0359337042bb8c278a5826863", "8ebd6563987e0969505718a915e7945f0d26213475be39a4b36ce9928d313935", "c139ca3a3866adb6d80c89c4ffb871c9cedbdbbd8e2cc4e273a3ca2d5897268e"}, +{ "126500", "41b57270dc8a7fdaef0345502f3ad6ecf8012b680714cf7723aea4c7cb03a864", "e422bcde2c4b3e00c42dde121d189205de9acc58be35d92bc590a67fc11b336e", "23277af9201d11f0c7bff9713f093d7d13827e9bf5ce45c95cf8116a02997c7d"}, +{ "127000", "34d5852f2c7ab91f6b7ba43851efe2838a874f1d47e6c41dcf413f263617c4e0", "296613313aa18e97281d6dc14419528e0914d61bf8eb26f4ee08105aa358c0d2", "6bd6797c2eb799e28a79010c8f79ff632d6559417cc253beca15ea6805b98165"}, +{ "127500", "07f471a70c1d559e6fd70d2adf4720987ac72e71d29c4bafd5f78e428aa6dc00", "c32efb7a2072cf74b7124a008939f8093f7028259a69d8c9d175e0bb4910f03a", "4e5c23dbf9a28332f3c9ca25568e9a27e49588ab6d8fe605aad8c40b98f34139"}, +{ "128000", "063c53a0e11590d0f370d0a3c2fdb3722c1c91e0203558436fb43b16b06f572b", "2cf68c71009f221feec16d73d8ec1b729b0624f854851153bf78146935b69148", "4a107a87caf55b16d2951f807ebe93768d406ca00450cfb669b5ed6c2f6ecd68"}, +{ "128500", "32a9b0507313417fdb97dce6e15852a8a55c80690028759b577723b629ec0234", "b2e0756fd80ff838386d84e8d82e2704a52c07e56c10a88fdea969948893b808", "a353283c0cedf81c24102cae0c01d2297e7d965b5c4c4f6a6c1afb2b9dcdfd2e"}, +{ "129000", "b3dc6186f79ecf8e7d4b2937ddc1ff5372684cf818665a730771a932461fa8b6", "6da8856b4177dafa784a25b68c4df9c250a664cc6831c9804403cb021239d03f", "ed6fa11d6ab43cbd6b53ea78bf00a2c664e6d768f376a8b33477df69c50027a5"}, +{ "129500", "1f5e8b0c9c4229ece2580e76e5164e1beb86e165d959cff8d7a0a9f74660505a", "fc76b8f58cf2fcbf3f2821d871788cf4cfac6e52b0fb0476e96769311865d90c", "169723a26b91806d2e4426a01f96d4c506a9004f8c858b5e4c7b1fac5b317ea0"}, +{ "130000", "3052fa9be8c4f5f24f40c5cdf0a8eef8087e08f1d168dde5d1e502960183f137", "8d108e91ab41a1057413efa8794611be06459dc53a8d2099457073ba932acb4c", "59e9715c601fbfda3ce117226d4e2d76e1d1c239e05aa23c2fdefc4761ebe4dd"}, +{ "130500", "73ed2cd1c1fa06e01c3c6fa4848d31b24564e667e3871ee032a1ae04812c4383", "df3d5e20f9ebc94bc84af002cdc9211efbbcabee00cd755653a0cadfe4cf77c3", "fc6c50d51abdb07de66327eadb4b803320de4f58e4254ba732f5eaa17dea8fa3"}, +{ "131000", "f78703a391119a15b5ce6a2a2bebf2988fb164656c968f72359af65852080c1c", "8fca74427f6789147cd1e233e020050d9babd0bd6f078ed53f704c6922b5ce3a", "fbc836afa97af45234ed223da7462c2a74383fd23277fb277731a3e1716ca620"}, +{ "131500", "e8873601a44048b85d11b25b05c225fa970d4ae14a3a30c0072bcf6459f2d828", "140c8f3bdc90be5ca51e7c3179c7b8839afed4458278759a35c4a078ae8cf4e7", "a3dfe4abdf91c14b0273001bbf71ec44f4698f8c6f1f6f30eb522c5c73170086"}, +{ "132000", "98752c54d7a5238387599ac3a0fe44b3ec462f88eb0c3c6414160ce79c128a14", "f82ed570eb9d3c9078ccf41e675c13fcf6e73e6e5bfbc4b6b2c1e4649dbf8a0d", "810b74f9c767aa7c62d699ec3889a615e85243f8cd7710845424677b0a43c5f2"}, +{ "132500", "7377043aca01beda7f7d70c6c2a9f59ecec4769cb330c231abf8439f231a6355", "3a35dacdff298a95ee0fc61728b4711d99c4d1bd4806dc738c684d2632fd48fd", "6bbab9b2642936d0e25f2f0b0e987c3eaa15515a7a70f6a14f00dce3eb63b36c"}, +{ "133000", "0d70e8ae76041c02ab65bdd3b0f6a456288532d5447dab7f7e30123b28e16543", "d6b3a5ad40a90d26a4b218b8b90852d49f508cde1bb2a23031f64e765d519dbe", "2aed7749ae9e8c34545f6aa4b13c2caf55ef2a9c6669c18b2d6a2fc79d89f13f"}, +{ "133500", "37aa235fefa6f62af6e393639361a4109369d0393d66597a3c63736fa5113a02", "9c59c20c57628b250fa5757d8d2d55feec38752453f21232141f82c1be4dea63", "cf42ac7466e89a3c791602ae3f785d709196d4bb20d1f8e19f5e69f30c57f398"}, +{ "134000", "2605e14bfe5b9a39a4d01da070c05d9bce4b6453b599a1f6f95d8a6344138edf", "1b02cbaad0ab46a737dd848c3db0f111c3fdc248d472636765ede6a6c2389b74", "3d4224d4eeafafda11e3261a668a714b7eaf019e8881dd30688dac28a087da93"}, +{ "134500", "12cb93a2b1e5ce4d9c6d2266bc6984839271c92f8ac34205dc621da8033af81b", "6346ab5cc2bca05485ed517f9e494e1e35e33ab9ce011923c6713dd0bc28fe1c", "6e270e7979e87e8a8dd0ede4b24ab6c2188d4f33d9f0f08f6fae0ca6d739824d"}, +{ "135000", "5d475b01fc5b6a22c775b89914c3b148431956df26fff2631111e9ee7d1ea55e", "182dc60ad5a4689e655a00728594807ca659ea3e870a4c71152b220279fda836", "f0ba10f249ef958564d7cd9d31e2b1578e432e7d8c2285931e4d7ca1e740ecd5"}, +{ "135500", "d4b244f6df6c05a1c918ec0c80b4a230c2e40de23847a3c6a48b8706b55191a0", "c0ea29271b681e460441fc515fe8af217459716e9116ebfaf9899531e55b9181", "48b5ebd4690edb79ca74a4560c09d79d8da8647e57690ad8954052b95448904f"}, +{ "136000", "123eb5d144a44b6940cc6194be4ba041c5fd8a5ffb342b5d62d8779605d1fff9", "9836476b408a143b336dab7cfcee4c07ddcbf6939fd40267f8315a7d4d576fd4", "f21dd2c8a381b01a01f3a4b73a70b4712f276e21639d5a63dc5ed5f69a34ceac"}, +{ "136500", "c169555d2b59eaf45046d5c3832203dd5109c6e3018504de66fd99242b41d5ad", "0884992c307a5b98b026f9885b6c81082aaa18a12ddd0b302fc5e358e313c810", "24a2322238cb677fc929fa52ff40fed8ab3712ec28ecc3569b8c8fd588ca3612"}, +{ "137000", "123d022b5482871c55b3638324b5713e225c6e36ab4f83120d883ddf3c0fbbf0", "024aa453462e49f50c55c36736542e4129f56cc81956b74f7c77e90b0e6796cb", "051560bd18e48d8b27f648aa13437285f887559b306b979075173ffe19e34949"}, +{ "137500", "3dbdb568d735e6c47c5fb8f459bc448693566ee30140da275f786fffb244901b", "c0e599ed4901402951a3663d225047e94861817b0a412b01e4c770c9719cfe53", "f998f1da46fec63c0c363b47020fe3f3422b4ebdc9eb514c9a1308982e6d9c5e"}, +{ "138000", "9dcdb63588c3f9d43ce67bb6da88a144e98b3340eed60478d67941bc1f3e48b0", "0c04f84ec720ccb4908774fb474149dc069c8420a53e89e9007dea32d90e380e", "e3e932a8d0a9424dc1ae73f0b7856d83cefd4549a0fa9f0519d11fd9b3c94a4d"}, +{ "138500", "918f3566304f92ee937b50939e5224bcefce1b61503b8cf5c75cddd293115037", "345d16e0d5aa525aeef890c1cd118edb3d1e6bf784e9445aad720dadc3408667", "57234942c9ecd8d449dcf6237a637bdd009829bd7227f0d0aa4fa1bad549103c"}, +{ "139000", "5a5cd26abe8d7b66b82dc847fe582d00c1aedf51bb747cda126f35d177df3780", "b11a4c12939538a057f35a15f561da8ad09ce4ec33a1b6b965e6c35d7f6da935", "d94865465650a0f5f1ded1d43c0fd0afea436f29e999560aa1ee0b07a5355f73"}, +{ "139500", "883ccc866e98513c10d46ce62ffc4b2f52914f9d3c77835ea88b2d772647098b", "ae7d18414cffeb5073a788005a70e1e80b3c04abc1726101177509d0872ef2a7", "e0d75910529fdb92ebe2279551b7f6614ce56217e14ebcdedf57451f35025b2c"}, +{ "140000", "0d53fc7a730aab5b7751832647af30f6ae6de5f66a26aec228c9642132460c09", "d157b0bf7301f4c28143ea0266a95c92a05a3499dac2ab929d57ab75b2be499f", "a6b6f4f34cb06f19a0cefcba963982cfc4d0200074371e0cad65e14a3655b809"}, +{ "140500", "b67b7cad6c800acd1fa41cad0e075a544368d679d03d620f5cee45cd966b61ee", "eec57bbe03beb832a99ab0bc6b77817e6bc459e365367b09fbcb905f3edfa85e", "2bd388afddafe559e744b0b3b07e6586edb24a1909e71bfd6153340b1d7dfb73"}, +{ "141000", "68756fe78e60cc7191d62c387eeccd0030ea6a67d4b1fb6667c068c5dbe20d53", "113007738fdc702b03dc17993f916d40e24e88d12a95726aef18156355990d7a", "695cca03b85013042bcce092fdeb39222498a6743031a96b0fc8af3dabbbce61"}, +{ "141500", "12aa3f916704a9120c99c22977c22b16bfb670c9e9d2807e0cadc444c9e8d02b", "e7dc3dcc436c770ba20dcbc3f4f762b7ab343fdb180e867b3f3db34f8b279871", "4baa32ead38ae032e115655d55a31d08647c588a3362e4f6b85f8d6b8ac99b7c"}, +{ "142000", "629495f161c45d033130f52a4df5e06cf5f705842039b89c3d499aa658ce5a6d", "865d4be2b339178a44d8d9ac4a53abc6b4f710b723583053f23b73c0dabd77b0", "25265bb92b7c7e669482e1ed6e8c41c2d60b169c5707d5bb15a33f959ee769bd"}, +{ "142500", "941a5dbf034317971407a4743fe1c5cf11ae87be184fe4e7749e2d32632deed5", "d8d4c2edb8362a39b9ef8b2693e1b4ed597a9b315e60e424e26797ac5266f353", "57a4154baa1de288b989de2dcf06d8a1f3b50af5bbf5a9a085f72921841ec59d"}, +{ "143000", "b8ac8abfe7b81372299d2a8be307e13786a5aeb4c3a671c8ae45d32f4bba9281", "8d7e1ac28129b56b0ee93dc931e54293f181d3aa253e844d1807d47b31193f56", "fc792c95df1f7a222dde5d47286fdefc2d7060f02db26b03708cf7642e445dd9"}, +{ "143500", "610bc499b94eb7e00d1aae8388937087aa421bfa9cfa70baf798b8f97e1b23d6", "e990d00ff71509c232b43bde64c749bb1fe597e52e40116893e02937c7943b1d", "09acf59e7f882faa32db3b0025aaa3c1a632ca14618e84530c665f82542d2657"}, +{ "144000", "58ab7580eef5d40c0ec3d7ac52425ad5afcbccac834192fe71ec5a1d15cd4ed7", "d9194f449db3d58a1784cdda50ca32d4212d43a12e85c6ad9f8b77687ca04a6f", "7ea883e770b9067c08ed807f0004fd96d3d35584781cf20d74a8269c34c03b70"}, +{ "144500", "9a49c8d5f6b072b617ff80d4b70116bf3db461f9fdf283009cd9e9b2c2df0925", "a2921c9b5ac78ceb49666c487d217ec303b1f5347d6902baca9b8e3779774c5f", "a48ddf29d2ff688201025318bc0362f95f7f4e7fbd7265a8eb95acce19088759"}, +{ "145000", "29f1fe68b8289b62a4eaabaec5abe811c61b6f2220dd15f04bf3d2ed3f98ba02", "8d3672fa9d6c4767e8d3819f09a9bfdeb98a6f35b83f01faf1f7b85c6871118a", "4b5eb44ce00f52df4406aebcac1f42a9b2e79685ae8ddb3c0125dc14a73cea0a"}, +{ "145500", "677d2c090d3beb31d1e611e42801e75fd3e2004e10ba8ef1cbbad5e2b17eb02d", "93a4cedb34458ef8b90ee740a6b19364f5ba6c0096a16142929987d2386358f6", "8b422f5ba0f1b2e149e032ca4f566fe353bc1330f5b40b5cab9bd65ebedb2529"}, +{ "146000", "b85efd80a2171505e8e2a83feb7f7d12e3793fa4ed2999d7b6148a1673e574e7", "c76311a2cba2713e1e7706f71e22abd117ec5c45d7463bd7cf9baa7734468c79", "782f73b81c2d2333ace904959e2e795099582fac13c71a11e051889864abd89b"}, +{ "146500", "f1dec5d905557b23d644829ceb4f9de311a05ea717740e9103d155157e4d1354", "3764ee8b0d6ae8dc762a3b43d012eea45e1e5c1008e90403ba84549502c3b62d", "41a73a0299e49dfb3da0d483734e359aa70c9fa846e624314a87ab2e5291f82b"}, +{ "147000", "1e59d25367fe453ea1e39d7f0c870f14bc37e99ae2899a6f0e67dc8ca110804e", "238df05f6e2a851137fb165117f2feb458487307ae95d0683bc85fa748cea31c", "84fdecfbad7b1f0c5f7c2fb6513fb0a9871fe8af6879a7e04a40faadc409aa6b"}, +{ "147500", "4547d35c4821dd671dd3d4d99fce894d455c083985eeaff26531187f54349bd4", "13f4a0105947e707604293a632917b8b93caeb00c02a28668a9559de36e5822e", "6d41213b961e96e1cede02df017f362181f6c10b3faf55a066fee7e817980f22"}, +{ "148000", "f50a828d973baaefd78a069efcbc42389c7a9d0e17cf4476d6bff763d3b219a7", "7d057f6f26c87ead3d5a3bd63b23ad81ba5a9a84258b46921f27f07919be82cc", "88dcf2f5fff804ef8b64dc24ea8747bda74ec2f0f0b1c15e5144ebef5543d29d"}, +{ "148500", "219d8ce760106e41d5b6cb72360801884950e795cb80c5cb75a4cbee7c9884cc", "66abe4202adfd1c91b092dc15dcd702b0e383c2a9a87dad84efc20f2391d6024", "2e1b9af96ce01ed55a76a373db6f175aa7939267222b8ae2b81d904ab115c6e9"}, +{ "149000", "e13e98351891f9940b40210188016098d67d555ee60922bd710d234393583886", "2751b92f77148b0b55b15c1e1939f566749d8bd28b70f9fa9445d5c66b116a4c", "679915acf67eff37a889fdec00abfe90edd8d9a6b5195eb403b4a33b2b02f6ad"}, +{ "149500", "bd0986d58541fe55bc5615de06174615007bb0a4e9b7d52a6e1de27660ff5e1c", "8cbd4ddd59183bf20e4bd2ce22136e8b1109ea2e81fae850281e600a04816105", "03d93cf4d27bf5519c826bc4fcf8bdc5ebe413953587f82355c4df6b77346882"}, +{ "150000", "b0a52b599b482e9e081373c2d0c12adae59742c92c3feb16f2b56a536389c566", "2b66e1c89afb06043357c8a702e15f37c6cebfe2c3ac2e2994b387b111852c2c", "d4e5a3daa131a0afa29967f8ad8f402f8baee17056f075d0c811687b53617103"}, +{ "150500", "348a90e69dee425ca95455f04bb8e0a9a5e8e4c9efc06e8358e90069f33cbd87", "6296399a3fc3e48c09ff1bfda646b6f19277f2c2562c8cac5c850d691b2c2110", "f2e3eb906a46f4e787a786c9372b847e3d667e8b7afd9dec5ec2ad405c5995d5"}, +{ "151000", "c2fc138fb4f13487c8f0ba65b1843cbcbfef598d66205495ce12eded834ed5d6", "6b3d49e0f596367b951b6939dae4629d81758a560d8bbee402b4258fe3896e18", "8db9363659e76cca5e94af0b7bc72a2da150e5e34a80aa86fb42d56df45e2494"}, +{ "151500", "f22af8f0a616af674ee4e07e5821c6ae1ba54d431200daaf39362d203283af2e", "8c445485555c915933539ad6c8ec776b65480a6b6100cc2f2355af041d37ae9c", "2057ceef9679c1a12ef58985712ee4ba239592d95eaaf5d67ea9023355d1af89"}, +{ "152000", "ffb05330a4e59f90c081b821c1cc26def98eaade28aa6fa36688c9c9ec2a0ea4", "7c94c4bbaec72efc42d8c00f50f777d09fd0bf0c71475a31183bc391038e4fa1", "13864d254b6e9099c6dbbee5f505134c40793b9c353cb738b1d97b80e6c44926"}, +{ "152500", "b7c7e8aa6953c0ad15cc9b003dea50f9f8bc08d8c8ffcbb287918a9e570affbd", "16591b434c6436280873b7b1d81157359b67969455cab02fcbf7ed9dec87e64b", "998ea569a30d37978769b49eaa6a5792e64a7309313f4e982b5763c2a1f69712"}, +{ "153000", "fef11d21d57c34ca41af06608c09e6d0a1623e6970123e654a81959089913630", "0683353ede70fecca1f5f072916105b0fe941d24b2744dced890e2d4cc114356", "20a6cc7045658dd34f400e80232324750eadbdd1375fd0ae3f72fcebb8e5d6eb"}, +{ "153500", "0decdb908b6c897fd269156ef088ea6c5c76ad98cae97cdab6b9958fa458c4f1", "458fa9b12274e81b31d551966d7992d6304bd3486a76d9e484af250b4d725e83", "c8782ffde622ed54700cd51b78fef2fc8f1d0276e1398945678088c449428592"}, +{ "154000", "8e921a4716e55e2c03536ace904f1b76f2e1c1f44eb1efc293e819619fc64a6f", "9f3faf97a3d07baee0cab898c7e2c16e1e75cb08b8593b30897f9290e7564464", "58e96c936858c0d209e875234d5ab2b9e46ba4f0766cf53399e53a19804ffe61"}, +{ "154500", "b2ab747c57f1e073712e5c7c63d14e427e4c5aecb70c749d686ae6740eaccdd0", "5b6d69da753ccb8fc0e7cc323bc544e272b607f0fcd7ecd3afc27fa454bb13c1", "f720914ac67c99900d3582520b06c775eddb424243b2f00c74fa5b78534291e3"}, +{ "155000", "4a27f6a366c137b5b0d9a7864ad6ae3aa2aa4f92fd96afad203f9750743d1b25", "5618bbb8a52a4a6523d7b79f9da38af51c38ec0b250918f9fe13df1f5ca4cded", "5457390cf1c31b2e16cd5c42c20b3907b5f68e2031af2ed0e18f4e42f33ae788"}, +{ "155500", "44de83681d8bcc4a775141039552a3bc94ae7150ba6cccb0eb51d12f67cfd3db", "526775b79eb1e6f88bf7b11c21c21cd3de6b70c591b146f75dd6f7dfb25d8258", "fbaad0826ed4fb17fc50559bbed4e4465f62d7bcda7c2841868128f2b682e541"}, +{ "156000", "fd67b25d5f2f9e33e0717ef2eb6f7a8b61c0e369d1bb27d363c2fffec6934c6f", "069fcfe28f96738efe2241bd5c46e5f9dc2568399dedf97a3b222e7db1f8d479", "828d25c4b68222571874c8f59096afb593a9a8f3b21d0da13e80db52e1a7b1b0"}, +{ "156500", "e4ccbec221374ecbbed5f7515a62ab145566ca98f91fca6e9e9e5faa5a302e1f", "0138154cbb27aeafb8785898175459b8fad1a50e5526745da4f3e3fce73906ea", "6a9d291450c9e77ef6037e3ba4e4dfee19d922ef52b20d48cb51216247ba8868"}, +{ "157000", "7931d577b76d43c21d638b392ce9e89deb30440d5965bdeeff5ddca528b23f8e", "2b3023999ab4fa8af216fc6fcd1b74a6d9b91805c25286b3a9b5c21d111bd929", "5483ff5e1b7a0d69cf11b8445a1e9a1260641f7e303d234e880d098b76756971"}, +{ "157500", "5a785cae6668099aa3bba0aced796a2efd3f32357d5cda07964c38bbb8547f11", "92fa0afcea0018aa72753e44978b29517c44b86583a7e7293bf41d0fc52adc33", "f7b8d7db38fd620cdfc62860ce93c698ee8fc716776edc93f6fc03e2639d6b32"}, +{ "158000", "215585110369813d5c23324bba75c2fba77a3cbbb8074822747d1d5f7a54459e", "c2bcfd99aadb46819152e678172eca6ea41d068cb9c3644effd3da1d90fdb6d9", "4555c9718c5e20d36a96dea771a7b3d3753c871454c10285057b792f62bece49"}, +{ "158500", "33ea7e9a89e3e620f7622a67f945e6a84caab88f8df84416920e34611183a012", "fe4a8ca54ee30957c1c4ff378addca94aa3c2faa44d6dff2c90aa740c94f322f", "676d511f80604351ac7666c70d8775c2f86aec0f43d339e705d16172517aa82f"}, +{ "159000", "5dac31f23e99492315f0ec0395c5913a197ecc6bfa5a1f1c38fcbbce10f5b2b1", "3f33701f476adc2de539a516353507c2319ee322415cbe2d2a81d25579320df7", "1798754aebb4e7543f64a7935dead4fb7c197cb27b68e660cc7420eabe87c1c9"}, +{ "159500", "e49f3c6d819ba98b65a07f3e2b4cbd4ed74f8f352ddcc5b29cf715870ffc96b6", "8d4baf5eb4e709a1749ffab123eae1c16c84c08c2b10c1bf35b904214b55622d", "35e32ff53ab80061b60218b9e199045e59d7274c18d18b3ecb65ae67df00a73e"}, +{ "160000", "4ffcbf8641b4b794fe4e304f3e33f8b252b45c99d647e26c174830811d5214f4", "d9feccb9318af01dda19ac1b834e8aba8f1a31b7e3c0c874c2340e5f963099f5", "e539bd7ccfca8e6a80a5826779678e65131dec0c3260a430dcbdabce60c018c4"}, +{ "160500", "940e235e254ce7e8c7884b846860faa5a7f8fe08fd7d05bedf60a178b294bbc2", "4c96d0c1b2293677ff55acaca052f84941b801d35426f5f6fdd0985a772e140b", "369a4692e6c3548bed6868c8f5540ff7773fd465795cb6f4f167a38a9ae134e8"}, +{ "161000", "49a2fe7b8f78e83709f195d11f092cd5bf6756dfbea8b61f6ad4acca38e0f433", "c61985a4419ef741b3255effd2490b3959d9a37b9fa458a01e314acf2cd110c5", "51745f2fb8b5b26377d02698cad29b811725181176b024b8cb6270a826aa2d1a"}, +{ "161500", "adf7a049b0055137358e82ff4cd0b223d4f1e65a99cd9427eb8892e9b3956546", "f2ea625ab6cfbd295435c3e70fc60ca04f444e88a9951351519c27066044094c", "822600252a5f7b5579773d156f38accebba75f2da548111012f2413eadfbc939"}, +{ "162000", "78eb9152a6249d26cfb9acccd3be7692835f61a70f9c4dbca7dbce97e8eaef29", "92bb404d3deec9249fdb8e8b0c11e1e6ffccdce4f6b76e49185e0e0aa6480b30", "083108fe3985638966053b609666fd101cebb4826499205dca009f72106fe219"}, +{ "162500", "f0016f65cfe29b53a443c3117392b631edda432fb508e67f537158d939bd24f9", "7da855957173b1caef3a5be9882b88d6be2feb3860bc528822ac203df9480ef7", "97173e216716af1354c97761a088c7e53f624cf44e0566d20b1e6a4638351487"}, +{ "163000", "16310f334b323b1c422388a77287e590286b436eb1d54c99a7dce533febad9d1", "50b8d182a094d5709040d1f8be2ed7aff41c50d3dfb49b6474ed04c7563a2afc", "b4843076181bc70a13ff31ac41a165cd89223f409c9e0d13f235bea9e51182bb"}, +{ "163500", "54529c58d723c981aa51c3bf7202246d09e30d6bcc22b28929b2bc80b970a46f", "81722de9f999145ae10c5a72cb03be616a2c631f6239f01243836ceaadb219d8", "7f60e919dfc92720ef62c9e3bff5878b9a4406e01cae08ca99cf4b3f86b2809e"}, +{ "164000", "135d6c860f9cd670d82153e8e37e5202b6b1632cc35280c0210587f4cb4d8f49", "c5bf964eb82fb51d1f5a4507bc2c9d658ae2f868cd517674ee1d81266971aef7", "fc75259e7d42db12a26a3e42931fb01e8dfcaf7f0ccbad81db12a4130cb978ca"}, +{ "164500", "08495f35f925470863e7dfb79ec17bd61029899bad972ca0e5bdb0512a0ad908", "8901ac98fdcdd833938280eb495214ec81269d8ee99e0c10886b9184b0aa9d26", "ec01d72736d931f0852ed396196ae71dc6a82c0b42d661a43c424f43211b0ab1"}, +{ "165000", "5178c8e3106c700a225efb2d7453be3a94616e980fae5a532c0a9fd103aeaaab", "a71b7ee462788bdcf6b6945da2a2b426770bb4e31c7063db4b9c80f82ca88af7", "33dd08e6f7e8858c84e0b9c438ad4e6c59eb9c4c30aed571f57a7c213cd78795"}, +{ "165500", "3d1e48c8657aa62207f24888630361eb85ea3f8225e65deab240e5a242fcc463", "b16e47a7ad5a208fe467efb2f7a2aba78cccc41dbcdfde571ded9b033b2c660b", "6aebbedc83a2cb1fda9df193023a8738e6e4ec691b5485a8229bb0eda0f5ddb9"}, +{ "166000", "2a5df181ba84755d4893b8af164abc28ba9d67f0fbf70a9fe44f78202c19e78d", "6382ac5c3033076f67f758d9d4a66006b6c67983e46eb4488b8482e5d020cc7f", "c190f4febd681311354ce703dbc7504012e9e2c7f176f87d87d97ad0213ce2a4"}, +{ "166500", "f33bbe1188c265e4f52649d90a9c853742c89348276119166d9dfb5b0a1c1d1c", "bc724795f0704caf13beea8188647ee2d0d8c05593cff788541d1f694f02e7df", "04e29612e5d6d95e89b80a3ca7fc24ca2f8472b2cc4f7b87f852a58a3e3bab0a"}, +{ "167000", "278a49c7367096b101da81aeed3a9b3763b9087446e3f3eb7d279bbb180ccd1a", "c90bba777861cff1db1ef3cd40e240a74bdbeaa23e2d4716dff0700608431547", "b1dc55904cc908d2c676275faee49c1a788c14c4ee6c7db7fbf85cfabee49924"}, +{ "167500", "de103832de75b420ee01b8eb238c7e5ab2fc2895848f1fb934bc0979af54ee3d", "5263039373a72cea915df57bc9369aa15e7dd2ca6c3b6df27938d5240ef4cd8f", "0f8d4bbae624d8c65e75cecebd8c8924c544404fb51a5122d6d79f6ad81148af"}, +{ "168000", "c347ff8a9e0c4297f74db5943de2edcda14652f1e707b0d789878424b0f50555", "fd732e674ea0cc59454e599365d9526a135a67ee82a1e54460f90b934957f9cf", "7c421c0a72e79c75e76037f83184ff85f13a833acc677d120ca890d2ee62576a"}, +{ "168500", "7c4bd55cdd16268ac7da91c44a5c204519aad6dc79a173d65227995d8f480ca4", "66e715d9afc7e37855c6f1436bb3344b440a7db44fe5163f2674b542a3a8affe", "756e2c879bd29673c2622c3ddf7ab61784b968784d4b38e8bcb5064a4056080c"}, +{ "169000", "8d8295fb630e487b21d46f82e5e0bb95d667635b1c0cde080e9965ea021f0d3d", "32309e6dc4e7812fe36a3e9f14079eb2f9a04dd910965a631f76fb23f29f2c5c", "cb1db6a081bc3bfcbbe3936ecbf34475345855d6a80e004f44d6f3a2aa883bee"}, +{ "169500", "3ff4f89571d4b7f8e2b25a761e2b03dbe82d9d2acc565c8f06f8e61b7b84a48a", "d71ea82c1b352917a9a60feeb3ea40f35447c58909a0832d17451458c4a0a079", "9791e55a423775872967f93b1c93656d60c275daec74680174f9f3462ada4fe5"}, +{ "170000", "e4612c319a4c8cda00c8853428e0c57c4c688d9c7ed0ebe3adb4ea410066230a", "2428df1325dedaad3c6c2e18ba57184348603cb4e5d4fad961d9f66a33e8d4c5", "298faf147be61758d1bf330195d35ac46b2a674af72b7cad4098a790f60b9a13"}, +{ "170500", "38f6d4c55c456c85b59d965db3386f3bebc9f3ffc101703667c9ada2c6f110fd", "7fec7fc3f24c1f7e635e06427d949e9244c3383ae8a1cbe5ff92c20318d1b303", "784adfc421d9d79b16745145916d119a7b8d21fcdc1b2b2a5de378b5caffc8a4"}, +{ "171000", "fa2d2abf42e47345b9b06ab4f0dbcb6d818815b383959b5b0f69a207e755ae18", "6943c6e99feadbcc5f22d2000b715e609874953a2f6b06ab18c6f6fe0d9ead08", "a5617beb4eb621345e1af0f9a671e21a92b223feb5ea9011fe196f8d673b5bdb"}, +{ "171500", "b269e08b7b8fcfaacc4cb1cdc39bea13237265f03eeea6df488039715959d60d", "f978606a7a355e240373d149a0bf3b2a80d735371506f6d83a7eaf2a05f6a300", "5c977031ed8854024e6d2484de8c4ebfad7c69f130b063240b6ceef706ff7dcc"}, +{ "172000", "c1ff70cb404b9a3f97513e00fe8d713ffc5a1ea49b29be1480dfd3b0e4410d1b", "f2d46aa05b23a697e347a4260c9d14b51e08af5108bf22123b820a54c73c3fe0", "878d911ccff1d8bc13825fae7d2a40dcfdf3c2c6c817f9d4f4f2ba0c77d7dc97"}, +{ "172500", "6af8406f49ba05570e46ebbea295e07ff856de60f7f7a85f29ccdf0483deb414", "2bfa8eaf8be3fde78ec35b8bc4ec1274cd089732617255d9b1450f676d359631", "1c5f68b20516cf13759bfc90f300a01c970c2ed22aec2f5440d524f4fb8ed2f8"}, +{ "173000", "4187e88e79ee333c661955addb9fd1ff4853bccda1c1f73585fbc4b866d46ffc", "2c561a6112ac2531467818ef79bda7fd294cc2d1aca8d700ffaa8ca3c7e2cabb", "b4b9badb564279262308912a9588870961cbdb6fb9ca5488f37928ed9eb3802d"}, +{ "173500", "979cd0755a559b4298c4e1af1ca1ed389c152f6800718aee777431e3b84b2975", "817578adb3539145804a17166425c07a798bedb2637e8e6567e77406da8cbab2", "e0337c7b2e52ff99af8dabedd1f1912d1a2201e8153b3b984036c26a7fc46ea1"}, +{ "174000", "84e476b10a846c1f76cd25ee8721aa8098a3a794f56a5a6e2fa8ea08dd7de954", "7e3015ed948fc061ef3955ff4d18f5c9f2ccd86794be959d5e51e604c4ba315f", "4282860b30cc16a2db68903e8bb0f3c1dbaa5949174240e3222d70a994cec1f0"}, +{ "174500", "daef6a8cec458daee2a97f145d74867790d12697f424e390fa5ea96c0edc5889", "e70b3b4de2ebddde769763e56a861ea73e3a9ab8360f0626ef5075560899c18f", "e69b1eef08603fd07359c1216cb118cca49ee176a5448a49e9a3fbaddf9936cb"}, +{ "175000", "3f6c5c68d024c26235bb054fe0e892b4172a50c900ff7e36a061b17bb4adb44c", "f36837bd4b44bb99bc4a99acdc71611e6bbfef26095aad173d5b6c2847cf5cfe", "31f4639cb01d8370582158623353a2f1843dc7d0d5240035572fe76aff38480c"}, +{ "175500", "2a25fd32974c49ec621f4256e89f3c1569734a675bfde35fe0ec4572459a99ce", "0de2de8ab8f49f684a4ed93762fad169165b9f29306fddcce37a10b3e0f324b6", "4aa307435bb260b7936bda377dc6b2ee78dea1859c5a50504adc278372449044"}, +{ "176000", "ca43896b57242e50c5e1b0904b12b7008d63f30810c9d1728929a45a051b1c28", "0c0a240dbb5b8d9c5303c2e401b1a9be3eb940a2ccdbd40482b18ebd9d16fdc2", "735a67586d8c32fb70e490082bff35c245683e46815882484721852e5cd958d4"}, +{ "176500", "01bd824255da4562af0cfe656645a2e644bedd67f5c4c2266e9d706d724f77c3", "c1c8c3eefcd2a0dd893ec58a59d9b4b9fca2456b4ebfa118caf122316ec1758d", "be47ea88b1c0c059de0a8ec08c34a38b3595772d37516a3f23c86c12936aa27a"}, +{ "177000", "1931b94a1d1731ee2fb2b959098279a73f2938815dabb1689c98ca64ca265eb3", "9ecec3dcc0f626eff5310a338ac6ec36e52cde0e31dd2668510985504dec6b76", "4ed89396d2f57a853ab5c7cd9df8b3a83a00c56806c8e31e8c229d835f56a056"}, +{ "177500", "d5e641f50d45b9d3c2f81c255fab7812b79d778bfbf3acc3a905255009efabb7", "780102c55e6488511505df92213d370484505fcc63e36844adb4e55e28b11891", "14dc898b282b20f15851d882a8a54723f6daa46598ba197a435faf51ca0cf3fd"}, +{ "178000", "41dc7c791cea13b0c22c556ecf0b9c43bcabfe110cda05fdffc9a213d07878bd", "f502dfc4f8e1e754fb19789de0195d3f76515af97df6f6a4dff9af35e9e64cc2", "501bdb86464c2e4c544c8c7fd634dd884c38c237a80897da49f526e44b452dce"}, +{ "178500", "86fd0e05f7c975edd10fa04040fcfc06aa5988f25a24dc475468023fb5ba60d5", "9a9d5b0da31bb391cfadb78b79de03e6d2f9356b6e8f2a6b6f3561718607666b", "d6a0a18399d9c382a9d7333af7208f4084dbc08054cbe0d8f0c0403e63489470"}, +{ "179000", "9f87f2c50cac2bf6596533b242692ac06dd59688c85711dd3075556a42b5a51f", "62c5b9a2f74642239aa89a9468c1959af35f4218d16ae1c0e22879ce5aea14fb", "1e72866f3fbcc54b6d32cce2b1405ea585e5d98f36eaa840882db29d1cb40384"}, +{ "179500", "2802d26be7d5a8dfa0e84d507569ab54eb2815addf1363e844143d4d1949aae3", "04a66a42a874e8a94de4b35e0fe5b2415e2806089e62b0ce867206a3bbeec923", "6c97ac192eebe679bc5905a7e5684ee9f1dd3f0988b85e8c1e104cbd40c8cac1"}, +{ "180000", "fc0f88ce08e8dfefa8774c7b9e101f82f4c7928aac246233b5d97b178ea1e8c8", "d2cb3429b3bb7ca9c4bdbffed735f779979900ec989687ff9563819b3f340a40", "ebc045856c0f24839f6a45dd27eae4ae20f4661434a02544469b92d44d80133e"}, +{ "180500", "55068efb221561b62da4c6cd3933963165b99679274f0a18b57e12a0f59c02bc", "f4a3a53f8756a0f1ab9f0dde456df65f68b487f452e35119a395990224589672", "bd9796c38a7e9d8812e8aa74fe7400283cc92e520eee8b25cec8fb8b49e678b8"}, +{ "181000", "87c0badaa9ad1ee338a1e0bee51f0e5d95eeb69b608604b687e1b75cfe28b1fc", "55c6a1f3d35e1ba2c56261370b991094f37b2e0c94c585c83c91ceb0e66b4205", "c27ff860820231b97dd7e5966560e39679ecd722ecc3b5d350db9d614072d9e6"}, +{ "181500", "0223e4ac4db7cb7aca8c5dbcccf4dd6d67c261e158579465c830d00f0b2065a4", "1523b5a7b17c5f0a487b27b05911b0b023b7b70c1e93a676178193e10dee764d", "d1b905426b42ce35f13137ee204becc90c653d824d70a7ad3dab923aa6e49106"}, +{ "182000", "3bd580fcde83b72980a98de1bd2bc33f5d2e5260a45b2025f8993ff148006fc8", "b5867c690edbe8ebe6938bc93774d516dc0de5a71a28b48539e4029162825354", "44c3ef084983f11e3a1f40f9d87e3c0af847b4341e1fc53d576a93fc9910251b"}, +{ "182500", "d5ed6e8efecd96800b30644154dbaef8704783309362f9cdba26c757fcad2d70", "f64f64d8652b12527197f54411334ba0ba66f2515e4c99281a075d1df597c8b3", "0c1f07a69cf1735407b92ec781050dc703cd29874cb873c09126cb3afa36d701"}, +{ "183000", "e926c6476da9f0d3fd84aec136e029881901667ff07d80ecd1e6e6e4a1e78979", "e74160bd9ff069b6511c0602a1c72fc61dddb22899f805cd9c2c0be184848033", "96eab6f32832d3e27bbffae0e7db6c7ef6fb2aac226893ca446387a1b76230c5"}, +{ "183500", "5bde7c982564b58b9d46d8208922b3ae8cd1d50f2f68c7a4a8d71e636b66181f", "00d016a3247ef22887c0909dc0a7370c62bb2601b09425bfbcd93f782e1466a1", "12c823ca9c001b3f59b04b61af005cf13d260633d4bcdabd77594c9e6b08c14b"}, +{ "184000", "f1cecf410b8d9f5cecd6bf19ddb1c7157cdc5c42e110a42596620d9b54216dbb", "ca3d938eed902785feee39efcc9a60f26ba5a53ef969f174ffc7f44dbe544bfc", "fb6bae9cbddcdad7e3115e225bac8ccfd62e4c0d450f84a1b0bb1d40e716d095"}, +{ "184500", "89d6e5e381ea4c429428a773caa457945d6e5986e77830699d64ca84b6b7cfde", "30e5fef97c937baabf267183b5f8bc9de88eb72b00c204abf6db1962ad1e1f0b", "3b3ca3348b62cb425ac208e34729700e2c0f40c8ff769c3a2f078479768bf6a0"}, +{ "185000", "d55dfc02a7dc5e64f615b9821e7738cc3f4b1cea50e291834b3d950457c0befa", "3976b8fa6d5486bb07e4f6a5a63f200089781bc8c347f858bcd2d4a8eb4ebc7b", "896b5c4d3a04983ae70e3fd2a3a47966c20203204f3f55ddde32541d3688aebc"}, +{ "185500", "b74792db4244be3b16341cd6bb1af5c7a9b71df58b812691901a59e2e6889f8b", "4523193666a8f6eab2f73949efa94fd98d9ac8821ffec1c8069abfb1dca83b0f", "41b6264e2cd8870abddbfe47bc199ad0ea07fcbcdc541b7b1891c9dc1657515b"}, +{ "186000", "673e42a71dc7428d516a2bd892f5bba9740deb4a8e7100afbb0db70de4432d4b", "54bb7fcf882d25f7e4cc19b41bd13e44d70c04d31a6b4e2ddc388b6ebc0b1818", "46d0b88252df9f4992a57d8accf413548bb64cfc04dddc3cb04ffd994dedc695"}, +{ "186500", "ac9d112147478ad6096daea4f3b9b76912367605cfb6ac68a5951478787d84a5", "7e112c5297f3521039d52a994be89b1dc3b6387b4be5398d7673542df3db0945", "f9147a1faa3d7041dd4c83681f8fce6bbc11b307815b2697f02d133d6fe7d5de"}, +{ "187000", "b06838fe81d8bc39304fd98dc9f24ebdc0e6a05a363713e028382d77334c2afe", "53c32d4af24bd19d1dda8c23186b6cbad5cfbaa6ee169666de3b028473f3d388", "7da79dc097ecfc37210e4c4bdd457cd81c4d3e150a775b2665c44b65e09de915"}, +{ "187500", "c3f730a1d3977c557401a7ba920f22b768e9e89924a07598af8f6dc0930a4585", "a83e748dec264dcc6494d6ef7c63025e554aea410915c25db93249088c287442", "c3933db2926c4b67ca839e3be9171e1e075e9dc1d001d4da8b7199477c673ee4"}, +{ "188000", "4a74ac7ebe38798b80ff54f21a428c40915895bc44a528bd8e4ac3b9f378def9", "847a11b8eb71e0b5dd698b277fbcbbfae9c54e55477320396a602a26b1f73d8d", "caa476f95144ecad27f8d99b6b8f0a6e5d1c247cc48fa9535f4cfc986e0a91f7"}, +{ "188500", "59891ac998632472cdca935fa4a3819fc676d23702621f0c41d6d38fb9e354a0", "4393d0b0d5af19f6c123777762a186fd30666e8498fd76468c3cf928b4e6fe1a", "38f92f653e9cd1415db7b4f10650f767133e43f413173f20db9689680e33be76"}, +{ "189000", "7c43d2b882946af37b0d1b1e0b3c08a8c55e83b9d93e0d3c10ecd3ac7a49c1c9", "0a5758bf838434644aedcccdb7905d4bcbd576745f82e53ef74c9539b9c95cd0", "a78379476f62d06d8e3817387860f6ca0e409869efc3e674332c2bcd5a543ac4"}, +{ "189500", "4913cd6821bb3900bb012df98da308582c7f99c8907d1dcbde5caeeb04ba1abe", "83dd01f4f3544a1254fb7b6c1fd8654a10b4ed99581b1058c79ff2a3a08b3ab7", "d38a7cd403d69c3d04f3ea66cd135fbcb77393e3d8747c81a43ae30acc6fb763"}, +{ "190000", "825d6842d16dafb7b6d3fff172fd176916478e6a14c50efca5e2b6990f7c2299", "0d7f3744d4e18d9132d3bf7e94b9325900ad8a574c6a48b04e6594f2ed07083c", "a485cc141b0697e8239feb81967a584aacc332c4f0c9dc689fa9cef5a7d52a32"}, +{ "190500", "b7dbfde08c23efe184956485d0c19d62325d121b493560ebb0d45321b1832b38", "227eab03ea5949234a281ae85657bb5fa39b271fa2218e294c4dade8273639eb", "189b8d34a7c89ad218babeadbb95200ea07e4aae2a840f432ce29180cfee95c3"}, +{ "191000", "e61629b5f59b130b4e6fbe4d3aa8027d13aafd890ac3a16b1ffeb1d3f590bc5e", "7736329d7fc7d226fbce139fd58d1b21a41381b442fd62f1d03bc53b5580f906", "60f22a08d5f6f33ecba45cd1d80f82b42029db3809d1101c43ae3e9bd9efc2f6"}, +{ "191500", "06e8304e59c8f386db5f89bbbf524959e5674c1f560121ee65e04b5902833f98", "5e099e60aa5f56a39831962822390e897947b435b4b84cc2f45a1e98319aeac3", "93ee0024748a9eeb8124bf9b5c298f7402d928459d5e2b8c5e3e241812da7fde"}, +{ "192000", "7a94bca1896611bedd44c28323897ac0b065d2832d36000b51da6d8da42ba38e", "640f07390bf420c0f65d0b59112d66b148df416f2a139f961bee379df0928bd7", "6196ad843e24ef1aca394913cb15a1a659e12aaa7b7cda6d0b87764480164193"}, +{ "192500", "23a1270346e2cd8b1439b2357aa6d9967285d727963656385edad740cd66922c", "fe551350fefafd463b3d5f47a53ab239b346bebeaca875c6c7a87d42ba976bf2", "f354c08b5a5faada798b058f860e779260600c5a36827b2e00280fc368ddc671"}, +{ "193000", "5c7ee526691d558d00b30f649c4f77ca4c595742f23e389ead78633f8ce2dd35", "68a041f99854b2ea4ae5bec9b030b48ef9edb3aa89a144bad9c7e744b234d409", "f54a673573587b3d9d1274e6e0b65b29cfc204724c6a7bb9cabfe362e28d04d7"}, +{ "193500", "d03957be53c5a92ade2f6caa1e1999c3dfb567084580cfc618fc7bbc6758fc1a", "e218bdc4ec703cc01b2ec52b860b2bc0ad51b90087088c9cc0e58736d625de91", "b68bf79767cfeef3edaec65988b827e286bacca28042ce3114d56658177c0cfb"}, +{ "194000", "d50b3435b1f5fe763970370fe9fba1f0a5af9e9a9abe295e1e61d8832b43ffe0", "6f3878f181e0dadfd1dafc8b2e75c73c6ae0fbf97a6bd1894b20aa93139cfd80", "4ce93b30284eaa26b7ea61bdd747fdacf2c4537c609924824997f748184fc30f"}, +{ "194500", "43f28b5c1af708ef1725ae8b0e4542dc6c6f33585455e6763038d93b37992cf5", "6792e3e7d2ee64a48ec47e9fb86823aa726ac49948e3843d43ef80995a4ba7e3", "59421cc124edaf1dc5e7d717176118325f8f75ca3e9f7c4c506134fe9bb90cd2"}, +{ "195000", "27deca29e0f720fa505c64794b7904c2f15e2b2bdd539f6066bdbfa8b9cb16ae", "53d423505456177cb9e6e39879e51b1a473abc363a6df7025d6c523f71fe10aa", "d8f3589f66e7c921cca22ebd1c9145ba10dc97f8d9aa1d738877d55309bcfab9"}, +{ "195500", "4996255d3fc243ca9b29ed6f5e7cb2799330bcf2c11e42ce9a82c017fa4dc47d", "1ee2de24a628d83a4a9b796d5f3c6c65d0327202191554d0362ceb1418904a26", "dfa80cb7bfc802b65a7f4a655d21701371798227507205908dab6ca115e53e2f"}, +{ "196000", "c3861c14add9fd9665a1751e1bee488a13e0156bbd37013e3e6a8da54da26550", "4da431d08df43f875267b70903b275831281c28902749fefd4bbe544989a910a", "45a345fa82f8f2447a738b7a6489b6f5e64157753f7f661e391e4b6fa4b4cff5"}, +{ "196500", "9e85e9ce7c9f969af748556cb124ec97c581e6ed8367c4c44e8b9b12d5495ea9", "14f7254f9bf3d122eadff425ddb06f86c16c4a4954bcadb5e99ba6ea78f8f0f1", "f141304882870f7a1a54ca77797b0d713ad31e7f287765be87d5133e9abcdbac"}, +{ "197000", "387b990115d39fb36240de77081a933eb7d4f8ae20cd72f0dcc162c496717a4e", "69c3b4cee6ad5d2d315e2b133a716b8640b170a0f5ea53269343bf4455a886f9", "a0ce44475b164c0f91bba84d738187d02ca78cdd865fbb28a5d8f22c33c1e237"}, +{ "197500", "0db48271823bfbbb62c8d9bb68a0ff7f46724dd251ceb8244253418b3089060e", "0c2cf4682db25fe743e7e2781ecedaa243dda4d9944edd9d1aec7a9e93b831df", "1f3027ed373f00ea7980e7e14bc8a1bd9fe3952af41e078f2b1df32f55c77d38"}, +{ "198000", "c65104e71ac22bf228691460ed6036046fb091eed1059ce756e1056bf149148b", "3c3f1f86ad2cd5cea8a979c55d01fe3dfcd5d6ec6fe485c3461d65604ad4adc0", "02fc4a02986275f8692e7ecccc1264bc784dcc1ccd811bdb1db098cd1e3eef1b"}, +{ "198500", "30e8c038e2a43c5ddc9e0f3a030070380cbb09e577ed7d783b83651df9ad5015", "dd0bd23d500ed9eb599249629cf07236244c001e0517c93dbe6debe262e7f4ee", "e6739a8f4f4e629a08189b31048e82982103b7d33ab0b4b56c5cdcb1ea2ed1b9"}, +{ "199000", "4b4e61aa4eec7a39dd94aae2c114994fe32185c72050d3908b7fc0860d41458e", "0443985e3352c7ec9e83fc34187460671679f71a3eff263956dfdb306f4e518b", "f6611077832a1c9dd956b563c1b09457d98a2b6b832d3788e30d8319a1026fdf"}, +{ "199500", "09e62ab674ae8526370e0059097c80cbf382fa098e67d4a1175bada96d5d87a1", "83de440f57fa996de35e346f73bc616137946dff6edd47273615c0a7d4d3d7e7", "681274c8b4d83a3eb9b76bf5e984c2dfe0892282f89c2be9fcde7921ebb62dc0"}, +{ "200000", "cd9a04e20b651dcc4518ae71ff5b0c8bc2ed5c6eb3d5fd2196b1e636987c3a95", "6160d970d27a8f799d74d3e01630761bd655268486a9107be28b128fbbc9dbe6", "e00de657836ceaf31f5bde6a5751a6c4c475cc23f9e78a01b405c06e106b5414"}, +{ "200500", "03609721a5de60ab9175d5cf5b9dc444f8c9d420b94814be90e39e4d5411f33a", "f1625e3d9d93f152c9e351928677f1e8cbca9c6812473c759de6216321fbfe53", "d3beb126fd503a82fc169a7b4b2c56840e2313847bfeeb520a91bfc0bfc721b6"}, +{ "201000", "f1be5c8c40f967dc2f1448f38a7e7e6a47c6d7e6ae9eae150762642394644f19", "562f88889f723e4c4d2a7b0f8b0eed383db6aa34c8e094f88238526206af125a", "1e62d55da61d7571fe187cac6157379772d99a15a967492074786b5aecbe6250"}, +{ "201500", "668f7b1463226ffe529002e0dd28b813c68396ed381a5725d166691660a0383c", "0077ebac17ba34e5d77c492ce62473602d1010d21a99380380dcf52f1a6a3318", "fa3afe138a87f31ecbebc18904846de2b7897b9759f7b6c60b230a8101a30e60"}, +{ "202000", "60ea6173bbe62b24b704cfe2b6e1d1995dc8854d618fb0e42e0c712110b70e50", "aa3b08fccaff9887aed03778827f73871a658dfae6ad99b7521142cdf8e86dd0", "4e95ee5671de054d13d166e8318a170bf440ad2ebe6182b2e55dbf12025c171b"}, +{ "202500", "6de298a7a2fa7ce5bba344237129f982b1071969df56c15d0ca2c0fa39f9c1c7", "dedfea5340d820409423688ebf7c236cbead8e502dcb39af7686681b1f4cdea2", "cbb2326e4c743de2d0834b486e4f8b1029e96db14dde184423a72cbb284b4341"}, +{ "203000", "0e117900e8f0bc91b0279b83445b8d9cebb374dd81c84a52f0b3e6b94c880e1c", "74c1495fb1f720209dadc85404e75bde143a59c7d21ecac61204734dacf63545", "b42a2959dfb5317c241e686bcb83ac1bfda5b7b87fa8a0004cf069be1193ab9a"}, +{ "203500", "ee347878394b9da8a6c11dcad54882196eb1a6acd7e323154167e764d57f00b5", "6ef1bef22de744dcac118ba398ca60424a713140fbb76fe0555f1e89369458b1", "33ab652565274a6f0ca4e32152c5ad71cca5e7f2a0a198ef2e7af6d11e7663a0"}, +{ "204000", "a687e4d0cdb3eb142d1acaed94b80625e8d9a9d472545ed1dec3c5e966db98b7", "728306e941f0ebde00511bfc3a30e50cbf283e1850ad4145f2697671f14c5775", "80256fc3b1e5468981bcc71318d368520445ea6a76654b2c4ce3c8238bf405dc"}, +{ "204500", "c813ad2efcaa352e786ef9dc912e133bb1f32fe408a54c114152223fa3c4e96a", "fefab4b9604535559292b1b31c4996dd815f25a8ac474cf8bc31d0c176aba97b", "904cf3d024345bc0cb59b2394adea94e9f9e0b24c0b298369fa8f13a4a788443"}, +{ "205000", "b67beac20c8c3dc2e07c7d88d8bd4922b8803da3a5cbaec8c8b0a6601314df69", "88197fef17e17da657552b7cc5ea2e09377fc466d37dbc22ff8a948509057d63", "b9ceb088a6bec5d9ef64b9f3fbea11d3c74a023589afc1d03d9ebeb8dd171f76"}, +{ "205500", "0937f7527f96ec479765e3be263f25130d7898056813dfdc67f3f95f4923f2c8", "716b95c3c62dce9b236cba23dfd9dd3fcc68cd41cbe9d13d6f8349503fdc3827", "33ad2f9960e74628b62f3c9ee3ae6158c811656b69b093eb7224d9e7de52a58e"}, +{ "206000", "aaa70022052f41b2195c68a4c77c11b78e1a8136f03477d310a57ffdcdf835d2", "dd9991c1a086391127322eec9667bc193908aa869a012b36f0968270c8c679a0", "5dd178775801ce351cd81f8a943ea7226c58711a5c51e1e1a23f5697728b9d3b"}, +{ "206500", "7724e797f7f8e157fe2292c5a76a018278bd7bb95924932df289d975c4191c6d", "dbe2029b6398ed4f32b906956006915345255bfac82ddcd79e44848574c50d36", "d1b982b2945accffddfa88f88a6ecca1857e5004ba7cef7c764c3c348989bfed"}, +{ "207000", "3d779550ba9dcc4e29106cfbd2efd9b22340432345c0df139ab31eac25a45226", "cbe3c2dd884e9ed7a1dae427c3d475a8c9f3c8803d0f3507398b92a6cf5ddb96", "e4f050dbe983ce3a4c222639bac89a731956ba1b8d78d9ecb04c724527207e5b"}, +{ "207500", "5484677fb6f857f8009fe0e371280b61ba15d0a5fac08bad41392dec1f38c85a", "649c2c9faebadeb93551828d590b757b444b6a54b40298519e5aa8505fd81009", "7b3fee88b64fa8f3b491877f080c4cdb756e70d4a3cb4731c384f4be754650df"}, +{ "208000", "cf31a458b286a4f77890e65d02cc506bb0454be9f373a1685f2f6b2b91a76207", "22e9abf8f61d55f7fd7b85e0efa3d8a0f6579f43020b19cbe921a79d0122000d", "a28f21af0dfda5b9461198a4d1bb6a1668ad397de817cc1cba0c9ca092831401"}, +{ "208500", "4fd3fc158e9219659c7ceea1c4f02bb89563c7524e9b8e9f158b61bc82c52881", "4a0ec89610a1cbe8193dc195991742ac08583b9c86f9d24a5b63241f8da4b476", "7ec70ca3a2fc695421810e24d119812218bb549b078d36d04c272ddf11255643"}, +{ "209000", "d54f4d0b5a8ce4ee97d0ef4cb455ac54b93b0092e177f1532e6513052439e9fd", "59a0a1d9ca71393c4e4271d8d1ea63d8f0fa6e8388c610fe4bfe8362dc0fb231", "af3eb79681d6c9ab82b6d4110b48ab5bfef942b0fed6354464db6cabe8526e2a"}, +{ "209500", "14e2bf16398fc52492652cc0ef3fd516eaffaf2cc3b7f89e37f3bce63d1117de", "d9a9a12a655ef80cc830f766200a05617bb235555e7cea98818bf103a3a6c1ab", "c5206760e03824d9bc3897c88f85dbbc62e0c26bf0b399cf3b0b0cc2556608b6"}, +{ "210000", "4e035fb68e9d78b953e76e14a90355fa127db686af2bed4bdb301fc3223c322a", "f6916044d1b6a16eb726cbd05a2e900f5b9f828625c850cccb699327c22037ba", "f1e000d5a2879e26b15937259b57891c59f50720888d76ee66ce7dabc3678231"}, +{ "210500", "e9ad24df7fe871c7a87de17e0c091b99a332b47903d8d39da2a18ccafe02dc1f", "f2cb48175161b22cf3369f59e67941f77675c6109590ad622a4bc476364043a4", "2733184c95cd78942b971fc16340175508f01259703aaeb2c8ab74624c1e7f50"}, +{ "211000", "21fc2c297b7bb7c088668fa502215ac26b2ded973796765acc4feaf2bff112a9", "e21b83547b49382c15c8fdb2929711d49eb8693d08c0738813df68c359fa2442", "204c7d0fe115c292647e70fa3f45212bb876f173885b51c402a6f47c9f6c7f3f"}, +{ "211500", "a83b2da994898b752271b844f26d88d300646e04c4e89786f24fb4c7397ce6fd", "4d8d8b7364ca603e61da4d09bc9c0b1dbc2373e65f5db2297828aec6395b5991", "2e8e7abf5d80dfb979a72d14b5636b2f43a03b732e81453167bdae994b5e0730"}, +{ "212000", "ab0f9dd7169c2b902f4762fce10983fe94e3c349353e189a510781244d66b77a", "3ba1a0d61a8b8a750cebf79f5c00362bf3c909f11725bc9e9762f21de08a7945", "8b45c656f9e0a66ef94b346f2692ad3cded09857bf55991d280dd9e27e614a38"}, +{ "212500", "b1fb4ee2f329a5664e6be5c85834dd79452b1f89551d599a70852bf49daec183", "d9143da167a6553a85f452745577ee6ef19fd21565b09ed5fa6cdc00a0f01a49", "dd2aa2786a23ab647fe5806dd1f2feb46461090b4149ede9295ff2dd62ab5120"}, +{ "213000", "dc4c87ea7c60026a65104a0d8a04e5540e3952df79a62e59deebfef6ae235e81", "8da8a14d3971436306dba00351d265f0bd06b1f59005f94336aea44880498b5d", "1373235a2734e53819e68a14b579b27f63ab5858c92e6b405cd990f30daad0ed"}, +{ "213500", "2466c2e233db8e30bce3d5ba87f694c3095fd391b6c38c2edf907a4f97d498eb", "c3f5734faaf87bcaa9be69122a144ad1f26009d8fce1f859a17c2fd4bc0c2c0c", "c6eacb28a16d84395e1f13d6ca6de8e3e7eded624e85739f23bc05cc917041a1"}, +{ "214000", "fa84d9bd1c6575cabfcec73e1834d129821b6a94d7814d15d038239cbc4a568e", "bd1413d32f7719df41ee9caf406a30c8b97e2f875efe7c9ab2fc56555136b5d5", "41e83363b59ad285cba7f5b42e9c845195bbf14e4cb3afee000fd51e3b03f790"}, +{ "214500", "556dbda0caa051476bf896fab40e8854a166c7bc416d5f3121fe1d312369dd0c", "4e5d7dafa56fbb04283e8c41e18697dac7beddc742d098bfb87d4df1fe90679a", "d3c7e3f958b443a227af7473a4776564e6f2820fc88db797469ce6824038ebe2"}, +{ "215000", "b7ccb76ed29ea49301f630ca5e9cf200ba7a9388156304636814ba6a6b417265", "8392386752e5ac61b9856b95e9c833b57fbbc5717e93f63e3944676202df04e0", "fe5fd65400df2fc764107ce9f33000c37d5e27cec021c2db43364c76d2d2d4d0"}, +{ "215500", "a56a071a789afd22ee4a9e4abcebd695a26ff824a895f5291ab639336d609bcf", "6dcf6a9b561236f8f627cd567d937ca4d7e6e9df72d466fcbcb505af9bf1ab11", "5db7fc42ca74a15514001d9781c8eb72833094b6967223e45135169f12928feb"}, +{ "216000", "0e1a9b2d055f2e7b637d9fdeb778c040967a8a2fbe0a38ee57bce4e8f4bb0a51", "c5532c221b5cba08f4ca281a247e98d28654b934c8595e57873232111c347ecd", "d7e521b1376e2ecfc6582d4164d57d89e61196fed40bafd33052cff69f65e101"}, +{ "216500", "9890c0ab7b427bfa46ae90fda04503f1b17a2493c7b36f12fccf0dc010d3f9da", "24ba34ff5619c38e4dc516e815af584f4c5ae6518a57918aedb59403a3b356de", "2b43b5a22e6fdaef8644a6113189ae7327dbf69e2b53c702bca1993bae8ba0c7"}, +{ "217000", "b282a7dbf2dfcfa4a46938422e557404ddcdf11509053fae49f5add5dd101d8c", "645bf6456c36a43bef5c217fd00b1e457ae136d52396e504db5ed9a97e406594", "80a8a9c2f44c33be9e641e56b5d9a5a154a2800a73bbab2a0580e214f37c7303"}, +{ "217500", "9539ac7cca0ca0524060e3fb6ee956d28ba115c7ae3f54d5927492d0a43eb49d", "21f680a60447675216989ea718c68c63361fab5615c683a7f047960d50ff8873", "05692be96ac1ea5432427408a51b86eac351cca847b10c46a7181fb2c46723d8"}, +{ "218000", "dd15ae9a3a001651303c757cdfa162b252b9aea2d1c4fcac645cfbc1d7dcbd7f", "78cd6e280ca819c264e6447e6cb93c616f0bd03547259a0f23ae38234e907dbd", "2516f646e05b15c638a1ff0ba0fbd35701cf22f4c2518d18f8791ecc77375632"}, +{ "218500", "6455bdb4441ac37e8f0d04b645fc033010698430944a873c2c097f7c0d3a02bf", "466f4eda729538e0604472f6c00c4f7398a28c9e59c89602716f611ed8731edc", "6e8ab1cd2afe546d81758f4dfd19312cf676fe1e7efe7423c127068f4f91a808"}, +{ "219000", "a8944486d2a12285430d1764ccfa03bfed013dbff38ff5fada97148b883db9f3", "5e8d4e1d9d6b8bcfdb3ca94ef5d0f8c75b9620b7bb5f360d8172e1becad9353e", "a1fca9e49edb1754773ebfdf2dec492f9d49d619d4d39f7591f7b8c0aeeefd48"}, +{ "219500", "adad89636c4dbae0dc680326d95d5a2bec6ffe7baf704f26889730681328b3e8", "d17aeaafa2e7a17d6aaabe48e88ffc53a8e61bca58de2e844fade3461f4931e1", "8fd8c2a561a09d2a686ec49ed898b43d4bae8383d938b2f7191d102f3c4109f3"}, +{ "220000", "69fc4cb8e3103151a20add15fcd55a9ee3c1f2cf78ed3bf9ddcd0692b78c2a71", "25cbfeac28f67981d5d011357c01ad82e097c0d09e77f0746fb11a93329c6958", "fe050048a14dd17565ae650de9a772e04dca5e2c7d53f16369633356b18a886b"}, +{ "220500", "fb7731f8712f081c1e9f446217bc1882d62d3db40bbe2711a25654e2e74c6cb0", "796240f85e38b57a751b19d648938d9f8f66cc8cd2e8611635832cec8d25179c", "b360d59819b84f71e3867a35356907474f67539eb4d1ec02911ef16bef70ec91"}, +{ "221000", "488df413aeead90e34c182fe75cd71227be759865df577cc6a4508cda9f13213", "bce1bde7cca72a43d9d80b03ea33c845799313914905c7800f7672654821a7a5", "3ce3b65c898cdac02127d69d28d38164fb235730ae6373487a6dfd3fd3b1a3c8"}, +{ "221500", "84d958c341c484ca8e85984cbdf5ea436fc1564c95baac52ec00e9f03d5dda3c", "c493d1eeb83f8dad5c17eec83e69277fc98e519c639d3c892faee2d6f80a5fe7", "e88c0947ba38c03fcd4661c33c9e2ffa10ada3a77746c6d28d99adcdf093ec46"}, +{ "222000", "24f8be00386b9a38f5507e77e72cea34598910fb8aeb57c5d7fd5b8b082b1d16", "77d77f3bc606ba0a8ac17dacf2d6d794bf655c58709a5e6affb1c2238149fe94", "9190732d87bb2140d12e5ccc17025a725480f5192563b58bb78993a5dc071631"}, +{ "222500", "c9db027d5a71c17a32dfd7694775edd913f829900532a36cc673168de4b41cd1", "c98ee6b634235506cd78e47c3c51ff7f20e2da5be5bc51c9269e0585a77f344a", "bc2e01c66f5e16c5166f33d813153626b5e29d2f72fd135ee38002638585302b"}, +{ "223000", "2491331dde706d72557719b2d51300a41185e0a231600a748cadf6d76cb97be2", "f464bf83372078d78b37b0aab9e98a697eb07bca9eb62d65919635d9a62c29f6", "16b0949606f4d837cf58811261026d3e7a014f716ce4b8775e94808c33fcb1a5"}, +{ "223500", "757897eb0ef5db6fac3a16b4167e73ac300fdf2126d175ddbfab527fe72e5cc6", "8033074e1db6b73e123b62aebd8983887d50385f70770bec207b628e9c945425", "ff9e7cd3fdafc513b0522c21678c4b6334872dd9c0487fdbbac6d8bd11b3e516"}, +{ "224000", "b07c519e796e7ca9ecf620e6437128ea8762b00f16ffb3f2ee2abd5973fc3b21", "eb8135fbce4a5f3d73713eb67416be84d02239e85bf87dccd22763075438c693", "ed89408882869163baecf310923d4ab5bb880d85741bfb2b4ce322c6b049bae8"}, +{ "224500", "4a873566e5cb9ef793cee37c09f7bc11668091934776eaf0cc5254cf8f565ebc", "9484bb580ed6e25fec7482b2f708ee463088b54ee3bf3a06ffe06a1892e70360", "ba459cb6f5e554cbff0c1fb05d217e2b67c53583b6ceb3f91f0885ed76af94d1"}, +{ "225000", "b4b671d3954ba70856a978c8c173096a9db7ba168c8815730cb445ed0b921f7c", "b16288a5f727839ad38a64139741eba8f93f33035d294365e841e714927ce5d6", "0a54bbd14b732d0e359a9d335dab210d8fe841f5f60246a688ea574a19b171cb"}, +{ "225500", "17279999d391f86406797119b105c9f5f6a02678f7c3d34d9f272c73dd77faf8", "d555247b00f10b1b9825a09d2692d22129b967e1ff244d1a60a756e7b2d9cefe", "d5fa227b78fcc9305f36c7e8ea6cf1c3f8af9cb61a697b5ec0658d2fea876edf"}, +{ "226000", "94d997cdf120719be0ea6a4eb198704a18baebdf13f65e28e51b49df7de1d861", "d3d5f6655db1fa41b2f916399ed5f36246ad98025f6943480fe15e43b0a8a034", "c5144eb0548d037485fff77b1bf83cb11fcae1177d23d5883c4b711ba0a6419f"}, +{ "226500", "dd41f722e300bee85cd30450c9fd08c3d4102b1095f88617c10b100556c5da49", "f43f89d4fabd9330fee3336ad9bf701601c33aad3abdd56eb6c164c21da1ff10", "28f53fc862f547a8ac2ba68d6dcd67af9c55ee7f78cff9da296f327da4ac711c"}, +{ "227000", "a0e48510962ea5a5f18c8d413b48688843e5cb36b8b74b5e61bf357b43334ec3", "0fcdb763c6a77599a872c5baa6fd1ddd761889eca1c53e882b616dbe40de391b", "ee39eb0234440a966c8d7908596539d233186b96d16cbfe4ba353d3c488fb68b"}, +{ "227500", "7f5337c81192ee64e2e1fd4da832f60ba2d89b0336e8e169423dd403d6f76a7d", "fdebb66099af9283e9c026e1e9a112a66af6e3bb0f657ef78392a9dad4768963", "1b8d657321389d19914e8807820f47f412ff10598ae38cc6968db8f07e897cfd"}, +{ "228000", "a8779b9ce01000a531f400c46d8930c487ad00315f0ec4ee8acfcbbd02ec9e7a", "e9b6fdc4d73e7910e18d95bf096bd5becac7b96a9989d60e564f1ac2480b1fcd", "ed4a46642d2b08d633609ef1e2b606235fabc7b6edde6ddd1b7efba80e24ba7f"}, +{ "228500", "074c0079bec868361a58eae22d107577538fcfcd531bd3b0516becef48d25083", "b0bb15325aa285bc0890e24b0892efb113246e6d785554e59022c0917ee4c35f", "6b0fd05325b08bc3e76624c3965df9639e65cd6a09836311d36ac958421a4b29"}, +{ "229000", "27c38d7adc92ec6c3b2e5c16ddea6cc06d25cf138ebd45a935953a357143cc68", "f916d1f8fef52c7532988bb984eea0f136d7c777fdbab72ca0011b4535c91e46", "f91af3f0774116fcdf41eb53e3daf292b151d5ca659b06138bce03949d7d0882"}, +{ "229500", "1010ad9db0dbaf647e510b73feb8352b927c1170dd09dfa15fa0f5b9735852fb", "7a7b2eb60a9dab15faf8e37370dfcbb6684a67faaf7ec1f50980694c26dc558f", "f2b26bdca9c6481cc63717041a580e912d81a566798355274a8c0fd318174bf1"}, +{ "230000", "e84c9aa480b0a7900f557d49afdc6273171bfea6e6adee45c3c2c7408c7a172b", "1f03b2bfbe709d7b411679979aaaf2eccfbf14b2a08aecb7139b191691acf77b", "d8a6802d515be3e56d7a00368b1b2621235aa970d5bd42bbe3bbc52610a88dfa"}, +{ "230500", "1cab5352d167b21bf28c9b3b0f8cc821eda60b32ce9f2f77de5737edbf28bcda", "8867625cb142e048d056cfcfe5627fb7ac7a20a83de0a9fc008bd4951ed7def7", "88e69682650794237dadf48c525a4ae488acd73f9f312672149a989a5e86d7bb"}, +{ "231000", "a7e7ae0369d5839690ba5cd0f83167cf68e6dc9c5604feddeb986b17cd35ae76", "4f7deab8e1ace7033b726836f01863f33677e4ecf1f8a488fb19b99630fd2176", "7b068f0bf62f019f82ecf753f56febf8161a14d3fd602ba2c1f3b652831a5d00"}, +{ "231500", "3bf6451daa832303c2242f195ad2ee1a205ca168fe132087ff899461f29dadfd", "6b87a643ce4a5cdee1f45ea3ee7fcb9b5df8452209970de76513c846c73ae7aa", "9fd201df310afe19da892c9a5ec244ad5670fef388f54872c972099a71d32de6"}, +{ "232000", "6e1ae43ba56524a6e2bda4d769f8ec8e99620690baed8d8d1764c3a42509af81", "eff179dfdb3a490f2038514a8ca3c65a1ce73c266f808378d767c60d1a8f9b16", "514c7d3a6f929542b5c61c3c2ae5f65273c5fa335c145688344bf30daa47ad12"}, +{ "232500", "95589eb200430bba2e6660842109cfceef9a90889ab8eef7091685dd052037d7", "2b8b93e3ab1fd3b12368ba3dcb7b087d84528932cd4fef51ae863dc40718df55", "3ce34edc74e8c7e402234d169c5ec387e02cd9fe9ca3701b06c1ad2a1c5dc65c"}, +{ "233000", "edef1536377488c20d7836daea81dc7b542347febfdb3b7f0e89ace9a9a2f980", "ef9ee2dc8e6eece115a4fa188288ac21117d58bf45921924db619655394ef4d5", "791945e15a74ac1375df1076c41b37634e1e812d6cefed1e9bf18299b177e1d9"}, +{ "233500", "7cef0816722fc26a5a131003a9df2d08cfb005d752a7211cf52c6c27acb735ae", "dc9115037b26543076cef7cfaa03c2839378b0cfcb8b164f883f2f73cfa95b11", "fc90108555e02fa1ab8434db732d30539708376211e5f2d4c7a751cce2302395"}, +{ "234000", "da363a034d807c2ec1aab013d8695631a0d24c50c34dc0db04286a1a53fd58ad", "ef5a49fea7936d6c151fb533277c19b7e2bb3e88e9351cec946bdce22c5ae5b6", "f2dcc08b2d9b7b39269b00c9a1ea2af3293a51a7b516308c7e8d28b88692b0b9"}, +{ "234500", "e35fd8c71da099b9f3f1d6017c9b799b6f150e553ef827f83f84b4d62ef723cc", "b469f833b3d307d9f12fdfcb7a9777aff2c37a2ccf713d2239275f39ccdac37a", "8b2a09ac35e35fc13ee005a727ef7284948370812e3a2fb1878a7b12e3139b69"}, +{ "235000", "903c98a140b5e8ce72a2571fc17c585544c4076e6d2b2efa8c58b635adcef6db", "5d048227793f68e79facf5538ee5980089562490688dd1f929fbfd459edc3263", "53708603f5ccc4ad229bcd619940e473bfcbe112d8663ee4de727ffc5b812f99"}, +{ "235500", "1e0c48356729ddb9196f9bc8cfff295e2205283e468534eb127eac2a8503612f", "152dff3242d0914c503c8ecdb376d1cec2426abc09cc99907b1f43b31dc197b3", "ba7df23159f8f78ce63125050842c5497c20bf9d746e5985ff964dd329ba29b2"}, +{ "236000", "48c76115fb5c845fb7e9b8d9bcbe2270755b054db11cd6ad6c2ad89152607576", "1420e404d7b541a053200034e94f9bdadd705dbfb57532c2a454b9b17c36cee9", "f38a89aee24a3a08e18b6f5dedb4cd567f646d7ed3aa06fddcfa4129e4983c58"}, +{ "236500", "76dbcbc51593c2ced3dad33d42a9f8c522f01a21383b227b0e6511c76363d782", "f432ef854ed6a03b4809d3ecd8a46def940a0d251d09484ef1b6bcc3271b0f17", "dcf2169bf1b7d2d68d675d63808d7fc41a7b3b8396365a32928a367def6f23c4"}, +{ "237000", "8c821cb30e183a3f5a3b28bff8b16d1606566e3836a2eb0d47f6c02af8d3f324", "b4bd12526051dd6ba2a2d616a95212c8ab4d6adc18ac21822a57738eb8284e2f", "feafff7676658b8dbd88abfc9f266df07564bd279c37ed6d9317c9264224feb5"}, +{ "237500", "ed4f21e0bf654339e17083701448309eff81e272b89e00fdabff166cdf812bbd", "9d03191f41bf9d7bfe65b5cea79e55f32c57765ed5909e11ef961fa56f3f69fa", "d5c2791447c14649d99a71a5f6213bd71efe8ac7d56cdaa7ebab49cac398868a"}, +{ "238000", "5af7f4d9b69ce00a56f5c7d89de2ffb0df0ae23520ff218ab2330ce4817ee326", "509f60bae30c0cb7666f7baf33fedb510f3364abccfd0881671650caceca4cf6", "765f7f7eec11f7f3be4461fa8c07e260ca15d5231f0df4106750101ffe2a4cf8"}, +{ "238500", "e95df9d3b7bae4323a4562627b9926d2a3f4c152e93513f0b57d83ec88ad8868", "9d0e160a8f87e36e9fc815538b27d8636daf94ae5c8701d323995054446ade18", "4bcfd021d9f54456bb843225a6d760252dc8a914aa0b71e7db8bbe57579168f2"}, +{ "239000", "17dd8f7338c85dbdbaf0d87bfa224d5fc13e58aa465cda17eed21ec1e5a13051", "61604321167ce51b0c2043524749d385b40cf729814d88e0394149298e1d612b", "31e49ef282416590d0ccd69ea1dc54cd191a8ad5aeb3d65be56c96262089be3f"}, +{ "239500", "d10a85ecd99d5fa8df9df4aaae9ff7b6360bf0f6c541fa6e1c8d743ba350d1b9", "085caebd6ae46fd58b66481d21579720316fca78552121f9252ff8fd5019257a", "a818e7b156f2b8a6b2b80481fb48ed123e8e037b15dff6d3f8756e4b8ab26866"}, +{ "240000", "dd21b880d234b770079e0478bddfc53646feba611a1858a82be2d68a5f70b5cd", "d0bdb4e68e287851256fe8cd8518ab06b2f8bdc30984ef27feb96cbf2625bd81", "eee895ab9a76886db1159344b4f0274145dfa8d3a875d42aee1df6c4d8c13d4e"}, +{ "240500", "4bb3da166c854ac97920a04fff729b2da619b130b3b257fba10f5be47354faed", "b7081936dea5f45ae555b58ad83d42234183f80123236a1474f1df92b289dbb3", "588912e750fca882ac5651cb56fe42bf2d3b39aa255e291940f2fb7b3477cb73"}, +{ "241000", "cad2acf8c8a9802e5c162170b2cb7112447b1b5bdf3184dfb6ffca5d5ca066f4", "50a13b720476b0d72efe8fedb30d6c24265a0cef374e1de14df89e3488fd3930", "db397f10c56a1c85f49cf2a3ad21119add4671fca5262d41168399675aaceff7"}, +{ "241500", "f89869f168fee009c6b743da990e96a296823c795da2fbece16346aff95cc0d1", "f1e24d47abbd5056f7d3fd322a882ef885585d877ebe23b86787fd8bfda5c03b", "158908caa9be532ba7cee05944c191206d13ae103310523dba267dae8f10759f"}, +{ "242000", "8cd2957d89f5937f87ecdc188f5ad6b275768752b873f36348fffde02bfcc4bc", "9e37495c487f19227aa0b4312458907ff749f668a3cd386d46318281e03497f2", "be9e5bbf9fec786bbe5de797be25ff3350587f8b9f6e2558a7a7ee39444fe74f"}, +{ "242500", "4d84991c165bcd35c6f24e4124e5b93678214af88c683ba82419330162070a43", "dbc9324659ca8a138b7f72edddffa009859cbdfe03dd397da0d897b40eb97efc", "b3769991128809cb16c4692fb4ddbe36638cffbf285b0d2576cfeb5a4f1e40fb"}, +{ "243000", "99f2ae7beed98478d52ce8a3e8106262d777e9220d54159cd29173f823002468", "f1af12a5aa6ba842b39e357a45bcdcf93c9f718992cc160e1849c693211642cd", "19f07cdc4b0a888a48f45c2eb9e9c0b9d7f41b2b20f76184199bb1d5509f298c"}, +{ "243500", "84b668ed1334a0f60f2b7cccd9a1bd05b758fcc1d3b6de13314b60b1ce8dd69c", "a02d27be36d8ff1a07ad35d80e1b2340c042bbfeb7ba7c0f4289eeb8b66ae117", "941e486598b5e0e2ccbc01ccbc2b353c73d9f62b9b65a7a6c19d0e0cd0661a1c"}, +{ "244000", "58ccb25106990e5eef0f7118707b96402f853599ec51917347012350230701ce", "989a5646dc6e9f91b27d9d3f3eee07de2267b5b62ca8c2e0faed6883f1d04e18", "9a1abf9c623f17a54724cd6dcccef464a48945860546783a0249155776ab6b15"}, +{ "244500", "60b50cdbc1be5d94c144f682c62cada4668154d94b909100baa392bd914fabfd", "15fe02c7705d1c3860305d80ae479410c94dbe8ed03f942dde09d3a3094163c5", "feded4a0f87382ea84f1f789e638864fecaeda1c5c16d83352595f9d2bcb68ef"}, +{ "245000", "538eb0feb39a02cb69f673a6707d23f80be40a922ef8fb43ddb1782d8bca83e3", "ca4b24d390ad10642d096a14bcf8fd51d7135681c9a750a80144b107ea02ce1a", "30b1817c8d6bb5d0217d147708649bd75ff6af32a8e17d81c562e17a4c8d0c53"}, +{ "245500", "8e7a40c1deab5dedd03f960399dd0a59ae92ed849f0288ed447307112a4679c4", "fe223451b524113b6d13c696681af1a1004e5be0fcd14dba4edf5d43f1b52894", "e0beb5d5705be0bc851ecffc517fffcccbeb2972a1784750e736219dbb346da4"}, +{ "246000", "e5410e4186cb320449ee28882d9f32cd3eeb79104f807651b8dfa0164ebbef82", "0a4203ec776383111ff8f9ff697c72bd8fe1203d55242790a9cd42086b2f6013", "38987dcd959005aa0638e7caf50d4ebe553edbd892c4854e8ff4a99d0ac90d60"}, +{ "246500", "0c2a1c0920dffa7e8a582bb47b121ac02167b2015deacd3cc2a4151419dd8dde", "1df603f77f223501d3036d16d2201004c712f86aed58cd0b3d89b32fdd1b2032", "4d5324138f4576ee887daa3f45e7b41eeee59b71fef399c69eecfe6170f8cf64"}, +{ "247000", "def0d291743461c8680127c4393f912663ea3e8105026bc76c315de3f7471a17", "830d9dfbf53d41d49c1a28631361db55fee2284001c16395ed3046f9a9278212", "5944d9c5fac27c3034bc271b35c16247ff7dd0a7b5fcb49a6079b4feff366942"}, +{ "247500", "41c85aad59b4ed9baa25743ed3b2205550292eb7e5e4dac974f0839053d0df75", "dbeb22eb94053b3bda3520ea239bf64c51d046da08951074dabeb73b06cce009", "2da981e79aa5ee1fbc27622b35ef4bb96249ba35ee4d219e7222a7bf489127c0"}, +{ "248000", "e34f803c19b9214d128703d584947a348459dcb0191cfd0a3928447747b7e3cf", "e58a6b50690ab0de2e1d7e5eaac39e60495e7f15c0e494797c49ff0a83e80d6f", "f139662f345cef60380f9b3e62c4923ebd53a286497e8f90ced8a3a03e948f8a"}, +{ "248500", "779f30864bc7a0eff2ff65a65af9ef49ed7125f708e923cff6a7a88d661c1688", "34ac76a53fca6d0daada5f7f12e339fddf5d654bc1ebe03267716822cbbd0514", "a0c941f4b2e5089e371c04426d84a1081972e00f6556b40ec401c4b02a66030e"}, +{ "249000", "46d582e130542ed696e49a52224757fbadbf61037d15182cbaee9d6895261d72", "7487aaf55ca988670dec71cb5386b80d8975446ba57feecaf64b3cc9c52a18e2", "178e37d57ce7da4f4b1925117cc97773475e24282737d91eacd043cf274266cc"}, +{ "249500", "87fdc18e9972ab01bd0f1c0314fe017d5b825b2a802da4da2be0c495e8a6c2fe", "364509f6a5c984e616212b9a328735397515d8392c612f774a55e8013b80f868", "faec158f0c1bc224e1b7f40a5e0d3c1302574d271e766b45b205c7f2d7da3f6d"}, +{ "250000", "f345e75ffd358b61924b0bf3fcf99156f97c1479a0b31c53713c219a38846b5f", "156b414c9c8d5782e5ff3c541bae9a14641338757b351f8cd7340d91ffe7c8ba", "f9fb2f646c22ff1d61f307af33c1e989499d9007340b70f191485b1a66aba30c"}, +{ "250500", "111446c3129d174c80978898f17b8c14c485a4c92396a8c2b15c76d7da4e4ee3", "67bc454190eebae6062bcfbd41b10f18161d777d0c7f1547d9c922fbe59301e3", "849f8ac1d68557adc798d5a31397749d9eb37ccc33b91d14d91fb0e6af078c02"}, +{ "251000", "a1d9e94171306fd7e28559cfdfc8be43a89ce142208f0b4a4319177bd6e1821c", "bb9e6ac2b06ece214228cab806b96fafd12d7fab5899ad4b8f6c57764c04b65a", "77d968ec31ab7d473525224abf9ff0361b4022ba8a4780cbd9695ca3954af307"}, +{ "251500", "011ed051ea80d7aa8c5631cc3f6c808582b7bae9533a47a1e9336280e244a66d", "5ab6d307a8215f078406e4ef5256e86f30683732743e4e102fca988e3e9bf157", "18c51804cd1c8ba5cb28eb6e3123525123e5eb7ce154a1e3ef1abecff63ab06d"}, +{ "252000", "0f60353af5fa6f614467ac0b793c0cbfb723b48353e45a163384288db9039860", "977d7256cf493f632575935a40240e3cbc08e8b82b9cb78666fdf4e17a80748f", "9b64c6052aea790947c3560f6a8bbf66c9f1e4838ba06cd9a9e65a8e5f7fa997"}, +{ "252500", "856aa75176f71b2613ce0655d8bbefc03739a2ea066d1a396f608d596de9214e", "6edcec572883a3e3e60b10a312a59c1e4486a0c4a73f5726b7b3cd1fa5ad8a8c", "08733b998bfba6bda0e903937f56042b4e19ef839cdcc67b6b052f863d8a422e"}, +{ "253000", "135cd797ea002f028f372b545ba294120d92fc0368996f3f0a4a2c3aff5e2178", "f6f35b4573ebff09a1d86085a7c5ad8f5154bc67cf6f1b821780ce3f39d845c7", "5ffd6a38fb26450294129d892604accf80e1a66cf02c5966a967d846dac8a11c"}, +{ "253500", "7e62b3ed039f164bd4b37eeacc05736f7160fbd8ab2a0ed7c8789817ba43f47d", "92fe7b5cfff4d6c5fa17c317ba47417e2841e65a9a985499f3ed0ebccb05993a", "6d4c21387cf0c1bd29f3c94c024f4f03dcfedb144593562fa918ff26a5d511eb"}, +{ "254000", "413a5fd20a447bae48dd74c04912c73ced49cb866c96a65aa447164084dc3723", "dbdf24cc5fe71f376465115ace1ebbfdb9382c6a47ffeca175f7b1d71d077109", "ae6fc5a32ea4fc5bff43651d04a34112f3cde947601cb41bf297bd907ffbdbaf"}, +{ "254500", "dae6ea70719a1798ef4cd7eea67fb84482f58695bbf68106fb1ffca714532549", "aa0bf86ce61e6a6801a133340c93e099d26f06c45ea6a7d0303866d59720cd45", "846cd8c100d89c35d8e0f031c7c78403170734a71f89b41b599e3204b5bff115"}, +{ "255000", "48686fa37b3f22077cadd219544c1d55015b613ec8c5a4c367b0e32a1d93f114", "8419590a10c931fc7b06e4f0c9cd66add2783839c03872569a4d84100fd3ec7f", "cbdd4929ef4806d80da65fad8800927305d763531614ef9b44009c1c9207fafe"}, +{ "255500", "3480ad9060e55cf444b9f63adf976cc48c8e68e9c5d9f2e173d30ee5e21f8e55", "22d1784cfffac5b2f3587152e60a93c18c3ba34d5872ac90a1bc249b98aa17ab", "fa4403617cb029fad549d6cf18eb128fde5f574647cb7fc0a105d1f6f868938e"}, +{ "256000", "773459b90dc0d860e1caf2eeb99f85410a17adcd86b9c7a91e282d7375f69b87", "dfe7baf5a19c7d41d0be344f1c0648ae6a720b5c9b50d1a1755908da38ca28bb", "ea9dcf13fcc782c2091ec7e84982fd2774e1e436cb2c4d33a3c12ba41fd3160a"}, +{ "256500", "5c5a4002c3f5675ed11fbe0d1640a0cf72150462b9f38f2b6fefa04e2d47e57f", "504eb85fa2d5bd399b16262f3ed52330fd25eff4396ce7ce96604c58c835314d", "e2cfce4f77ced79d5e0a61c0786b810f219329b32f52928bd4bb5192657c0116"}, +{ "257000", "f957080ceb81d1ff1a57fac8d99d89f92332198d332b82ed19f116bb2e4bb232", "2aa6db9a7e207b621656e249da6a29182bb6e77489137f185c4adc4b43c2063b", "95ccc92fe8b6bc201819f99cab1347b864098aa83aa68be978a6e31d19191da3"}, +{ "257500", "124667d3ac4e97b204a238e688229f21aac351bceaee670bc86b048aa25a326f", "0806775e04bc4c3536af5ee7c404d2d53e780775da20c269b0c52258be37dad0", "781b0b767484115002c26e4be6d2e903d49c472e9343e422ddfb3c11698619dd"}, +{ "258000", "281275e81b624913ab150bb6061bfc3d065c3b8e876c1c84c933d1340342804c", "f2a8c5a57fa4b177d510bd095fcdf765e7b4c08d8ded22f12c07e3fe85011df8", "8cb11b3cfeb5f2714c096137da42e4fad410aad3f856f28025b9ed2b261d9a3f"}, +{ "258500", "99b3f45ea656e722d919f59a89e1ef97e171f1422ef68fe6ea17e84496369d31", "4b30ebda14fbb69dc80d6219066b66d8716e2235595125113444f28e2e0e3ee0", "4c7cde3753cfa77c0d82c7d2d292a2f17a82256aadc556c814a029e707274c04"}, +{ "259000", "a3c8b1010cff2df85b748d06b4070653855a780fa89c1fea1df8af1b99e1f71f", "611c731a6c76c22ace3e93b064a4f73f2debf5f63d270a9a3a59a7a46544d6ba", "1cb253f4e69ad610219c674194d9471a78c4128ce6ce918d7830b68081906b87"}, +{ "259500", "6f80b9fc49fe6de69d6ca2ec1a783fb006b73c7e2fc0caac427088dc31d0b527", "d9ddfb40c125b781b7780845a78f6c90c2b887b8c28a0a930ccd6ce7020bfd3a", "ee8cc1c3f98c7f8f083ed4f4de0d6bfab57f3a3bb2b9f688289c66a24827b9db"}, +{ "260000", "d3f3a0df265b13c30fd6d529da8a8628c98144abee10ac66feb2d98972e52f54", "31ada4b62db504d84fed898117105427ae16309d45de494c4a266316f8225d25", "fd7360e574377c4adcb394b707e421e770688a6fe8bc08c3f3bbfe82e78d6182"}, +{ "260500", "10c9f1214c1a77cf5d4097d05a4ecc043d8db4dc9ed855892763104094e4a1f7", "273762c7e60334efe73f1325072dd8829130ace31287493f4028fa9c22c98619", "b82c870a9178e80f581b4f92c6cfa3a78d0729db64312afe731aeb3150504ae7"}, +{ "261000", "bed3ea15e53cd2a4b2f8d515efa665b1552ac7bcdd575048efb6bafa8b3d0f0d", "3fe66c2acc1cef4355c4ae83ecb34597060c44da2aa73f0a51618f4f6956a8e1", "f5b264177952358c8af607060f3f962564d985d79b111f967db973a5f71a933d"}, +{ "261500", "0e9b83d06669715a10a70adbd0a89d58a56a853be8c6b4e6fbd3894fb865c224", "992896ed5c5c7c262850a9d3f7b10ab729de8fc572190e0c08745ca9aa2a5433", "cbd1670a1e8fbc5c785ac30f2586d926bdd2f7991015c2d34257ab8abb55c299"}, +{ "262000", "61022120589859e23c0c4fa1f2650329f44feda0823bd30d597be34ed030c86a", "eec28d8aa336511816f17eb3cbff661e6fb35bdd9cc7a63e9ce830e7dc1261bf", "6cba28cd036be7ffece24c46d9a749b6623cbd7ab6f09e0ec4146e8ecb8d606f"}, +{ "262500", "957872933b3a7c22e527930d65220a77ebf04077130f18703f4d9eb8384edac4", "e267fc444b94c0c3e8312c063746af1e93887e4f9affb11d03d5728885b63cc6", "00b7841dd209bbebc1b00f9f36fcc7306cd43639a782bbc2cee0976a899eb42f"}, +{ "263000", "e06e647a254beaeea41f7d2cf9d88531c5193df8a75d4f1d8df403e1c2a24309", "5aa9aa86564cd18ec3e2dca55315b46958ed92e4ed8710e33ecf3da9b051107f", "1cdf59e22388e040a20293b6b4c72b2589bb5efcc3a0dcc4913bea664a475551"}, +{ "263500", "152388327d812eedfbbaf6f841061eb28be5ed87dc9453402355d8d06c64011a", "23552aaa4ce81d4ada113f198ba4c848defa3870f8093576be677c2e3c92c149", "80bcdeeba034170cfc2c2aa7d93fc60adf78cb65098e7dabc3496f1dce11b4cd"}, +{ "264000", "ce414cd76a86b1af60c778ff9e5b04c31464198d303c9f1d53126cfa930e706a", "2a3acad69f31b7b30208aab2b1bd15695cfaca2d8aa20bb2751afcb5755ac0c6", "49fda7e1acf5e17b38a618fcdd22e97de446ba8d276f3950bc9984b4951c44a4"}, +{ "264500", "d259e8637b4b48b373b6a1a7afcd89b1056e2adda59b819654f393e63ad2653b", "31bbff6e4910bae42fb446c184efe8191dac8d6a86156568daa369230b5198d3", "de1cbb25b85663124fcf585ba74b00c41ea23a87bb6384a515e0a08816ab6b42"}, +{ "265000", "ead49b3a388fe07616d1a8e8c391d50dffa01899a7444df60d4d2c40fd8afaca", "9fa60617a2f080f521628ef3d754f1706c464fb43a8282bd07ce2ed26994be5d", "421c20f2a014b14fe6c5ad01fb72e7469100e4d264bf9fe77258920c9fc35df5"}, +{ "265500", "6bacbbb516631a7922e9a988fcc5e102d6f58601085f09511601f4672a3fe316", "4a5b61cce54e08360b9b2e338f39f45ae427b2cc49034fb0f1e71948a7eb92be", "015b0e44b26ae7e3aaeac859facff0ba812e7ede3df26ff257b3ba515bd04da4"}, +{ "266000", "b6993a4fddf6404fe544fddf2df238c999366b43e7a335b81b4524f9aed32999", "91407232bbaf55fa658262dd6269b1ec6c620eefab326e556434fa1d0d64cd95", "bda05714512e418de85a00f6a90dd00e63f5d0f88fd95f96c02d692a9439c4fd"}, +{ "266500", "a22adcd41d7ee4df6deb8633f53d381e9826dfbc7709e68b7b1ad5d71e8898f6", "314feaaf908e8a8046ab6eba7cbe3c97aa478b2ad93c39aee7df9f5a72955db4", "3cb8a12a98cda65e6dea78e1e5be078c3634bf5b8ab03b3b6ab7b66b30b9fe59"}, +{ "267000", "d270af2ee0a98e7e407e39d50cf4cd22005faa34480d638e7a6b7c10b8d59e4f", "024ad7c62e3a9ab757d4905bba29fccf5ef435e4471fbed49ef50f6f9bd1075b", "8f092d967cb25c5b745c65302fdf334662797e5ae57f62f19c527f5cf05ae1e4"}, +{ "267500", "1fa94c5777a0fb5f2c0b89389d3b537d5d6465bfd432810fc173dfed7a666c36", "b4e5805d093717d9c5d8766b1ccbf2791eb10118c9fb51898f0c49273c3ace31", "7620763c114241b5f75c35dc6675896a50037818e08d594bfe490d6f2656eb09"}, +{ "268000", "ef3af0dbba05b3633b87348bfa9492b90d0c500f8427c2f83e485ddb4e326b7f", "ea130ea23e47338355b0336648892d7c09251bcc9df307a7f587d7a425d2a741", "339197172403a19a3eb4efd95b1e39d141177fa0df817add3b9310dcdce7d715"}, +{ "268500", "f7d6e8a528849da7d14e07869feea84c406697ae7a16ccac0ef890aac5fcf4eb", "489c417d04b8a41f630bca15696e7a05ce36d4d216c04b1a6560db25e03e3cdd", "22291189be339d88d7200e09e4348ee5157cc2637368de6c14d0c902d80cc94c"}, +{ "269000", "0237cc909ecc6a560183034f478c44d9f9fc96d5a0369b89d5f9510676274123", "e84c666b3a8122ccb250bef7b603c2afde722fd985aa36be484e76368f13f10c", "0b2fc53dcc0fb9840bea67516680b5eae925125aa21fa4ffbf5d9c7d9e955e93"}, +{ "269500", "d342e101fa8308700ee1a663fd05b05da014141725d0b3655a3f0fb15da83771", "93daf70fc7af5e7fb37d973246c434cc834a37a1fc69fb522f9ea5b82ed2bb2d", "b144b04a09760b2cb65ac9142ca3ee6a1ba87d505dbfaa34f258f8dea0ad26bf"}, +{ "270000", "83e4f6c8831be3fa7b6b6a0aa13805ae107ebe64f496be123a4ed9711cd69065", "ef10852638bcb24c4341161935a116bf5b764ed34380ee55243a35c938fef7fe", "836224c011a17009dea9d2ce9842cb7d19c1b837eb26f57aabb14a786f198ff2"}, +{ "270500", "557c88f51ceba0d2dcf7bffe8ee8cb308f8fb2f14998db8b6c23764d00d756eb", "ed1e1382a827b3dbee6c583053acc263ef365697a9325d3ab3bb60f80621b66f", "c2da9b6c6ffde7b4040c2d4ef1a06465e07e6220b140b6c04d4e85259af35b16"}, +{ "271000", "8cf965660be26838d4edfc4ee6c9e3f700c5074a0537edf09d19fa8b25f9297f", "f717dc6ecf1404858433dea8353cae36a181baec3c8ab3fb0c8eaf17e76f2f46", "3c1e09a5c48938b029d8232814e48f169f693f208d8d251c3b7d6d78f531a09a"}, +{ "271500", "940439c29f8259ebd1f7a7a76f9cb7c34981795365d06cef15b272ceafddb513", "e013f425e7b9e0c919d3a8a6e584fda18d798f64cd32003c79d1b9acffe92f8b", "8f104372f8900d6abdbea8e173ebe003f60baef8214a067c4c037f0e599612bc"}, +{ "272000", "6aa33a0d087f0a56f911acfa99469611ce6a9fc336e2ef2ede07c854c0ac34aa", "34612581d8665965d653cd9736459b2708141168a297c9eda4c73e64ee4b3511", "d065b6b1de7d2ed8f8190bb76d73f699f56b67f7bac3ba3fffa313b0368eb791"}, +{ "272500", "e165b1f323ea11ebff46a9365e5c15c736a639c87e0e7866a790c212398fab51", "6e2b03ecf9ce016d375afd28e4895a3905c5e79e64a451f4b5863d6f8ad37c15", "54bc63721296bf1f6f2990f9364f8991089b183b646e0ddbca6c1b31451b11fd"}, +{ "273000", "7e8e42c625a39262e7cd8ba81d6042788c5685fb7e1925556bb81d87f23fc9fc", "60337941f27f0191f55253642397b4141c09a3796a2e8c972154c90847a04adc", "f65c9be70852523b31c7a92f95821f306e9017297e04d39cbfc4c8dc3ac0678e"}, +{ "273500", "50d2fab64d92e6bd34396a65ea083c254392b73b806c9c23d10a64fa2046ef63", "def5f3f2d73ebc5c90d4a3e5e8100e51e3144b63d3de0fed9a6393ba3138f62b", "62b9175a2c605119fc599836a2a00fde40a976be16043bf98c0773318e8ad14c"}, +{ "274000", "86afbaf7b386a0a5ca9199f42849ba58e03c52c3e14e4796be5a47bca65c3e56", "9fa018f6e78596557adb6a6294c3ed8c02e5b07835258d38d00714b662cb88ad", "dffa1e76e920169f88dd0892436e3dfb2a3a6daa1ec42287913d5b758ce918e8"}, +{ "274500", "f4a2f13cdd599a02991bab088d21e7d28d907caab124755cda5b5da1a0ac3514", "3e9121bbd05409156a601f33892ebc88a1d832d59180e591e571cb8bb16d0233", "77b22ea80e05caf4ff54cc45a88682693fb8d94f28c18084ec8f8d5774ea4a79"}, +{ "275000", "a655f397a1362429e51239e663aca0a3582f4a984001c6093e48c4e0a2e05941", "c3a045ee8c5239615793c006587052cce7d63cc81c2ecb2af75e67f3c53a8ab2", "380849376c9a323fb3a9bc59969eac627adda0498cc3f60c6c8979be719e29e1"}, +{ "275500", "b3b6e311d0f5bd738f2502c2684af690e0f71c2a4c55afd5661d069e604ef3fa", "0690d029ffaee874f0407d12906116c79bba67f9b8378a31334b25483daadf3f", "a930052ad595d7b8a70e71c48aaffda01d38e459df8e0c1887b07799cca6bc5e"}, +{ "276000", "f24a85fcd91ad6a82056c8a76c2d3d5d04070ffd7d9b84a94ad0d6b8acc0c187", "5c21716aa2a15d63d306717b47e86748fb203faeb1c6b19d63a5349176e9fa06", "50e49772aa15a6a72eb61487d735b18f15f493cb29145911cadc97c1b684bef5"}, +{ "276500", "787f090210f18af487a5a4f9f284f1d3314fafddfdee64723d3237f55d7597b7", "3fafdf028ccf9b4ccc043ab7159a37ec9740b5cb34847a6ef427e117ed86f206", "b1b6faf4dc475c27eca39833e9e90e8608609b31ab38600710c7e3ff30242b19"}, +{ "277000", "b431470e16022c9e3e58e772bc8db6482f309cfb72a197a773b67ee7ffcdb756", "894962f8fdc8091b4f15d60a3ea4de232e7921227ec9092e4674338c6d0907d0", "e5e101d2a2f32a1dc051af8913cb1d611024910988c45848f9b079d9621f45d1"}, +{ "277500", "d4f3d44e493b537d6f5a6e63e315dcf5031240fbe6b6ac65a76eb8c35f5db13d", "fed8c64ebc096321c5b99ff1d5d424c213c3e75d13375645f37dc5aa807eb57d", "bc8767da1df224712512ff57acc5f836153fcf3d33af4a488783c172c9a3a4d5"}, +{ "278000", "4f76c78fc8d544c1e8a0d0429f7dac32c9f0857f906944503c80f58d809d25a4", "eeb4b5d853e4a976e994c9e129bad662bd03d8f2c7e78fe68bdbd47c28480ba2", "caf3543690b2c0033cadcdd0e989231ec6ab6008140bab3d401030009eec98b8"}, +{ "278500", "494b9880d486e1151d466eb73004b3f226ea90b6127a4aef1b3a90edffd4d0ca", "d9b63101013dfd8dac4895a0d5ece4c62702aad7cdb81a6b186e530df840996f", "18fc3d39d5ca9b8910aa153e2e32be9cbe36ba2d0cd789fd94e9676ade8d8be9"}, +{ "279000", "8722865896dd4d2351ef4e4def382a2e622b1e46ad54b3940a16f5073bb1d844", "2ee3816538cef7b1d029887af7e39d60cc1e336036fdbf089439f38cf13ebcef", "0a761847f3ea4261128d81a5b9f6d84c6f443b36e93d8830d6fea779264945eb"}, +{ "279500", "3423afaedb970d2a590a0f3e023906bef4110f1389bdf54e2c4620c36b72a3ef", "3e7446b32ace025408872375b1f3111075f305cc83f615ff2c6133e49ac96d88", "70e66af4ab3048775db66647a98a51d42511441e864a3072111bb46e10c305bd"}, +{ "280000", "9cb8d7f3caee172f2a7b8b8c2bab3fd01326468f8b5932bb88921e06167a0e31", "468c01acf084fd4986b21d1c0e1defef6a874a01b0ec21be66098d53fc4244c7", "6d0f0593c36f3b294d32c15b7e79002e2f15d8781ddf9781e59bf6f868da084c"}, +{ "280500", "6cdf47d170a6a5e57f6a9cfef7f2239d4f15a61d5c37f5b44a72188aeabd541a", "dc58435982155aaba2de5c124a9f441a90a575c9cda3f071fc9c4a3c9db61c8c", "2d49762f68d9f46ae49e6589818814e5fdc346b8e23ee41bae3595ab2a88f7ee"}, +{ "281000", "3228123dd268365939c7fd5d9ea6a151b6a95825ee1a49b9fbf3ab9f3ea45508", "9320e6e8aef527e622e610ab13eddcf82598b3f2b744f6e90727ebbad920c080", "e9a2293b4c692741422e626e36d5a0608e04ae7a39a0d69aac2d95e95c783460"}, +{ "281500", "a35ba852d6be87b2a614ceece176b04152feb39a95e52e641e7da7c1fcfd220a", "547cc277e5a3fe410e5265d8622bf0ce0f722c39c23b3274458f7f99e68f0ef0", "ed34358e2dcd89d40b2b86b619603a413876b29ed1cf8c9407c5817ef8add859"}, +{ "282000", "2533068b9c436719d1eadc4bd7e3e805ebd949d57e75cf5e0b17321d109a9a10", "1ee93f862e7504974feb14b488a590aa9221ebf331beae0786bebbc013278457", "2cbcfcf0cb47425beadf191db745e5664af5d6e8a59a6da8087c260c28a03df3"}, +{ "282500", "47262c1b2c424270254ebc4ad32694e51ff4c09d8c8da9e944b17ca3bc734e1b", "f940a70f96d1369af5b0318ee86f9902bd122036ace273643a8aa0ae7878764a", "b7c219d4d68bd82bc079b6eadb8205c9f3a4f9878dd3fb4e593d6e1ab39b91df"}, +{ "283000", "bbaa0da5024d6e74becb1d0d62b2aa4a8ce1c3bcfe27c587d3c89b581f22b893", "b8f67f07d3e46ae0436cdbe91a4eac1ffd8a8de111cab322c4895423393be210", "d3774c417554f65595146416dc39836999e63d5d4a7b617554d651ad839a6810"}, +{ "283500", "008c22a6e8d0b46e6c785736f6098de9ac43d5d1964b2103ab383498623a53d1", "77b3fa5d6f930d2da8b1171725e9f6e7ac340b88637955083de8a55a0d129b70", "5a762918736f2d6090e47bfc68f71005c8da87518f1a60cd7163c01a7e70d05c"}, +{ "284000", "6273a37ce3e5fe2c58d6b1bbc1f31822f9e1f78e434d62c9aedf2c6c18faddb7", "0e5422505c2be9b93d74f39ddb43b8f2a6cebccdad41d3e631e56a5c075622ea", "f8daf28977a24e392a7550087803586900d30f35b34bca786992c85c89b6c2be"}, +{ "284500", "6dd5efb7d0636ca3212a14ec60bdb9940d355e75c4c3890958c2120c4e0e92e0", "8adad9dc3bad71a55635afc41505883ae38fe99f3c96f021137e049a1b829a55", "bfa9f23723426ae1b670779900fd77b957248dd1005f0677a51329ffd15b6a3c"}, +{ "285000", "7d49941cc51ef16e04919b3dc5c5ec87b62e98267f173202167ee9a359d8a5b8", "d947bdd3999caf548887208f2049fe528335634f5762d6882d4075dbbc6c6b1a", "12d4187421eb70562d96f5a73261abb5c5d75bc8c3fd7baf5e4707ffc76eb470"}, +{ "285500", "c06cb12bcc248f8a0c2e764e2c160d85ca356ba7235faa143eecf42f7ac2f7b8", "7ef16bd0db693d3ebd90f3e9152a8cc1c420a3c57dbb6bf02a86cfb3b1d19dd9", "b30a3f94cff5b1bb3f8a6c7fdb4aecc6a36260b71670214078600b6356aa1127"}, +{ "286000", "45583c3f15ca70ada0a0c38923bf9a7c63a82d7be1a05dd2d3d098fa6040b522", "d497cde577489bcf9ea8e08eec093ae16e80f5c58ea09344c27bf55b98fe3fd9", "7ceb57dc1b782604406fc32b6219e84e88bd52e12e404b2cf064eae6226826e6"}, +{ "286500", "94f13e245e46c93614627914bf086bde72751bbc3f88b35877d73bc28bd4a7b7", "83245d666cc2a32058839f630baf72c0d96977e7aa4fc400f58e75f2f9ecf78f", "6b4d11e78c15ccf29d5162656a219cfc84bba07dddb0af95e7e14051700022d4"}, +{ "287000", "eda15ec5157413f65856008baef31e5d124c511a95716b1f6b7364f5e3b5e75a", "5ac1908f2739c718feb04686b434dfa4e7ddfd5213d9977137354ecfdf5eca28", "ff3f1fb5580aa6c748374c95e371375edd5402d81f092c2f3f7f99ed01050594"}, +{ "287500", "9f7a944ae0a5d2caa33f72042e674d47334445b2f47ac89da38e29357301a060", "b7fca600d7445e8470e57c18e2eadaf73aae7abe888acdfba5d458197ecc1e6e", "929c0c6c37a26aa97b8256619da4a06437cd8d9bbee1fffb21b2f821ba40f626"}, +{ "288000", "0853047a1ac1adb0d95427898e88464c078405fa22ec5def178eb5de7ad31e02", "a3369699142afb6a7da295ca36953c883d67a31d3096d158486b578a6a585fae", "4edf3fac88f835729201fde959ef538f8b9f6201cf20427862755677dda1bd30"}, +{ "288500", "eab408ff9eb88ad56e302df11a2513c1dd7873311632911cfdfce5ad4f814066", "4f39359784cfd3619082b590cfdef0d6978434ad01885e66ea50f2d96abb2674", "4d88e8cfd4f195cdac4908f10c06ec9c7409ace62bb2b765beb593f6db52c99d"}, +{ "289000", "1eacafb1bff01bc0489b29ebc39bf137d040e6641170ce3dd89ff6ba59abf97e", "c8d5fe21e49f66adbcfa0c7d71ddbd5bfd2210554315f1142656f3802fb9de86", "95d1e5142422e26d394a2aaae4e79d7a5e6075b1207540599527e424d3fd9025"}, +{ "289500", "887dd7480f6c7ac0983d66c8af20fde72fd415dc9341eb28e1c017cc0ca046fc", "64cc676cdff6225d910a798088789b311dd78932e090292f289b965e35812bfa", "6a410a3735e9b9d42e2ad8024477d603f11e3bd9a1422ca3392bc99aaee715e2"}, +{ "290000", "d537cc92d4d860c7d1e74c77d63543d1ee28bfccfb33a3798b8fe4ee6aad5fae", "b1422ca72d6adfc0c8ac92b75dd68b19615bf27ce351c07dc461e4a483a01d36", "6e13f50e1bda168ba72506ec99a6481aeeb6c6a4e934b24c57ed41f95c4ce8bd"}, +{ "290500", "1f72a0f641f0e7c0a14ae8aa3a90a93130a302bc82616e7df2eac6cc893f8826", "7cfd6bdf925165f98609e9ac990d9c91cb484a1b0c4f26181f519180b2cd0ad1", "aedfc88bc4fea62174ad9c47b4da51e0bb89cd0d2977932943422d5a4cb51827"}, +{ "291000", "045c570b2414764749905e61329694b5feda76d2656dc07c208e0f163e8d8be6", "ff11ec49560b7c1264cc610daaf95d5bb7f581edf89568fefcc83bbef13b5835", "ee75c4c5048c7b58b1f03fe95b73e6c4deb422b079c13ee331c62054d729c3ce"}, +{ "291500", "fd55aa9e9dcba1752e4c20055a1c9b6ac46a21a3a932f059ee574f49b721f507", "3575b8d9556832ef3d4d929787f0ffcb147cb349499026edc50e4be282b15863", "329c508a52886135ea917a7ac4175d57ba7fc8fa928b6d9d453f10b1d1213637"}, +{ "292000", "37273300cca125ee3ecca17ef0b26cc7880ad9b6caf876a4eb5f248743433519", "9e2e93489d99a34477c9e7e60d7a971b7e7a14f2b1d1af1d797d95c945c26d08", "3aff06b73f04c09346166ee039067088d9f424f3b1ce7c34296e7e5424ea201e"}, +{ "292500", "c6d6356e96458404221b2fde26482fa42559dfd1caab1b600f045d8f6a2302cc", "5fd0c22eecda0a4ec51190a6356fcedb96e3d4662a03d1c231575dca131b801c", "5b5478d4a6d58150d08ba008d03b0eec8e78fc46cc198d43a2d962b0ac19d5dc"}, +{ "293000", "d3cadc149d4b135ec11e9b97cd25d6e1caac6560b16c0d53a798fdc191519682", "e8fb2e323adbb30a6ac4a40239c68d2377e9c8fc2094901d694e0957b9815cb0", "54527162bbf644ad5504de900d11b3393cfb533aac73038b6652a5152ff977de"}, +{ "293500", "a0ebf3b0b17cd3dfce121b5a4466c2a60a9ce0169c79aa070efbab912bc0bdd0", "c9da3ed914a818f8973e44fc8a4d450e68d775dac064b9baed30d71db09323e2", "3115f86a9da7e78d766c7945f8482567b9f9e23e7825e1f3a07c5a39dbb94c40"}, +{ "294000", "492dad282770f45e70bc4cccb1ff2d69568a4d761395515f41d53d0d703db481", "7c090581b9e3e74b2ae80d821555b83a563442f01ec32994b87b8794c8a94dfe", "5e369901a873b8417c9a5f998f055a33bf962f6fe0dc054c4f3e421e23c75d08"}, +{ "294500", "8923473c7806f6175ad2be0cc98c4066e69dd2acf8e7f965fdcefadbcdcbc930", "689e66a64c3f66de762b38b5cb0593b6c0f076c84a04823cb1f927f5d6601c12", "b64cdfd0ce81f7511e0efd94ee32e02252280ffb38612fc41fbb09cfbe65b4bf"}, +{ "295000", "3d5870c04b03d0cfb60c9d47169b81aa5c669fcbfffc602ae51b930391d06f7a", "34ef893941a5215eccb47786b0d108e5150cee56d691cd6d54280afa5ce5e85a", "9a909a02091159a4c6977ee981a8386a935a1b5d6f2bbba1192f675a3a6ec7f2"}, +{ "295500", "96c1ad430e0ca606b9da9929ea3e6644ba7d42c02371abd5d1a1ae099654192b", "8e03c6f39a7dc904f768bb459ba01c623791992208f124c37bc679e61a49fbe5", "65530d71db0ac3f29161ca58977a9a9cf8ee3383924203208a0f85ff60567956"}, +{ "296000", "6407e9c420afe4be97d10102c8cfc0d7f5ebaac40f6d5e678cac8144f007fff0", "d19593e2ea6bc1c13a6a3269bc9d7c6ff918f0a01dcc61daac670b37d2d80347", "f6e6fdccfbd9394a5b8261e3a23f91e9f68a08a442e39ac4d0c7d971dbee8e04"}, +{ "296500", "1f8d31ccc299f2c5b05e93383d8926862fbc09ca5b01085b3a1dd82d5d495d8b", "31fe78d77df28d71d73858589dd74fd5362642fafc9c8d29ba137126bfc0fbc3", "3fea4ab883e22a92a3040592c7202c45fdcf6abb271e0ef2f5bca2c337b6dafe"}, +{ "297000", "9cfe512e43f2cd52ff58f90464a04f076dfd0d12d59cdeb100818f109a9003e4", "5e47ee43df09cc31576cd9b0440c619a16298d39ab9264f639b5b9c86f8af572", "8c0565ebc2d8ba4bea6fb9ff082542adf2656fba21fb1fb9a237ba73c92bd8fc"}, +{ "297500", "95a02da1b06b1593ea08b020b4bafdc67f5e176dde40de7a1feda249571e53ac", "43777410c9686e5c56891eb7eb0c37f2110b339e5eefb75da0bb28b78f3072c9", "90995b05bea1c26dfe6edebf055eac9d8d67d5bb99a25b45a7c70c86ec6b578a"}, +{ "298000", "0d802cbe03a4b85c23624a03bb35290b461d8d9dcffa128de936649b7007f622", "b5b3a839917d03e52ba179edc51c12fe47a6dd9a5c57d678299387299219d164", "dbdf55e36a6b24cc6ee06dc1de48c38df924a62fd30b08e60f01d04e41f625b0"}, +{ "298500", "7e4e639258fe47ffca25a4b7bc7b908cdff41c7e1a737abfd45fdea1ba62ec12", "a8c88f6180fdb40fc4524197c5eb32ab9bfda23b88c4eda4a422994710030d1c", "754859875fbead5f6bc020587b66511c9e853cd9ff27a8940b600584870a4617"}, +{ "299000", "d2980e238042ab1ee113dedd25dd97fde37f474e6ea666efc83ad169c7ac4cb6", "5f89ed52f8866c340657985291ef23e18eb47e0631407dadde650801b632c010", "78ecdb589efc3612834eaf00b8407fe1e5aa47f4b361a358b11fc686246b8266"}, +{ "299500", "a3f56b859e1362c88c4ff21ad8cf5c799c2ae565f46f15bcbd275e7cb0fbef1d", "2a189688c70b29e449f6b3bc93fe61d4b2eef5af756039f90fd745b47bd74403", "977e42fb9f0b3caf99b4caab3ebf3b593771f749c528a8da32d80ba48171d917"}, +{ "300000", "5a2452a4745eaa9cd3c1c42b7e4482193c4f7c3324ef185a4d0a403d2002c0a2", "0276aa15dc1d6f0d96dde0520e357fb5ca4d8469115a894dd76e4a34d79b792d", "f945fad38baa507bf58a84d4fd333200b32de4b3ef2d6f6e872eee58f4e2ebfa"}, +{ "300500", "d02571cc76f7cdccf536b836770aa02a0d238cde89f23f767fde8e62e2648735", "25fc046b62a57b71347be8c33dbe9d201af1efecf98e973b35294f32b745fe25", "b3eb3b176561653fcd519c66bf5cbb766e46270b125d23a8629850293ad8ae46"}, +{ "301000", "b8ef5fe2861b8750589ed344c9d8edc7ebb9630dac0ec507ce09bdd532af32b3", "bdd32f8faa1bebe0c4d250a309d8e983c5444f63b8748eef76470b980c2542c1", "eeca0264e569685a79cdc0cecf89d2cf3dad1571d8be44e511e6ef8c70698744"}, +{ "301500", "573f412e4b6a3a7cd2506df938810bee7029b9af102e096e83861eb3b29647a4", "e8fb5de4c13ef24efd099f7808c0952e287aa23d51a96d37ca919c3fe08b9685", "5b71da4b99e34534688a2189be42fa184431d1c7a65728b60736be85807fb972"}, +{ "302000", "18b4cdc5a75c82496545009007b5f488aaef67892f6886bb36ec2526f02a5501", "c8898b9f003e3a651e963ce212412e35d3d825ad2170cbd1cc56bcb1f7a0c4e4", "c2d335c48e85d4b2b4ce1d1e01016e53cc515e252dbd262a78a970248cb021b3"}, +{ "302500", "ca57a75391cd670c7e1ed0fde565c1c15d67ac4fadddf92549874fefc3a51c74", "08a7221ce567158af54cd9ebb89e6cde68430c185f6ae18f1c4d7001970f0dad", "9052843ea255f0c302eecff974f8d6abc74280a6f283d93b2253fde0a56460e3"}, +{ "303000", "e6dcb8971d8b0e379173bec442b5e465d02e700b30a79598de9be17a5497cb89", "41c38012157119f65a5404f0e62a7656673f033eb64e8cf4275bc81aa4d88805", "96e6876e63aacea65a02d3ff472db7a6cb2a36595f0a964b0e44de222e03768a"}, +{ "303500", "e737b5b4805e4740cc8c50d60ce3769621294b1d20ea8b1bd3f3757c2a37e1b9", "b5aba92d8014d56fa32993c21c908b42330c6ca382631f57162cc63aa1b842a9", "7eb1f7d3e3a4a67f7d206ac431fadbf392a28d05179d9c89bf8670568b265a7a"}, +{ "304000", "9e5aa8da5821d8594bd9ed376f69dc851e5a7e0b4cdd755c6394f0eaf76d0e9d", "225f9b063c89eac0ee1e3136e644cba4f65fbb475fc5a0e2c1fb66270f6f13fe", "57088e40e0af0d94498c02f9a08890126063e2a75340a6c47efb79fcff0a092e"}, +{ "304500", "45a43ebbca6f1cd31a03e301398c2e9e9d15f1bf91db745a7417b4d8f25ac394", "4246e0afd88d5225b8ed8642d8337681f42952d0df01a71aa94d268790755cf5", "10ec6bcf6be4136829f4f735ffa2b6ecf32cf58b509032f99a84f45917a4e002"}, +{ "305000", "153be3e755e4953c3810e08165407725c11fbf92665616c708bd3b824e973cfd", "aa39085be20fd4450a1a03bab45c09f669a0a50d84219505b7077c0bccdde28d", "2c2a42b022dc3f6814ce6df5667be0c2b2b2319c726008f1913f5ead0ce913c4"}, +{ "305500", "c488fbfd55f3fc873ca49d57111f71aaf5a42c4bbdd720c0d96a5dc66eeb6736", "546e53c9ec8cab56e41df87aa26122e2cab4077646b800b63134a712a1e3d543", "18a0bed423ccc6bdd266dc57f917e1e8ce9476f7a4edd39832451d6b5621ef98"}, +{ "306000", "83982570d251358e02e1b359a0d95b96b9f64f3736dd823654d47da633d48708", "6a861e2b1c87c8002bf0794ea718b6be98b4d77ffa95a22a3decf18aa985bb25", "1e58e6045bf77bc6a9d9b0151d0528c50ebdff775080472e225ecb3429351454"}, +{ "306500", "96485ddc1d2d81f38a752fcf1ed3d7b734197c472e8ccfb0eb4ce3101a473394", "068dc5f5f5064a475c7c84960a192433e9bf18098d581f0877066c60ff0a8861", "9f58c14bb3a4c813730ef2a4eaf4606c6d6688519dc2831e17dd9bd30999e353"}, +{ "307000", "0d209df0e3d2879d8a0f356f7d4041d6e0825ed0b33011d5c8db9bb1ec0c7d42", "1f41650a79db8f7bfe188f47b7f1bb293ad4f178ad4cbea99d8f87876b68ce91", "f81ad79a2c76005588bdce6f0067b4c4b646a4ab66ddbbc1b9c9d0c9f0a55483"}, +{ "307500", "aad6c7f578667b9527223b8e4785e9a6739169528d9b0bb741119f224e0125a3", "d56e00856dd907339c3959733761bf3d2ed206bdad2bbf9d49e8ce6cec4be663", "a376a5fce9cea256226a714a82cb0d71e7e1773cace180dee21e8cc96a4cd9e6"}, +{ "308000", "1a02c273d30fd2bdfd3c0391715a78f6223c944db913c846927b8a20289ea527", "232e616645960a14c845a721665ccbffe5a70408ac38dc2f9d53e306c40287e6", "3b07c2f02ba7fc2380635d9940e457db2f4f3cfd0c023e997110c74366698a98"}, +{ "308500", "b5f04f2fd81500e1f7d817b94c566b97c38cddb21041bc5ad38757a1d11c3a74", "5596842f2ec00ea253eb5a0a5565d21e871a511caf4a40f7e559d089ac67ae08", "546d23c82d0cc5671004032e63646240364929fff8f455146650de9ed4bf4283"}, +{ "309000", "ec31bf5b86d611359ba7818f0926b3314c13e7fc6be4771e78aa66c65f308e1b", "19be4c08d59662682dcf27d7cea164915e94d1ff761f8321d6302d7de2bafdc4", "f4f65a7dc7e658ae2336e13df29e9f5897544a9e4524c675df9d990460996c20"}, +{ "309500", "a40c3dc8a06147b339366c16bc1a21d4841ffffb9721f952276c35f6ebb0fc67", "161fbd3c4ba1d443606832471979959ac0281462f897801dfc9e4a48d03df741", "7694e0b93a2b2c3edd6406b8b6ad715c99d62a1c595f925596dfd343ca3c8bad"}, +{ "310000", "10eeededb4d54ad661d257fe3ee8b383d88ea175da4eca06cb0d2afd91d705aa", "82535ab42a3a4494e51e508dcf04f233df0ee6869b14f12c2eeb3de7d0d9bfb0", "4573a6b08dde9b2e032125118082676e73366419cb39e394c47bed550ebea7d8"}, +{ "310500", "5937e9322a0b8b1886bdd639f3fdea48392c3a1f3ce5c729f4300307b30a9858", "463320d4b753e3deae3eaba1c7c0c81de49d883a7205d34efc6f933287bec340", "7c78e6d8f3831d83191c0f757628cc26c5348533681592c0ea35664c8e28512b"}, +{ "311000", "106bcfeebd4f8d313bc06f691e30560fc6d5fd4e8eb2d3aa6e5e553d5d7d6769", "efd1663f7e472207765e064537779ac8b52090326f6afcfbaccbcf0dd5c7cb49", "393147e3a4392a43bae029a6c4ca33678aa619236fc2231d228a60e7ec7bdbfb"}, +{ "311500", "81c0cd746d76874a8add01868bcc5465d7ff0a28ef2ba742b75c6c89986ca3cd", "1e89778081b0b13e825bf16daf61ee16669826b50efc794cf871ea170399ca1f", "52aec7d09759e499a9ac7e6121448a74cd8c268f2f6e541fca8fc6b685bf0755"}, +{ "312000", "bdcec2a9a093b8c5e6a3f712c866bf78e720862b26918e7387d511de18af59e0", "96fb2b8bdf01cf8b391a87158b880f38acdf15a6f761abe2cfbcbee83478566c", "ea915f8312f50abb1f93d4d0548b30b4c4bf908c0716b636f11afda31c278ea2"}, +{ "312500", "a9716ae91f6c1577726c38cc4fddf8a39f1bac41cd1d9b5605e52184e573d6c5", "4fae3413451a71a5f1e4ad71341035c582aa1aa721ded95eaabd734137ddfce8", "64e176102a790cc4816fe4510450bdefb75cfe83407b62fab817b0dde33e73f5"}, +{ "313000", "cfa985aff09b9e7f22b17a600cbc428dc8e2dbb9c2b22420050ed8dd4597963a", "fc3335bb9389d77b4323758d39d7391d4896b94ad440a66b178b9366492fc79c", "617fbebd70243a76bf7ac49007d32f683cde4914c5f322c9ce384201a1e50af5"}, +{ "313500", "959ad500e00153dcd9d8b6a8cf1190c799f69d3c5f6dfdff026a5d78ca5d0c5b", "711b49060d7eee4f08a198fd3fbb3c611915c64cb12c8152210e9c4ffbbe9c0f", "8c77050cdc2e2babcadb760c0c3ae04fdb8c15cf8bd273575a4e6a678d2d1362"}, +{ "314000", "ab6a7acb2629ccba949934209d7dc9cd895eacddcd7143dcd7eda19604ebe05c", "3faeb9f09e3a75ed2247e4e6352c5744e091f5f44792ad20000721198a075c79", "5820cea058fb71cfeaa1e0b97ecec144f54f7645c12a7e3a3601598dbd49af82"}, +{ "314500", "d9527af7b2e46e049c738a9d40f7720d8ac2e8e94b847cb8884d922ed004f543", "03476229cf97cd0f2813169fab1ac07b9648a4dd86ea864feead69fa34dc498d", "1367767bf0f13399e7fcf36703fda084a2e84a058bc7c792ed0e939863c67a27"}, +{ "315000", "626c5f923088c9093b00b846a1ee92657bae30a36370f679804743d1decf948b", "d51b5ca87ce3888f7299e3f2c0ab7f3e28afeef234f63337553c972f6e688be2", "c2b5bd34a86888ab91365677eddeb350efdc08ea8e7a0412d1625a1e2a2c68b0"}, +{ "315500", "2446c74456b4b4b216b760d567abed176c12c2f474459d6be711490190904e07", "23a8dd7d4d710ef6a23aada5e4fb960bcaff7873416c6b9904e1cf61c2abb0d9", "682141b8f01b129962a351be4f513c57b5b9e6cc731af7d5e8a4c2ecefde252f"}, +{ "316000", "32e55b2ff3cae917e3248bfdf7ebf79cdeb323cacb54348bfdd0b1f411c92186", "ed4b4d67a3f55e5e3247f48d32ff231d24ef6970f8223e255c2870aa2ddfc92e", "99c2dbb31a927d7fc58e2469d9d6696275008c8fd7ce8c4b7a763d451b262e5b"}, +{ "316500", "634fd61f515e6ab677e142e73668fe41e462f25351383262b369e1a622bb9784", "0f6cfcbdc1408b6bc3cf64c897fb67126affe7e82ac682707d90894d0c6768ed", "907b1ad13b42c90eafc0f367ee58f72687e8e9206dacf4b7363cf224be8f0b2e"}, +{ "317000", "1a8b1bfb7cf59f0ea1d7141f2859a289b1cc0cc312836f5754121000a5a08dae", "189e9b6ec139450bdf78eb6e37a63c60a13551e1b9d0ab737051cd5dc29dc445", "d6c457a968c9fdf545c1e3bedb35878c5625e78020149a213ee94cbe27906664"}, +{ "317500", "d2d2e1c03ca763382245658d9e13d60db1c11199930c6edffa504cea704e9cb4", "5ecf2ae923e1b0ad4bb52dda4d3c5b6ab31dae5a1152f40688992ac56cf7c1e7", "25ece3bcea84121fff756ce85ee8587c1afe2677fc24b9fb351594beb49e890f"}, +{ "318000", "14c481ed71e0265d9971041215ffa9d80bd9ae3d8a20bdd514b3cb15e6d820bb", "b83d25bc14861317c60d2a38c2cebc995004a3164e49dc4109d195ce719165a3", "b90c053847352df09121fdbea59b636a257c21b6230089ebaf9cbb7df6f4b0c3"}, +{ "318500", "fb1bdbe68f6fa03555a52cc7c70086b585d1585bad7e7f36bd7849b20bd62d7f", "56c93b2ec1e226511dc23b53e7c6992905a4c4875ee9146558712faf39024595", "f69310ba42600ab030dd00a61fc4614bc7ee33c8b0b4a7b3c739c81cab9ee01c"}, +{ "319000", "3d520676419671efd72eb59b19a912dd30419f5d50f9dcdc3faa15797e8b78ee", "f0cb1c494644102763b745ed186810fd2fd2443abbf4c8ef02dd42e20e344e35", "e38b3874c6a10de03ff946f37ea26ca61047c7b3eb133af49941a968e8f84535"}, +{ "319500", "e6f93385e77b36b8bd02e95a7be1daf93e43c2c15df61ad7a53cdf76581c93e7", "8679904d6abde60c2f8b0628024a00f1357357852ea5e0085a8557cd55a3d5b5", "fb8bc1b7eeeb5277f551dcddf5937bec026ff0d1e4007aaf3aa31f2c531166fc"}, +{ "320000", "edbd0041bf7c7fe4378c089724a0dc3d91bcff7efae1aa5a5e9b1d914d9f4255", "83d2528f44d5537305cd76560b0fe1da24549b295e84a37ebc9f7e442f59a2d6", "f73ddd2faab0d9f48a5847489d5ee6be324d47c39797d98b05acad0368063fd2"}, +{ "320500", "fe6af92a7429dc15ded665d91c0280feddee060e7a12cea78ab54f591a2a97c8", "3840d83015f1c9053f2a74305ec9aaa4ab9c8fca66c62b71c898c0d8e40f94a4", "a5b40bbe9947a9a6dde0556b09fe2861d8cb80ca2389995690c1a4a3f9ca121e"}, +{ "321000", "09fbf5bf7f04579822b0643da9de72f9ffb4e3b086334876dd7ebd4a0b1e5456", "3d01cbb877ed01843faf98fb687aedfdd63b6eef204d7a08e5177e93b6315237", "29a612c741f988fc0a2eee429ced3d48018b415ad9be263b05f46846833a89aa"}, +{ "321500", "79143aebef47a364850164688450127d503fb0b5fbbf6b3ff422a655973699da", "b65e2511ade0cf401a38d1089a5ee4a0747e003fdc2c29cd48e47b288d776801", "56d1c182d92b89acbd68757169ff8935bbf5544a916634b280965929168b37b6"}, +{ "322000", "03aa6946623b9252193d58e6dd00bf586ad4f57dc8fa04dee924b5c15d08d8ba", "378b057486d0bcb43313d5206b5e08eeb06be740ceb84456f5cf8549e46157c6", "bd11e7da95ef2ae8209685205c82a739873bf894bee4e50d6dae7c6b81772cf2"}, +{ "322500", "cf8971a02d54a830b3729fb8f1d1c283135b1a7e30d5cfffb4462a2472467d66", "233e6d4bb154d5d3fb1739a4e90a258f0910ceab33eaad183fd2108d8ed464d5", "7fbe3ed0761dc6172430d30f139157c8b898502f1634307e4f3f08d49f9be590"}, +{ "323000", "8d6c05ddfebc0476b7ea506c6edd8b1e7a1f04f46d3d44c404936fd8c8c97089", "c8e2bb9126149c636285107b6b51a2ea4dfae6a9362ea82e9a01fc5b62317e13", "5ad60ef0abc2a5ecac539d9f11d0c77c0cdefabdab5a9b5a4f839ff5d4986002"}, +{ "323500", "f92d520784eb12d8ae3c11ad1803d5dd95a497c0084c88784702a5acce66ae41", "81e2f522cc756b27794e1472df684a598aa925938ee87027d455dada0d2835e4", "c0a590351ad91977c743641c25a96711de72eb7afcae92068bec7d39044db470"}, +{ "324000", "4d33cb6af695638f89500645f741981a2b96eb2b6f1361cf4915e9df14639412", "0d5d58a71b6fb721127f551a4744091aaafc4740ce74e1e094783488946bf46b", "95d0d5cff5e6ec05e646c3afb0267b14cf1455be7cc94c7b2b99caefb333a913"}, +{ "324500", "9cd5a93ac51080a0a3dfa6e7612adebfd307a7c2ea510d033368490c6d25b7be", "046e088e42fe85a8f29cf0c61d1d7c57619c29f3a5574cb7284374151fc02f75", "ba026961f26ad93bf8a1bd29ed0fd9c00d3b8d20bffedde3c7656344ea5e7686"}, +{ "325000", "ea1bd97d2e59f6bddba189466ffe1e7be63f5574f110d5b87ec3e0294b2bfe5e", "c4d8725f512f352599b2a7506b3c52e78012eded7fa5f6bfd99058046342b2a6", "2806e0b32c301fc7e7b517ae6f3499179296a2a56e71256b70a68f44a6c18b41"}, +{ "325500", "df8156f044118b84c3e2482e346c5639a19b2f1583944286cb9550931c3ca0f2", "4310bc5bfec110e5da8fe1dc798b18d1b1453895c70554fb4d52dd7d6d7d813e", "0121cceb434fb22a7fe131aa8e3cccddaed1db6365159c2a4540a3e82bf89af8"}, +{ "326000", "d46ca9a4ec0e9126c9b570d00f7b47a005d51f25d9fcbf0c4ca71a29a5f255e6", "426c81fa951ff0ceab76207fe576bad3be2279d802d5b95b45881c73827a1241", "aa8d073b426c4a1f76a7fe65b5f70ef93a2257a4d8736432f524e67f5845848d"}, +{ "326500", "603728e060b7c7cfa603aebb548a3362364f3ebd83b07742458a412777ba9259", "16fea467df6f746c0a430e00b12d568c7103829328a2bc9b57fcb55c74a66bb5", "d919599180ec29d9c60387ae68bcba2f0c88c9ebe8876d351ece0fe6189f0753"}, +{ "327000", "6913cd3da36dbaf5c6d407da68f46bcdabeb504269ea70c0cdc219590355796e", "745d85006082600149a72c38c32e2d378917153b7c8dbade476f6ba32726c893", "f30e90e6104c58c79bc5edea2d7739d2a788669f2c969f8cdb1fdd6116137d07"}, +{ "327500", "b6538b2705612808867fe5d1da0fb00b6257c3a4314d327b0c6403facc8c06fe", "bf9d4d5ad9f15c14615c36f8cc7ae29defe64971c5824f95aa535c1bba7083e9", "839b723581c717d4cb889d7e14505634ab4480dea58abb53b34bc47c6975c5b0"}, +{ "328000", "ff013ae3b0bf04df355f954637c6ca2510479c51180977a99af805bcc8c2d63a", "fad93d54a8cd267fd2e63abf1da6b26f2f9bc1febac401d4731af0103b31fc6e", "88fc2b74015e76da36ff1ce8cbfe4c3b23d7c0243c9295cdbb451364fdef1254"}, +{ "328500", "ab64d04f26e2164824afa50c1b5592c172469531a20f35a38181993a087a5cfb", "24d35a5eb7accd3545888e4c525742d90b01981447d1c2969ca744181e4d6b70", "a030745dfc07980d9daf81655a705a35c78ddb6594937b505784fa1528a79a6c"}, +{ "329000", "79384d9bb22811755a4bad2ca7d238243ad975b956019cca645144215ead0547", "295fe151911572801c0d4e1ee4e753852edbf6078d7bd798dc5e2da10692e7a8", "51f963e7c2e27a31dccdfa70eb948778488463162943bd74217df26ed9ede3d3"}, +{ "329500", "1839ba9cdb5db971f72defa707c006ef6ebeb93dfff2bf36ce873acd327531f9", "a930915c8a7d58ab4774dffb87fa36a6f9b513b466bd73e5c96965f85ec3300c", "7f1a0fd540c40140bd7f5d626f51ce2998064e9809c43719d309e35e1ff0dd4b"}, +{ "330000", "829b9c203a0c146c2794aa0ac22bc71033ddd15a68959064526afc2722febf94", "e09093eed9d282fce0825778bd7d2c9415fa5b9adcfd2263e7137537d861d29b", "ac77c200bec1912410ba921f77e306f6a09e4652d31514625ac78dc00bc71c33"}, +{ "330500", "740e9f27889b06a301e355ef7dee62cf10dcda17d4023c157c55327420b308f3", "a298a8255a0b30782c5d968988514e0437f4cb34a0a2f7df8475a18809007d1e", "9722342e209584cb9eef0f5f5c57ff8545dad281d39e9bef7b4c0eebbd3cd3df"}, +{ "331000", "e2a4cc3a53ac8a24ac52f6fc574d0e9fed0d240710de0694ed5656abfbcbec46", "74e67ad885d1f874c4ae7453085f29d254c684ebc71eca3af50f3278c9e1c266", "43828e2a6cfa59da76a3aead5ae91068ec8031c348826bf11846316f3c475fa2"}, +{ "331500", "afdc42adb73a6717f48e35b3b51bb13dc6233645b8a4805723dd771062dfcbdd", "a3988534eac8b2c3f5d557d1277440783c624597b8b922df33b6fa38b824fc33", "f6269385ecd144edc5dd3527e373daf61488aef4dfde18101b014e58ea3aa39d"}, +{ "332000", "4812ec71190df534e5d8d4965492cabc3606e51c11e4f9181c470a779926dd7b", "3d1fb3699e9f859472fd032915cab01de53232e123b1e4c93db2871f7c2aff6b", "adfbf39fde89189f36229f39dd7cd13fad00b9486a0d706ab9c19d4534e2c17f"}, +{ "332500", "50ae97dd398c25069522d5eb3b45a2332fd045f6be4d615c7d36c7ccf54c6c18", "0bb46697d721417a2217fb4e632513d2ff82f34287bbdd732b9e2f893ac10df3", "298e9c841af61baf161808fe5ff29c268490906feb3a7897d3d433d1d369e558"}, +{ "333000", "fdd8f58aece53dd4f24881f1007cbd0ed25d9f3c62f356a00dc92aa68a13539a", "e0ed76c2c22a2e784c8a689e1032cf00b65a2702f2b3f025c78e2d1e5190070c", "842641e07f071ed697b5689501d8455969c977fb6327ec31523e8c600db51fb9"}, +{ "333500", "5ea2791919a4000f9e363e277b7522fd9ebc9c06ee5fd9dc15e4ca8984a2d8d2", "69d3bcbe827a926dca144c589eaa175f16b6e523b487773b93fee7b45a5a60c1", "7fc573e06ccca42108fc016d4c9ee7d0bcd607245fa871470f4b034330b5b71e"}, +{ "334000", "cac1a3b80353133e863014d138b408202c77a5759cfc5642546416d73f66ed84", "9005b02c03c93c41c6c78357f4323a3234bf12db1eaf36e81c1077a324f7a07e", "2ff0b8561b95225125133dc2aa1dfa52c4e816a4fe8347b84e63ef6d3167f25b"}, +{ "334500", "50861ba6d952e1f0fe4dac891ff4339ac5fb7094205767f2d6233941d2821c10", "f77408c3140c620c63f8bedefb370397dab67077b4168c628d787d5b22419aa4", "d55baf24587b88808b8e35834c74869f9d3ad0ffdfb0d1da607a0f8fd8214c84"}, +{ "335000", "594b37798c188fab76d6d65c058115b58757893ec32173b45bfc618e8c857fa8", "fe50dd76cb7dbe52cc6a9f6c25a3497dc5e4d141e59ce1bafed04367fb155b3f", "61b2a970de4379841279c59bcbc2ce67ae76fae42d5e5ef2dae197bdd48f07ff"}, +{ "335500", "69b0bd40b74e7fd15be354b734717bf197f1800bec85120b26ca21ea5ac0255c", "58cf057f1edd07227964239e7d220b4a6bae95793694841f7a06479c5e5f7420", "413fc049ef2299a39d19574d01cc36c85a63d99bff587482e26374b461080fdb"}, +{ "336000", "71631092dff7d8d09d44bbf35c187c7cb5521c7a5eddb1422f790e52107b6797", "e3bbb2e549a6c857855772ad5317902ce52231c464fa78a107811c8381629a49", "5ca7df0ba49c0bb880a55258a53d084950bf0cbb4259987f0920e1dec015f247"}, +{ "336500", "ec3497d60fb7d85cfb349bd96712903aaf8a86e6d746f8187a54a1aa5b7b3d51", "dc276fdf1858b7a7600213f9b06d4377dc53ef54e112efc864006d28c6cba3ff", "5c9a0b41ab2b10fc7c757be7c2977e61bd48f4dbe79619d6f1656ff0a81278a6"}, +{ "337000", "70b67fe1ffc39b65d7c3834439efd501fcb9e5d31202322a878be2cb78f741ff", "b91daa38e81b0b79bbd48c50f9d5ef92cd965e729b075e10b270e29effadcc3f", "6c505bfd33c714e5bc7702ae3ad169ea244b89bd0e5becd96f0d0284c28cc07e"}, +{ "337500", "c5df2f17757c5cf77fc421904662468bf003326049de85bec43003d97a5fc47d", "29d4cbe540e3ac54271d12308edae379b59365521ee2f09a6585a82a046d7550", "fb7918c3fc90af8f8c951c5c1c4bb29ae06a1b57a35e7a597a31e8636b59d5c8"}, +{ "338000", "60ba652d7ad31c96015323efbe454694c5ec72dd732c8f4578ec2f5d072afbf2", "2e3a1bbd3ea4e0f318830e43b20d53162ab6b6fbd2191524725965c549360550", "f9495fdaa8cabfd460b7f8ab9ba36870eee6d2a0f3bad67fdb52e79a7dd9532e"}, +{ "338500", "c898aa2617812d17eaa3f8ee142c3018fe2807862ba6d06f309b3344e7d799ad", "6bdee06900bdd6c83f8fd8538d75af113af8893ff99cf9a25de6842d3f0d9889", "25a5a722cf5bf7d4ee4aff66a6294274f598602717a0ecefc0be192633c053b1"}, +{ "339000", "e0d97756042e78b1c14495a68291e5033c39c56f37a48adaccaf350b12f59202", "913f62e783258b88638a7c42b2f403328b683f8c657520ab723ce2196af69666", "bd0caf46efb2dcb6e26d920ff6794cf3a77b592a7a33903efa6e2108cc6b8a86"}, +{ "339500", "1dbe406aeef28cf78b7d43eed5fcdd8c9d7d6d11363cb7e595d7bc1d1899140c", "8cee4f37f98fc3da1826dbb96aa525a49fb1fa6db5b2bd64dd3bbd4fb7d6c238", "450abb3653fc86852646e95572ca4653c1050de7eedfdf3fbc219fa400c52342"}, +{ "340000", "99ed171ddc0aafa8a5b6f9e5890822c34f6ddf4bf63f1488afde10526c74c8b2", "ffe05de29a9901370e815a782c7478c3075f8444ff473b20ff5a2ab311a63022", "abca9c6b29a08f99c78109f92296e105ea18e208af03ffbb7ed827393f634603"}, +{ "340500", "92da105d515c1952ffbdcb5f5b99acaa565500d8f4b6e45aa093b61ae53fb7e0", "852c42d37d42f8d2c740e57b8e9e769e72445f57c8fc9d1f91e62f029d7d985d", "04114d48ae342df3b1994cfa44fe6341345eb49b8d228fa0b77514f00c719fa1"}, +{ "341000", "da401dfe258750911b7264ccee0de1b53bd7b90f63d73f46ad5d5914203b59f6", "84e7b57cabd661c1cfb68407595a6a9607e0dcaf68f74dce2f8487b1f43a6ac4", "e454513ea741faeaab0bbeaaded3ff3244e8e2c8bc53942ef26efa9012ca49b0"}, +{ "341500", "ada69a2ac0977672d08682d195934176caaa7de0baae2f3a32b1391ebf550eb0", "cc1d077aae6a1c18f60c874525182f8cc211cfd0a851381773cd0166c108a43c", "09ef805774a86fd01d17e379b36357093acca1ea6c8ff5c8856e12dbc82b1ad2"}, +{ "342000", "ff83fa02f1e15e52a1e6ab3f8690bd9c4bcc7f3adf77dda003c6871283b695ac", "5983b9dee33342727befc15d5982f9ce987ccee38fef71c34c482c92e062308b", "53699f929f82af192f093ff8b7cabe83778ec64db78584a73f892235a9eb3db6"}, +{ "342500", "cfcf80f28aefa27c6f09f71080e4af7bfb33f94d1c47e80633187f80a806c6cc", "08f62f928db36fa7757f30edd40f93c20dc43c65c693ca5de4c87467d40377a1", "a1b4bd9ea2f7d8b01d7e1a761f09abd0c1c89ac28552fc0f2cb5e4e6666790c1"}, +{ "343000", "55e1b51f72f048231b675c90224571930a59146003b4ddd3e883bcbe4c8c2685", "1f6c53f636480ebaac6569f100e804de9a604dc1bca0a626004ba9852f2fb546", "2caa3fdaae8801ef2aa217390696053529040ce256b839f3f3d26557cb24db62"}, +{ "343500", "3d1f67b0a5d905f15f3fe5a7a07aba456ce3ce41422a3bd94f92fd19ce7960e4", "4201088ace85294f87bf646209d2e9cea09ac2587654d57c8105b016ed3adac4", "06928ab5b470f9bccccb6292549f48341536a3e0a28db92e2d8f17198ccc0557"}, +{ "344000", "1e718e4e82839b50bb5409297dc94bd783264f1bd3da639f2e4b5444c6765025", "c2e0bdb2e293d2940f99295b59d2fd9b57a02632605bc66e4ed69de4e26c4afa", "93c559c784cbe4d7df210f059dda5a5b7ea35df91b63704ad483680bf53eb9dd"}, +{ "344500", "aee9558284286ee6de93a1456fd3cf6c81ff542b4c1eac2c7694b869742572e4", "56b70751d01bc1925f288a0af1223f309b7bac54e1cde463ccc9667ea50c9ddf", "879ad91894bdcaa2250107f95879d7cb97ce26cfa1a0d6c71b91689e41879795"}, +{ "345000", "852cae52d99ea4f4f299f1b5f4a7629ab0d32f8693f503cf74a1f0a31a9a80e2", "a627a26363ae216baf1774585d1159977d378f34b54119670620bb82cc9784d1", "9b6d95864a083bed38bcb6eede6fc4a8e0b6af52db78b9ad59121047a6f95858"}, +{ "345500", "09a3e1f7d56b1662f10470c2497e662495b62065364f40dfefdf8d34f5939fce", "e4d96a1576f516b5303b60dcdded21cb4e3f382f4e7c4b10399ea4b6fc37670d", "d46d62b87b4809283a35462c2841b606094612d2df79b3edbe90042a3d43cd3d"}, +{ "346000", "3dc0fc157c00c40ca92c8125e818f8b5c6163761b0c6955a88eb48498b1d6a45", "6f60e0950cb6f6ad48e5b56e9e94a680ac85109ea90ff94df6ccb58adc44d3a2", "354c3b2393598bc3961d45c2cd2d8600076ee0ad3efaf582fcfd065bc75a6889"}, +{ "346500", "bd5552ed2748d686ed3540c52ec7a0f97b839254c953074357fc019667d69188", "d1707671c71c75edd986ed69fa0d8462f1d7aaea3e0b5cf519972cd3ce7d73a2", "ec6489225bb34ff2c7560d204f2772ec37b862d9b93642faa6089b8e73aad020"}, +{ "347000", "68b383fb101b4ad08a4ab58777b9f3e34c69143bc3872785c281b155de8769f1", "0105724a536021bd7c8fbf2ca7e433c247009c97aa48a8688dc7c9af88018688", "4a329bace708ed6a32c94890216feac9141147f47d53cf0439a22899e97d673e"}, +{ "347500", "af3af4870dfdc980d2bc5c946e773806957c2f5d98200d5e9ace72e4301d0ef9", "20b564b903b75c62b5c7bdb911c753fa67a547a47d47e5a60a0a4790362adb49", "2e447615292fc2aacc273c021ec96b58a9d1856b557f684e531457ff4101cdb9"}, +{ "348000", "e72024ff3d0ee72f4f78b7e63ade7a7ea037da43bfa9deab400f6739fde391c5", "c0ed8b08b6b7d50bf86069b1e8f6c7c36435817114e27745be63db96b5f716bb", "e8f81bcd2b69a03b9eb423336a20bdcf659ae0711c3d765e7ac89931fb25d2b1"}, +{ "348500", "1d9d9ad6a6b1a8d5392aa6d35a7472fbf80535ee334a043025cc3637d9894db9", "101e9ff2c05137c25a2a270055264bfdcc81b290826d968ca94de4038f791790", "a3afe000faf5b427c10820657138d0fe4713b009daad3c797c00c35aa35d2d38"}, +{ "349000", "bf0cadc56a8359bb703738a06f7a31b305fe7433989e7e4094f379511e27a19e", "2a2cfebba2b09215327049cba461b4c56cf54cf31a0d3c6f8b21a637e6a4db5a", "7630b9c11e847b125d2d7879d4e6305401fe6656c5c997c7a521cafaf170a131"}, +{ "349500", "78065cd5e2af5a3a4e838289be5d1460605048c1cf2fd1ef9ba8c88619631e91", "c00a12d97c8a1cdf4cfd4e5185ef06ebf6b6c58aec4cbba2851e47c51ab03089", "2d1790871fad7a3ac8348c2c1272d78f99e71e73ff4d51e4e0f1421815b4cf7b"}, +{ "350000", "937db7a154c0d4c5043fe8bdaa0969670f132252a6c6bf8f7ed5858ee11c97de", "8c276300614c430a75552e0cca7d83834ce7bccd7ea1d592012300ac2bc5bc66", "1fbcff068ae14baf34f3bbce37b16a8cb04bb7d3cb561eff4207b4430d23b8cb"}, +{ "350500", "6ebacc5b6fe9ff0e34d64a047981fd170f1b13d40139073e6e65da9a617fbd18", "f181abacd6038099f96854c2c0ac8f7d19504609f36dd0aa085af150f21ef930", "08c66db3dc00525562741c47770de3332ebe18568d59fd418949a93788b0e785"}, +{ "351000", "156a0053ebf2ee2e68a7ef337edc14044503653188c60669ec924fde43c21ea5", "dd728a51d7f9e8f04e74e2116698305470591a6e7937b2c4b714193843eeb584", "6e541a9fa878ece79546e3659f1a8dee6e9b7a49fbb66073f69e3c7eee9a8339"}, +{ "351500", "5cea6cb5b1b96a2641bcd705ae86c40ce7a8572ff4d6815d7531ebdbca13b958", "fd4148c5b36775f35873746e962941ed43d95db28ef21734f4351f1d8a69d012", "86fe88a8015b6b1c64b729af16e6997820f9d95de1d7eb12e70bbb1d5899109a"}, +{ "352000", "43dc3dcb74fcab2f5e90992eedd8a7719f7b7c7658b2086583ef881092f88aa1", "eac1623de8acd8fd497f9da85f85614f5cd02c69aac6044f24a3685957009f58", "47ad336943ccdc25684fea6e107940073027bbf850fafae7139b612fc94dd123"}, +{ "352500", "6b895134f53c26c0b24e9909472962abb3dba5f8b8ab65693ff8e45b3b77e566", "aa1abff115fc49dbd6847ba4779ee7c514dfdbe3895e7bc3105b74d0fcf1f4e4", "884c7d07fbfb39307f6edd46fa87e83d1afaefbbe3237ec1e89065b70579a0b2"}, +{ "353000", "7785e099822d5b6bac5c707ea57d5d2cabeb52e1e2d82619c8bc2051b486767c", "afcd99c877d144c3253dacf018ca36e61e95761e44f993e0a4cee0854a7030c4", "adcf80e9e4bb78e530cdc25d81ab9c78482397643a136c585a8d10738a62a700"}, +{ "353500", "c0790882442b7ad61aec5a64faa355a8486f8112f9a691208f38e9bc96230492", "f7888632b88cc7800d381774153c34626ff63d859ce489286d9fe904403e9ec0", "e43f0519f71417cb8a09cce20d8559384e86e64ca7a6b8f392b5f545e94afb88"}, +{ "354000", "de0551272a32e89def017385ba1833443c4e2ec02196c33739deb8bac6cdaf25", "78038315c2d8c142ae67a01dfb98009847380ad96cbf6cf700af8693f6260caa", "eddd66351b2cddf490d23278f6afc79315da83bae7dc10084310bb791e7705ec"}, +{ "354500", "c2e4b7243560cd6e4511d175e2c3fe98df223524124f44faabfc252f57d503d7", "1d0fc9a93c812ad30f81462a5ce1fb62d74f14a1672e69dee3a3b797fde53270", "6fd7ff9a6576088f6e6498606fdfed2a629bb8e481fa60ddab26827644df175e"}, +{ "355000", "1a11051121727fbe8bf80391ee403566e3b0dce4ac611b37a516c7e3432aa231", "f363b96bad7663c981865cd98aa36aa2cadf8b4a623a030e3c7e8a58dea81992", "c8168a25c3140673c0275e75090ed811c6e5656bd49e151560df2fc1ae640334"}, +{ "355500", "c877ee5b39b2a7ea9723e1c90b2e307f861e42275c826ecf5b6c84f97c120385", "d7cc21f18f45fcba316afb516f70ae028723a709a1a0ad2994579078aec10ddd", "529fe08e2adc1316c2a0ca6128039d21ceaa68995c754340a769044bf6980a16"}, +{ "356000", "4226d4f7d74316c4f9baf33868b492a72f2a2deabe02b5568ef40606641862be", "a364b4408c45633b64ca685f42f4be377a4b730fd762f28e0015e2ae6e23b0e8", "afe55e92e2c9bb42e4c02a6d0b5a54d98b52b8053e4bdb4bffb954f4f8942dd7"}, +{ "356500", "f0014d06574914b9215379d2b187dcca46081a5fa27d6a32a38efd382a9e945f", "853c10ad51f992a4bf0c46c8471046641edaa972c537c8a92b32cc79ff80b445", "56ddb16e6fbfa6aad2c73a8d5829b67a450b7ab1ae5fed5d75bb860ed939762a"}, +{ "357000", "1c78c05a5a6c50b6d0372745b8a3f0ccbd6c4878e5fe2227c81bf36cbe31fede", "118150dac00bdc45c95b36d35a57c63379205cabc42f8da5d8cac3f8198df0aa", "db8240e2b8713497a22a8f2ac518ab5b029c5747f314e86cd1ad8ff3f1503217"}, +{ "357500", "44900087fce8f2c01a87a2ab15befccc1d9b9e702b17c0184cda90876a07fc86", "621888deca43a1398ce69ef2cb1ea7523e563dd552e173c3af45eb3f00667df0", "82fefcfa3f4acf31f877878c219f83cfc671fe1f80dcf7f763636a73101fa324"}, +{ "358000", "40d642581118288429f0b72a73930470989ff443944b7215edbddf7ad8596d31", "819138d682f96c5be33a73fb51c7b698f347c76086d468a3cec421b5ded9bdef", "07bf777103a5eb60fac5053417011d7d6a9a5a89c8c34bfd0b202ba48dff697e"}, +{ "358500", "39f707f88dda6ce8bc39c64bdad9d1fe29f98b517080ed55466a8a221ee19bcc", "30d012c4929eb3131b7f50c34986d7e1337b46ce6ae7065a0613ba6ad336d2dc", "3fb61fad96e3da7e8b6eb33c884df7ce843d64babebcb7b7926b613a30ecede2"}, +{ "359000", "8a04b19b8f068b14a987511d635cdc70ea66e37b63a5c3750bbf9bb2881439ce", "7d053e5b5d919b21a1ca21dcb5d31126f519c76f8c0d2816555816496229c970", "632f9c544be4365c0cddf8bf92bcb63ce286e7233344413fb313ba2ff586ac0b"}, +{ "359500", "15293eeb7f425f8f041248d3cb15cbedf19eb921389a4425b8a14a30d9f6f08a", "5b47bc2a1eaaf8b83461d28c535cb1b6b376826c9b554df7498216cbfbd5e76b", "8dc135f880bb9401007f1dd5f874c1e3b005bc84fa1454288a7863ee1afdad54"}, +{ "360000", "37577d18f84202e74e17eb9fd38e760dd94096b4623917c8fbe4eb8c1fe727b8", "985b64f248199de5acb5f6dd54aadfe6b2eec0580ac17701e1a6590b46830cab", "70f9a5163ae901c5e23401b39f96a068c1c048b8bdad27586435cf669b63abcb"}, +{ "360500", "2db2b88ab382de78f62fb710454fbe0a9e07dc7c09ba76ef26bf72e4768b8cfd", "a1f4e7d6f52f1fcc610793c0822a6c9a40e0224deb7e56495d34ead537fe2fb5", "47aafb43595d1b250de55f611a94570ba7292572dfc257b0cd5b716faddda2ed"}, +{ "361000", "3891670905fc1e7ca588a4b72a30c57749cb7c9c2ed47907ed3a69c7339caef6", "164eecf5a84889a1ce42accb7ffcae55c4bf598b13720c34eb403fc849dc5801", "087c29e43d9cceae103703acfe3b296cb4c50b1e22aa18c3473b52ff3f8885bd"}, +{ "361500", "ebe6b83861d092f8eff3579515524a45568c743e7df656feb775c45981251891", "ba453dda58aa37da9c4babea1597815a99cc4bfc9aec16fc3f8ba1d85a031574", "cbcc76e776b4170358edba336f2d98c9195adc0d1ba82bd4c7840aa9ff46b5b0"}, +{ "362000", "8524397d4612f5acd6fe921ca9de4e9338e2f74221d4d1755c3682fdbb2bdada", "d9de4ba457b0d1ae37a2dcb9c8d921acf206e96673d45346ff85de620fc08334", "04ec872f96170049e211be83f0f09942fb27a2056b14a9d5bebecd30af615a84"}, +{ "362500", "244d8c96246dd1772efa9b6dedf90ed9933f9a1fef43a5a61fb9d59e9e19645d", "fbd24f0a05dad2f8048794e8f0c48aef1d9419e28e125ead88eb1127bef72ed8", "60c9c9ec0cc6804311d0324aaeab9c743338ad5295fdd80caea2216bd3a81cd9"}, +{ "363000", "2d0854b709d2c4fd84c1d66a736c4148a3b1001fb083f1acb38aa34416063487", "eaaf97d25a09d024b71fb1dbe1935a8cf34bf0d30736df8e9a7b6fcd4fcd63c7", "814a2b982f34b758a145f8d21f44d4518bbfabca32e0bbbce8117530a880622a"}, +{ "363500", "eb76872dee58ba1a3285a93cf5b257a12a903f9f628828bde4dd320ce44ea11e", "2145d5e2136393a6d205af57d6544782db4c701b6a5b3f14a90528f30cded69b", "36fc0b74a6927578a7daa39ab73ee6d90199df057a75599c6bac59cd4ab63f63"}, +{ "364000", "043d7b87efe77f8f2d34833a08544e15838bd8b8e1bcd902d8b1ba9dc30285f9", "71ad76919b65882a929954ac642c401dd8f298faebf7208aa01301815df4f32a", "795babd03501ed1d5f9e5fcfddc1202feff8319e219d468a008d7a16d77dacdb"}, +{ "364500", "10b77b07108cd3c1b5166e51eae74df84f39313508e8093af4fb5a5c8db99c8f", "9738d20593ba72b8e0f80a8c960f343846b639d3b5f3ac623ab7d7d0258e8c61", "a99e4094e7751fc605904406931c76491f4300d52ef5584e3d00eeefa01dc440"}, +{ "365000", "a88f0052b9b490639e238ed8d2bdae3ac573c598eebc036fecfbe8d0d651cb62", "806193a3ff83178e6847129340bc66f087903dc85e8d45d50a3843511625fe4d", "f800f9b0da3e850407de0198d39482c22418ed5e085af6c6bc0492bda6491492"}, +{ "365500", "07674af4f751c8a09011204107b77df887eb0989580ab710bc28f86e1724b972", "a59376d69d1fd2b3601728c2eb2f3f935177f5abec94f9b441a6734b8c9dd57a", "f050c7b58f25bdc732add78f058b17b437f684cda3cdb9697ef1ccc26593b3d2"}, +{ "366000", "e7f0e9b3671c1fd8ac289879d42ff60cb2decb8c9fb8095152e444d183d33d55", "f04e0f59196d771ea62c59ac3882474ecd053519d37899e2ce9bb2d1a779b3d1", "b0c17ab8421de54b13fa25a7be2b623f92fdfc99bf9cff188da8d00ee05776a6"}, +{ "366500", "28fe13630301f2809e429288503e7a341a536de22c078ba11f5056400837d18d", "a3a2aa196a595a7effa0e8a3ddf8197fa3837c1a55a392f456bbe2745442d844", "6e3e34faf2a38205cee3dcc12ed0519960dc05b4378a5d7b264e977a34145362"}, +{ "367000", "066c5da3bfb95638c9b0c37cf99fe28f31cc4852082933305b1561f8b289ebe2", "4d69dc379574aebfb8c507bc6791adee838a066e7de10e2e5d633faa6aaf7927", "c10e1ebf67ad69e6cafa722890d7e63bd8fa7af02b3504d04721d7dca1cadff3"}, +{ "367500", "ee383e75691d5d76bd0d84fb2edb77a9f3e453fe14e3a0840524d4966eb3bfc7", "addae0433c1a0e30adaa6bc21dc08c4c37c7ad6d12109458cc8b9c3deb4fa80c", "bd8e9a602a825d25fc27b6d83ad29e34ff074ea2a8ea694c919e88d639a3729b"}, +{ "368000", "7718d30ae93a53584971a1aae7c71b99f17332702adfa3ba93ac53faa3131bb3", "00d48572249cc7eb9929065f4d8e5a4268b69c425ab521e974066c7a15ba96eb", "74789961c36e16dd0c2817513103375041368b49ff8ecbbabe300c64f66afa71"}, +{ "368500", "49160ed17423768caebf15a07b978b51b9a50f88cb934cfcb2ca335db599b313", "252c55080a47e986faa7b8e8321239a25b25d5109f3b60cdd66c2d7086c32bed", "9d2db8c4d6d232322264bd21f19fdd4abd273c77e440f79392e96302846aceb7"}, +{ "369000", "2a35afabeb4c08f7e0fc8564b016b65792e64b6beba78e5d7c0641af63530170", "08264c57b5533fcc49b365920cb2d8b698be6d412ee0693e4d78d847530eecc2", "4106088b6f4e3c1905df95439b4986171c20dc64b019149fe72d03ba0d79576c"}, +{ "369500", "003a85d64df7bbbe1692464040b072934789d092d6f866338b0e9427e823a83e", "7084540c646571d0af1e383b6753e92aec196cf20c88bd913e074ff05dd63502", "b30146442cc357beec3cf48ccf52376250011fbb712a4efd5446004d201745c6"}, +{ "370000", "434d40143a0e8d8fe2e00984effc5579bd3661fdf33dbd93cca7fd72351dfafc", "bef78b640aacd4fd8598056dd42dfd6557355ba44f18fa9aba104eba4bad9738", "9d4f569ef3874b03e72f2ed5029f9ebd8844fd88051cebb97c1c3daa087f7372"}, +{ "370500", "02cf8d2c1db6faf3e7755a2b3d144a4936dcd9f34214f1c8aa826465cc3918e5", "24b38a6971f48836c71e37abbeeff129d21fe5975302103ec2af62a337c33afd", "6061f78f93a983e545f9b0e06d2098b8ce8a67f9a98d9e922a58e7e7de1b754f"}, +{ "371000", "2534f9c4ca46fe2df863db301dea97a3bfc6e5a3645f4080d221e9fc214efc8b", "24faf019a5e3c38e1e9c941869b93a6c5bb2b2e3e3c754c37d83bfe009f78c20", "d8f2e545e9f60114a37b677d35d5b1140c933a491728de7a7154e6f9eeb99416"}, +{ "371500", "1c3ab21bf75be98963553462f21fc369e7503fb8699d9f6e1f635a952c55db42", "8dba0c68d6c580055ce406b81e3262b9c7057ba8cbb8b221130766e667c878a9", "70c1bb70564110d67adf9d12494e89753fd4a4f05e0f4f0902c058e626cc7c70"}, +{ "372000", "b7d862d978a007b9e4afa1f2f0650bb20c0298b8bbce1666d58b009c07014bed", "f070560c4db4d96f47694e25dc96746634b3b1f172ae1efc8435b29ab083697f", "4aae622c2506753047894ce5cf9d7eb707435a9e994896a6f4d7eb0fd02e0e99"}, +{ "372500", "aa2c34e6c03803e0edee9675926dba87db1bed0c89e605dc40c2213a330e53cf", "dbad4244855f790740309f5f7e49755213bec4d672cef6491758cba12b5571e6", "adfe6f7b32d60df2f459b9a6cefeaee4c6d8699f7d021742a5d593bd3c4bde72"}, +{ "373000", "c03556ea141010a523c44868eca127684b01e83f0a76090906728aa34e599931", "b2d61cc71ab0b18171db2117a6d535128c25e68031c3c44c059c7c7965d05c53", "4762b483ebc34a038245662d1ff2938c9b345ea9f0c43d2b06efaecac6184115"}, +{ "373500", "b61ce82c38d812c1e72a830b062bd3854701409fed42cb8cf89d9c83a68aa4a2", "3cb1ca2e543310ff8d22cba4bfa2973e264837d2a4a5052cfccde4de4a4a477b", "85177a9b8ee909e6b462a0edbb6bf8fa04fb45c20a41242c60cf9e25ca661a36"}, +{ "374000", "0a2b671cf0c4e82c857482fd9eae13f8212fabc508c3f6137fd3004038d2fb7f", "fe35de23fa234b6dae59ea82cfeac3259eef5f8d8878aece906a9e71121ed71a", "2d73b8297e43e4800b22a92a402fc7fd9298cf4ae76b7d48a97e286d6833eb75"}, +{ "374500", "31b2c402de5e4f0911f5d14b927f38483fec9234b0ef67efa026a3648ffd12a0", "80a419a3787c4ab2a27cdeebbb020eca8f63743beceb73559c09297682c46475", "b96f53cb6f434570c6f019f74824dab40cf8df0874c43fa257442b69f43915a5"}, +{ "375000", "1673933d5b2d1584e3c923b45bacbae604b308007ff19e25999f5a1d89afb040", "cdf2c192e290686651e7f63bbadc54d0d8f7b1d2f7208a097807de32159451c2", "c5b8ecdcb1e90452677fbcfcdb638f552e39c9f1b842b5e7bce3ffc104aeb718"}, +{ "375500", "6b35b7e04b2d788de6e2cc8909ab7fc5470b385905dc0e7b7b8524ff57d7d7d3", "ce795b401b8cc3db0def999633c2835436348b032919c9123e1481800aaac88e", "16d2091d9d7e6571a6a837e81f4000bbbb3057e229a8999b69ca532e068d84d2"}, +{ "376000", "9a2ec84dae6c1b6dd358c57205e0858d987b68bc1e029cae1b8239ee5ac181c0", "d576e0d718d3f594ef61eb7be25e4083d1ead1201fe8eaabad00c63938144f85", "87b22143efdfaee0e8bcb0ae2c50b0c5b70154d0160e2718f9f6deeb867f86e7"}, +{ "376500", "bca044a02b4bd78ddd32eb668c603f16f14daaf04cf3541d019d3421868a14d6", "9abdb75f5d7bccf402e2e02a07b5e6d5205822c4ff20ff5531d29d4a8cae5d4b", "d006de8ead0065377831d34c519404f011d6543b4c0c07ffca21673dbbe73554"}, +{ "377000", "1b4b732e1f4b18b744aa40196b7bc5d3e1074fee1beb4efc674e38f16deea7e9", "04755ac05c88590c66be5b72ea85735df901ee644ea1f35772b82bf18c2eed13", "ace5a8992ce6a0e9649e7af13c92c8c8bf94fec2c9b7c919e885db7bc4e84544"}, +{ "377500", "a51b1aadb6f280e7c23ad430b8c59c8067f0b8dc10a0be61666d1da71bcfadda", "d8eb0789d6088438ddd828d02844a644a2102dcda7614b262daf994437be74e1", "504975ecd3f6a7a4d6f76dd29393a289784ef8031505cde3739f9eeb6439502b"}, +{ "378000", "82f6ad88db9e44f44c837c7a117802a6bc4379ba9141c4faeb9e7731bec60f35", "8c48f7630228d3c0322986552aa96929eba1314f8c62baeb801b95cd3cf400f1", "9a8f21d53b2e81d3d6a7d8cd55679ac21a6301d399bbda5a3edb394b915d5c3b"}, +{ "378500", "c2fbdc981504762cd306473faab285e108b27bff83a84a1460bf513839d9ee93", "37a18476810b603df1cb7efbad84e3b49a24676073397977eda35fb559e7dca7", "2a31aed6c09e9adb08dd67540fb0f501ba40d18e7cc3de9e22a0ff619637cd1a"}, +{ "379000", "5866ea5d40e02e5c73a1828d3c3bc5ffe23f9702292ba595560908f66b23366b", "ffd0dffc4b8703364b9885055b427f2bea2336714ad4c5fe567e1efbc8fb7b62", "153d00afc4ba8d2b059e818023870686c13b43cb1bfcdf00175a8684f178b673"}, +{ "379500", "2519dfa5eccc5f59b59c89bf35ecf2aa0f5f8b43ccb098622def88dda5177b36", "56df546c0e7bc87f0ca01ee62f0d0939810749cd5fe68fa4848f6f302052ccc0", "e1a9efad3f09dfd23d883b2eaa6da604044947d3d7edf52384d0338288ca5156"}, +{ "380000", "7bfff4292f5f17bc71f6763e2257fa585c6d56470390648079609d8116988255", "e5c4c441e3a8f0b5f55bb8f5ad18a9bf4bf04719a558e2b954109e5c47cb9896", "334f5b20d53e889991f7770f0ab58c442dd11a7bb1f40a7c02e95265f290bf60"}, +{ "380500", "386869e1fc8e3f7d6aa8bf28caac3d5a344330e974a42704885aea3cb459e179", "279bf20f5fc0c66f97256a42cecb4597dfbee3eda52cc03c01239d2be7ce0e0f", "9a691875fc9f4d84829b0569c3ff9654b4a79121bb3cf31fb9238edd27d3a2b2"}, +{ "381000", "86cf8da3f13d65311d707cbdc932a563a44fc12e1c43de337583bc0d113a5a03", "733b60f69120d3ba845a388871c75cec4b4e2479ffe31d83c0bfe980133460a0", "8f7bdeffa5b735d5114b7632878fe921080e42b1064794843fd311e95ed31a6e"}, +{ "381500", "3ddcf06f6b302ddea992508dc99ce57c1a7922d05a89decd38668c974c0d3d41", "145aa998b1e691947f9e9c1f9d7bce235dd64fb3101664f2c310b59479a49954", "eab537a2ce29dd0d3c7c7154f83e505684f4cf429235453f8f69e362f6ae8cad"}, +{ "382000", "5cbf96c1818addd8739c3b0a928605824a71eeae2cff1f520e644096662c6d95", "0282ec673961b684b9c2c43f17dc47d7a1c4128a19b4dde559103986abf4ca50", "ff00f371acd91a3ce59d3749087a3879ea474f2faa3562a22c4dc51080bff089"}, +{ "382500", "01447f3299aee987ac9c9294682b89f9643f28bf18123ce8114b3ffdb6a03c5e", "8a0e1f6c67098b89b81bb0769c520cb50a87299fff5497a87486417b43efb9f7", "dada8ebdae71dc3c94c923dae9dd4c90a65e2bf99ee6c56cc19a7d8e0daf0c88"}, +{ "383000", "d5efe4b385b101b754b2b30f6f99c2bf3736e9fd0e5a06d0b5ed3064e7641852", "245a1712512d17bf19156fd5288ebf706e85ba49278ed03c2d506364e7002e08", "e0aea51d3797945a25c74a6ff6a3ce3c78eb7ce94174af5f0cce318551baaed1"}, +{ "383500", "5b88888d1abb320e7d295c00a15bd74041ab35850fa768a8786d2e0cfff0948e", "adbbab8c600e751c331a054924b778213bef9b5a5e23f3d9ca8c9e3b877d8b30", "405c01bd1f9ebc8c3d667d84b3eba5d07cd070d0215e53b92592f38ae7284be8"}, +{ "384000", "def1f25883b2060a7b02f078b184a1fb50ebc9b9ee8190971a6315386382328a", "31cf28e8a9ff6242a0e4c9b2ba30c018acdf9279b8326185516851a41a15535f", "f9a34cd72e59a3f70cd776298fe2d3526f5a8119f67ea3b09d88d27b52a0bfbb"}, +{ "384500", "a08467964a472ee61fb3ed6b622acbcec35b4903251cb99324f14f2b9bba7545", "720e5881cab3613d6baeb94449d6695102a1e508f1b456ab03d2fdcc32486ebc", "3606653b8ce7719fe8ef866128c203d2c90d4b7be4a2f52e50c2f7d1b55714b4"}, +{ "385000", "d460b85b1ac270fad347a02c19917b9f38ce22c01d8b88e90d0baf63f011b117", "b207a874a45789d7b09e0948eafcef8b76c9184aa370a508a4bafdf9d26ebe29", "6bff034cc5d7f348e854dfd1e6abd3ca4c093d2eb766e821dbd03196bddf76b2"}, +{ "385500", "abe63c027a3d085071de60832600c63e46d78d244315facbee6f0f3fdbb02912", "7d911e4630c29d4daf24ef749a17d8b7276c4c9c3f6194c6b0176b4b5f9271c9", "51f3e82af0c3aa29b7af55ae6c7d6a15ce2a4ef6f84897bf464844342fb33162"}, +{ "386000", "656989d4c67537591081d194c31766bbd9fe449159aa2d3037afa3fab0f74a82", "bb24425f9ada80398f6b1e4505b1f6eb372966389f0805b22f2e2d8607aaa38e", "0bce2fb4e1c88f8403597fd89d31cd90fa38d25dc5f424bdbe13fdab85840189"}, +{ "386500", "2c055ea6793d46b622e43db2f1d25e05558f77edab26f4b1b200bd5aba514747", "17499e0c656152df6a2d6096c5dbc50eadc4f19ed4919a04aa3a5c06668f3acf", "736428b80f27438e4ea2b83c014253bc113cd7b342cb6b95aa60f2bac6fb835f"}, +{ "387000", "b25736d7898a4555b0e257ee1e4cc0a96c1275378dcdc0056234846010c29101", "15a65bf7b60e7729a9c9a12883b882eeae58af6b07aa9e1e4b7eab5775de2154", "2b9ec63bfdb56932f3216fc47aaa17292283cedd49a7a04cc2cc41a93a67b7d4"}, +{ "387500", "623ea15901831a8ece8d44b5da072e281b237a693fc3524b523f658fc4ab621c", "adcaaf4a4184c1719060e828a12933ceaf54184d50afa75118d16df5a67aa578", "c749b80575fc01e7835631b523a4b934f5935963d5afd277c86ff797d3b3ef53"}, +{ "388000", "91bbcc4c97dbbca8f88c68abad1a68e91c79f337a0bb7e14180bc2ce92eac137", "21bc2be4b2c59b991ac29c2266fc1cafdfe59da48e957f3105f8d45fe2284c41", "ec34df2e57a330cca8d7620b1d9353aa79ee0f98ca70e3a92dca3df2fb9a3906"}, +{ "388500", "8b9552c05fef1a291df8a1b47d92229429ba2aa1c3453c274bdbf8d3c7c4fc92", "f146203b047b7ecb750434bc317aaa95adc82c1fad15f35b22b879325ba38958", "ae8444d003815306abd9bda668bae4e19f52160eaf4b4f3061351a154f6abfa6"}, +{ "389000", "8e938a51863daea6ed977f9068092e5764c7dc9bb2491ac10291921725be7ef6", "ccf2ce60dd83f9dfae647c30e824864a5c208ed5c8837420f30cbbc7caa3638d", "b2c27b0f52a80b2dfde788ad620baec4ddd7f933ee69addefe33acb1dbb93483"}, +{ "389500", "7505772f28c062e4751b5653080ccdf943181e5f0419069bc20ee6255c2cdd2d", "a4080018717b150e0384c0cae9a6500dac7779a57565cad365483cf79ea99a4a", "5ab9117677d99645546e9dac7ff3fbe6f7d5da87bc9fb20b5af6e7b958a35409"}, +{ "390000", "6f4b50c04bbd5aed6b57f287a0e6d90a11ea1571dd3635ca9b6ca6ef541cbdd8", "b408a6d6415251b4b6ab6db5ae815ee07d0dfc8a8e9ac22c44470916d7d57ef9", "0361c1a625b6ebcb9300f0b7885bdb81147b83ee27595380405330eb84ce3043"}, +{ "390500", "b8caebe933d7dc40b9648b530bc042f1f93f4a1bf6e1530164682a1397dc1aef", "192645f2fce9e3b4a7398c935db6ecbe5b79d25d8557fc5ee13d1a5c95fe790f", "63bf3991947441745874d378da8cb9bdb65dbcca2fb0b4f67d1459e23f803333"}, +{ "391000", "0e6e6686e469e5fe43fe99fdfb377dc48f85d7892b9aa70e1ca46fcba1fbc940", "face758288797482e69de640daa24de10d7a35e17e3b575fe147d73666fd0b75", "42f1717e6dd23f095bac64c9be18b2530e7d0e00fe093e6fa129a63a7b853216"}, +{ "391500", "fd1e752770b8e555108d7e32c8f6c7e1f9b8dfcb20502babe4cd541910a03b68", "89601e3e196aa20964f326b166a74f7a601174815ac89bd1c385a464cee7a54d", "8b2f34e08e98c276848f6796daf338c2c08647b7048154327b0e58d4a230b52a"}, +{ "392000", "529453ab5db3938d1195a3ef84c286e8103c42b7b1b25362898674a66a48ed5e", "892462e851252b9a2ee03c507d1acae80ea67d360514a4c5770d7ce0dd3e1f54", "8270cbb4a1814555b8002dcdc92547a98b5913175a4e255c0266cd5f03616a0e"}, +{ "392500", "e3a3fd9781e171e256dbee0afe8373a2be01930182de5bcdf501db3a73a70952", "945a626198abde6c92ee9304cec95937cb148057692f8a6c5080e0ae930be61d", "11cc890a72c56df46f5237f6fd4c2a537949fa53ea0a065dd6a16996c7b22af6"}, +{ "393000", "01db0c4add701bc81282082aacd1fa1ed032967c1ce44c88a46f22f09a00af6f", "7b2b867b0ac1dc90aa91e0b88722f474b7d78a3322ba125ce36d0ac755b2c3f9", "7f916ca6a85ed98b74f5be9ee8c0451e63ef3e9c91573eb295335c2c27a2ff47"}, +{ "393500", "c045647644b0d7daac826a34e5f7cdb1f55a4cb4cb5500c16ba4791a8f46433b", "8985e0f86f19a7a72fbe581cab68588d1882b9a4b1c236836aa1e559612692ca", "7361778fb183e94949e43aa335bd2a472885ae10818d96530c5fa6b4fbb859d5"}, +{ "394000", "7336f022ef425203978336336066daf7f85850fd1ca5ce2be57119543211b7d6", "6f1a7d270bd2cd756c02d24aed1e33fb78042efa052bc7e710cf37a60110bffb", "ad66c0970633f1c1b542a1151287d4551e83392510c0a30f6d79b090287134b7"}, +{ "394500", "2791b8c33b59179365cb1f1e97a71a0ed8c4f9dcf98105ca35275dbfde1b8213", "8b5c24c27b2fe79353caa4f2d7548591db269b31c1c53b5e7664a47ff1646a33", "53d2c4e4243d4e00d6b332c4ff257d13c51190052f4c0c72f82ddb0b06143ed2"}, +{ "395000", "b68a97351f28549882241171a79cb58a1ae92d93a30e7524f3580dfa69bd70b1", "a2d0161bea0620be17038a96a9c21a7c5ef08df89362f1e82ce8de29187735bd", "4e5f889f7efe01700e2103a125cedff7286bbe6b270fc8abbc17ed614ed644dd"}, +{ "395500", "f674116f1af73caf4c6d464f99d55c1152f7529c15b0d28a12f35abc1553f91e", "32fd584340a63818498504c5fabc21fdf3feb2a4529a6b5af5d9ad67f3679b20", "d40aad5a5333194b1adde906913a50c32448090efbe02eab7e37df4b68a4f960"}, +{ "396000", "ded515c3d960dfe073403b321aae9d66a1dbe4a9565caed08c9314e8f1b1d2df", "134fcfe75781458a3899ad3330c143de491b74c09c98b8e95c16f79cac282828", "bd15a67e4b54b428e0c74c14e1fea888ffa584e9a323ec86e85672bb3061f7ed"}, +{ "396500", "b6745b3e2a46f458eca58083625f3eeab22ca3256087a45aa6457cdbe9999aa6", "4124109f22fdfc42c1343feb20ed8a93ba55cd7f65ac34146c3f5caeee272d94", "0bfea25929cab536e6128420fff5a11f559648af36cf6566d44bf1e87f116e2a"}, +{ "397000", "c79ef7c45f179c76254995bf3c810a62636c40d7283658c3d35f167f9b4289f7", "a6fe1a5721abe2a12fce95bc5f5e12a4185596ce991d6af28ad2cb2972305637", "487e1173dac8b4afb016d702dd349ea3e9f67d579e36ced25103d8242d2b8020"}, +{ "397500", "d36dcc0090a5585951004c7f9dd645a5a2daff1d97b796f2dba60c78a89d5a14", "a89cd3b2d93dcf17cdcb0f7badfe7af1077f916d6ad5329adfc38a6e1d25cb5c", "94c443495e8142bbea3d6a22e34cc6f8e9ec838e3cd9c4f61ae6ff170b7b90f5"}, +{ "398000", "2b97743e109f78d910532ee0f342b1c491ae74badc58085ba2a7b9029f9fab5f", "7ab0985407419f861b725834b5643d2666cbf5aaef6aa6eb94dc9e35c0f630cc", "ab4a3aa2dc717532967156a2f29cadcdaced3564a28b3f2a2bf5387b9f961c2b"}, +{ "398500", "4df2d83b00fd22751d5fc8b22743c9831701408cb9b788d86bf081c666e389fc", "9c545b4c3cac0e1d1f9fecd92ba0f7c61ac3e8a28a8c973ff6026fdcd90c4a43", "a5ff589844dbde9cd52951da27d06731785b5bec0908d7dfcf1703a40a81855e"}, +{ "399000", "6a00c77818429d3ed4b9bd5211a3cca69cf68c9a99a89f9e1f9e5301c08afb03", "44e27a5f4e4c32f6698257f5cd63ecf165cf4941a94f7473f3995b1a3a6bfd82", "3a870921ca65e9a9bae895a4a29520a70a4f3ca8178117491427be7642070aab"}, +{ "399500", "a6e49cf1def602b4915fbc2b208490f5a84c8a93366582f77ecf5575119e6cab", "83be829fea8e1ec65f493f3910ae0f3798b9fbe006e41df4bd927a9bd98f3cc9", "c001f8b45cf32c6503760c6905278ee2d55f3035b79c05307b9e446d1f2a5bb1"}, +{ "400000", "641c6a53eaa3c9b94e924327e70830770397343d7927eb713609f14448ea6228", "4252f178c0c42e28cce9ef5c0c40f08bc03e3b631a393de6eeff90e7b4d26d38", "b1ed7a8cc5c9177b8fb8754170251bca86c728a244cfb54b7c79fd84f025021d"}, +{ "400500", "73e034517c9649420d36a641130bf16b8634fd3b2568e58198508e65def1fa37", "a13f2b06f4b1b3daff6c10571f25318c3ec8e9f2d42c59f4f19369bcbff62da4", "f3788132cb664a0e812910995c536e03da19b95e03d40771fe6a7094afc1ba77"}, +{ "401000", "b249ae5082bc1eb852ce420a2361be80dd17228fd17c709761d0f52e81e8478f", "679e41c907f1e82c438671466ce285437ba23fa2c845d8c07b43af0829692b69", "b5c351cc2ce12bd45cfdfb989b02ab756db45764b8cbfc5c2214ddc999d606b3"}, +{ "401500", "ae40fda2bd776861208459ccc6f1d205b769de518dd00aec84f87811e006098c", "2cb9da6c40cfc83129da322498da46fbb48f7509d66d7e5ad53b6ccf2723ab83", "0e79cc1abab489be666493ce7dfad2892c158847d6abfd927febeb09c872671e"}, +{ "402000", "53a37e92887f0f1305b937538e060a4626675b361a28d8ac3cd88ce7c16adede", "d8bd6aadcc2b327c5d2ebe73f48ff2df81310be0b9c194cde8fa5aca004874d9", "4d93737748203b5132bb1b9a6bcf4d31d2515b7ada13ac68cdf08615d4ff9fff"}, +{ "402500", "54008c3fb34d324191f2e8790f68e097dab91c9933bb83566e2039abd876818a", "cd1605e18479c4a48bc76ea463608f2c2475d5b3d603bf9ba7555194f6a77d73", "f19c359ce0f426e59bf440bcc5b38ed78f44d1f000ac11122d76b49453eb4800"}, +{ "403000", "7ccb2c59698108c6ada2be19fe72a1be124c9650abbad735cdcd1b07fb5888c8", "208d179f6a09f352c3ce8c445468340beac166c28398132d642afa58cbb06fbd", "54497aba52a3092e6e944fba240418ad695f9f9501e26f147348354ca9b6c765"}, +{ "403500", "4307fac30841a99cdb606d9828cd6a920da0155afbea4e5ec770d2e82da4a850", "b6304f7d096028bb882b39de8ab14f625d2ae63e4c597d34fddbaed7c2b9f526", "21fdf4bf6cb0121101ae86c775a903512837e720dd1f2ccc1565343ee99642c6"}, +{ "404000", "b7845240f6d8ee0cc32e37d8682c587dbc52d07eef8c1b1fa38f73428b73afa4", "326e6eaf313513e4a52cfbdbb0106538065a4ed8fdf3d0e7eb6e00ba46037af1", "4174eede9b7fc4e01f1c012643298afca39ae871fa781430fe98890c0e78796d"}, +{ "404500", "73ba4ce92e212342e14471f4d85581e85c402a55671db59282110671ede03341", "b2af723149653ceffb01cae05de8860e28208128f215e3bd8bc65c7f2d03de41", "606f423f018c4abecfd83a7075225f01fca721dc89525e76d36650169fbe8248"}, +{ "405000", "3b3d4f18a6a63daf34505404d27dd936531654047b1dc9d1b1f864c33f7ed996", "b6287250e883b8c416c65541fbd8cdb01e7d76f989f3fe3e2c31b762d9c3269a", "f4241f2c2781ca2575187428bfe71098afb3db7e4a8380b5e3d4a92edbd0bdfa"}, +{ "405500", "74fe48ee491e1f7e881a9a5918f1848dbd129b08720f0c9f2dac17dd413454f4", "d57fd78c8080fb6739f260c4117e08c2214bd1afa6c4244bc16fdfd04804fa76", "5c80a17d894fb620e225de86352aae89d34d93533e9d44283dff3e70788f9180"}, +{ "406000", "81c002e0fe1d6089bc83dc43cd9d616138fb16db20f8ff9dcb039a2bf54bdbd8", "7e37f0088205c718348f6f13211a98b16ad8808ed51c824050c1c3793562197c", "b04710e9e4246dee4dc6be1151401dafba18618997d1b8ae0bf4de1e5b80d3f2"}, +{ "406500", "20aa6245826270b507ea3aa44b5360d608e2d52b20109dc81a63181f9727dcfc", "2d722a96f3605f68e844eaa0d3629408e9e20e8d5d095d33c435ea2427420a9a", "6fc4b43b79a0b8b6c35ee23683a9e4b8f38d1d766a5ef21d007e8783fded3409"}, +{ "407000", "51c75ef8115644c138fc20ce9af7b771731a1efd11231c881096fdaf59591660", "11b150fec2d433d57eee04489446c967a692ccdd64fb6c90f95b150f6d5ccaa9", "1874e943352cd0c34a96faf793f3eb4ca1c7be75e2c7c807159f0950fb2cdc7f"}, +{ "407500", "6f24e1c00195775eda44acca48e654190b2a9cb22f2dfca41410ce90a067af16", "8b49f54e99a2096f0ab8dcf8f22fe21db789b9bad29e43edd3566f5eb7045b5b", "6c1f21da50c16552a04055b16753fbe51ea9d024a98fac7d886991f880aa2450"}, +{ "408000", "ce3c90abbc8da7ea5c5df3c25ad6fd3a7fda496b1e0f696195bda3e6dbe7919f", "a5a21a4cbf89271969f43d9c808706c6cdb624daf4e5250d6690d40bfef2e78f", "8759d76d04358bd628a1b6d3ccef5583ac09ea3de67caaa33dbb46c96d276925"}, +{ "408500", "ff9b888f601e151a141d92abe7007d40203e6cdbf107740c78a4c1c715608626", "3a6e13fefffab34b8bc11418f83163112c871b7483b6cebaac9f9397b5894976", "a0908b7c3a62eef624fb191bffb175c01498f593b7d85f0aed815c016eff40a1"}, +{ "409000", "7f3914a988816ad71eeabeaa91e918ab92df56753de139ce9170256ea433c610", "39c9ca62d51e871cec9c9724f12841ded9e81d1b684ba9bbbd118c4d79675e3d", "942ebd81ade6be2c6bb33732810c9e2b351d2bea484338bc237156270ce38dbb"}, +{ "409500", "e3fa8435841942ec88357b1e3e0c33702412a83b07c68589319064dfdffaaf81", "beda309cb0d0295f165e7ff4168eeb205c921f202c3c9524960152b7ddfa00d4", "4058bcfec1a3664865d77e828c6b832891b2d1ec0b57f210d53d59bd31b256f1"}, +{ "410000", "3ae6fd96e35b4a84bd063aaf72cb8ce5eda797e213dfa856008516a88039a94d", "58e69a89912f506e6f4ed9e89229f9d81113cdaeb5bbd120ca273136117dc82c", "7d997c8d8ecb9a4d6585ff3c93438fea372a8896f67b45ebdf524128ae1382e8"}, +{ "410500", "eb2bc9bd04d8c2c4ccfc4096116e390bd407e98f0d81b2a7a1f096ce0e86336b", "3a87b4d2e3e1c6c5171edf685bfbd0694f293987197b33680dfd338e3ecb4b98", "ba448dee877fa01c76a73f0777778d806ca738030a64d46bef3b9a4eb97d39b3"}, +{ "411000", "a57f32043fdbc1b8eabab9e66fdbb7f40066ea9e92d3b1055e7867faa4b73187", "afaf24d67374beb37bf9b1c1f0e231ba901b91abae33f81367d55bdf78e1cf2f", "8db864625b2c002339a7c5a7e1a50f596c2c22f6304b0329432fc787f19df836"}, +{ "411500", "ea48060ae79a850a73fb9da920ff9d38245420ff20fd71ee09f5e1411c53f60d", "248238d9ddd8abfa0b502311f3e2b21f3e5c5b75719915069a209beb7a1be710", "da02af0658237703797b8a73fec8e7ab7f471ff0b312e152c1584720112ba9ce"}, +{ "412000", "aa2691852758d5a285217fe3a9bd1c2d29a6d337a0e350abd60809cecfe3207a", "5a3ac34a9dfcdc2b17eb45244fccf0fb4e9a843dec6c6f76355c1a81b16f90f0", "84e9cd8662d95fe81e421ba6d02268febeea187d3b710fc16490c90eaf4bccb9"}, +{ "412500", "5a0807ca910611b9dc9992060c41491071f17f9b4f71b8934e8fba9cbdf95a69", "a904ce16e3399f6e8eca3201ccc7fe5b15344c4bf306f1e63da4ab019e0d9582", "3ec35eba33a7ba4d1fdeed451986728b0ff9f9fea4b407362a9016d5f6ef2e46"}, +{ "413000", "6b93d17d702eef90b2795ba888ba49dd4d0d1545784e5d508bab8f3f3700be79", "20028cf3dfdf9af6de78fd6ec4f174f46a617f2d3204ba22c3b487d3cc135be5", "fc86207d5b5cd24f4948eb88cb46b669fa563894cae0997ad41194a7d747ba24"}, +{ "413500", "1bf2cd60f8c697785716c23db0c3588c42528d3acd6a8427311ad176e9bd3d71", "b6e7e1e76a68c20f6909cdcab53f6e820bfbe896cf25a7e435a52ec6c2c3bb85", "c48beabe0f4091cb2123d6eedbafdc409d3a6902fd3a7fa47aebf356d27da31c"}, +{ "414000", "ca3778a71094657cab8c697bb6d36930a875d3c76fba72194abcd69fa5c17703", "02c6d73c2091a860215de5aa0741c1396c9fb5334dad2786f1f483add87f1ce0", "2262ec877765e09b6232f90ca1cefb23eba57935ef49a9219b8faacd014f4abc"}, +{ "414500", "97f6a6e7e49a245ff3e2acf4c2882ec0173994a21c619f7a384adb93804bfea7", "79845ca1a36820aada03e8c46de2dd19dacd64131d91ea5c102bb90df653cf6e", "4de40e1303bd9d37f007dde622c1cc446dc537fc6836cd009b94ddc437100077"}, +{ "415000", "e68357575afa23d47a2a7fd4077e14d22e51b786c8866042263c42ce2f6fdda4", "4cf1d285f03ccf0ef31333c8b6ba0142b54791b826f29ed619266270c725b070", "1e194249fe3404efdf742b982dd74c828448f9429be057e0eda060065cd1d3e0"}, +{ "415500", "f975006a0b269a3c5e89fea165ec1821ab21dadd0e95d2f372428339a09b9476", "a2e3b1b7b2cedaaf531168cf85aea230e8a27131f3643f15269cd8b7fb55387d", "21938ac9bc8bc929926c4b7773a9a002213bf132592e682772e67b3d1baf5d70"}, +{ "416000", "27ac3cca7b525e4bced3bf89072f6df21ab97f85317dd242d9698a9f695b3d29", "65b7175c50d753059f0955541a646bb523b47f1fa35f5d3d86ffec0077e5e6ec", "318af64c025936fa7c6d9eac3c43ae98b361eac10481b35cf03c96c832eefc8e"}, +{ "416500", "c3947b6b74b100c5bfd70c7cf1baf822871046f3ebddf211f20ac0ad00660851", "ee1d3925d350a9da5ee86bd63c792406dc6a1c70fc0d286dda655687a0b83b57", "af9acad2158b709dad09721ff0df14576b6d9fa44f6c8b7534a53bce657f925c"}, +{ "417000", "cdd42386e134f3cbe56a5b6ff14b08dc50a1a02b70278f20a6982517868c7613", "2f7eb3c08a36c3d1ffd90dafc4ce917e3b44fe62e8f545e581af01a2fec59891", "a77c8210926d9f7ff84820ef7760888206d1fa7e6fe91891f280232d515ef087"}, +{ "417500", "758c5ed9fa53f6a940eb15078bfc3300f68a45174ad55b6d754de04344db5dc6", "9d180ee51efbd082e027e34d85c9002b72233e99014924f3b56955f3dc2ba17e", "bd9bbb6cb9e629aac281de80994cfdd3397acca99651fdde653c906300d4ea38"}, +{ "418000", "de38ce06e6f7c0509fb958124422fc1e0711c318d7fd1a0fbadae47352ec0eeb", "128c492324c57e30449629f7a9d475ccff48d077ccb61dcc5b7f91d013d89337", "5081c305aa4c0327fa8cbfb020382fdc0d31b1925a187b06b73059cbade1f026"}, +{ "418500", "52335906771b9b38787ad4381361b609d5eda9864ca2a7d2d22125faecbbf76e", "192a8939e510e4b270a3cdcaf4d5ae7379dd0a20e4addae21c2115d0bcad0d18", "4002323d26b41013d1ea056ce4e1e2f407ca07bf38061d02c0041e8196963d0d"}, +{ "419000", "d7718cb6a671d3e323e7f8c85b013f8f46dd89353a6f77672806cbddd9887379", "ccdffea8a7310aadb5f103ae277ad075b9daa876c08f3bc4e13ca1fe85a400c2", "38eb759cf7d0b9fef659e9c2640d71387e762d0d0c35dd2d9d02b92a490ac4fc"}, +{ "419500", "311eb00a753d20b8c4c073eca48fbf44066e4c97dead7b0224ea65d24dae43e2", "5d4d46ec84c96ba390f8d1ab5cd82fad5d412133341c4ec204f36a47462a1633", "c08cf696bad8203144615527689a09db37e35b54183571f36a15cc47f422f2ef"}, +{ "420000", "02abe9181281799d247884c1887745c6aa80f60a1ceb12693d328015d28b5a84", "c5713fdc696198d00a681a1602a8703b724c13362bf059dee081747db8c31908", "a2c34ff963efd864a186e1dd9c96bdc75abc145341e129cae1b1a4227d506b07"}, +{ "420500", "f24e5019cfcf1f0612785511437fb2eb94b0a44ae6207ff537b07113a6deaa5a", "4c49208f8e5513b0dd1940c861175e2bf7bba04d6373e734cdac63237fc24f1a", "2a06b91a345e95c498468479da44100d4eb31198aeb0473d902dd935f2c89f0d"}, +{ "421000", "0ebae57f2319ea062c101095eb8c2cde71bb38b0df36fccd23fe6d5e40f968bc", "7c50e4dcbe642218c07f3bc8df56974ea197f1107b9b523cc8d984f1903c944c", "80200e27ad1a99c9b556577e4a7183dbe9a9d87a89ad2076006ec94d9864cca9"}, +{ "421500", "3a65fa88661cc79145ba391c18d2eb928842a9ee2642c757b3731ef399323e13", "2dee8bda6a09ea7ab0349f743da33dee3614c069af8977377a94bd87d072f131", "219a15a9adc94181afe5c2b29532613b8f06757e90b3e83ab418365a7a993730"}, +{ "422000", "030b699998f98d4b331ef746f96eda057e7a454f98765a0b695d16fd3e7aa44f", "9b2c25f8a003bba7778aa66ea405ca0a7d1b4d1a44ab35c28124d0d147a731cd", "0cf658dea39d09846e7ef4eb06df6cc066e8160373025491262efd613e188942"}, +{ "422500", "44dd126ceb8b88b2d3d942246ec2ff298ff07890fc75156510de8dfa22c121a6", "fa987f8cf06191b45925bee07fa035ab558e651c1b94d1d518524db426449e5d", "8a32b94cb5f773f48202b8b15150b2a317badedd78d46118281352d3ca19737e"}, +{ "423000", "93bc08b4a0ce5ef57f63ee483936125540dffca3d9d6aa1a24ca2f69df2e2100", "a02f084ecd89f843bf976fcc5f5c3d7b9a5c2b5f549c12b896f4985f3fb18f82", "28fe299babd0481c8eeb2ea1cec2f68f82ab85f571d104be8d33943008ee5f31"}, +{ "423500", "4a09df19634b6b11e40263176de979e2aa0b3aca1a95825c3ad7eac2a84bad86", "1a2acd078f11b82d5bfc43a088c8ad652ac993c2478fc2469859ee4885da2ef9", "dbfc352c35d85d0d29acc20be05bdf46ab6e6772d8373a7f43c73912d1b803e5"}, +{ "424000", "bad4fea158757021f14bfa735be04d0514bc3632f96600b1e4d632efc33c6238", "ea4dcf8ad8122d652811cb25f7277c96380f8f3b1c839f63d8085d1aa69f5f89", "e33554c749df7d7bd996e3edd93461887d2f891cbc8ad2d8a4eb39604bb40c32"}, +{ "424500", "bc5a6d616947f853ed4f4d9737fa063959d32b8acdd92b11e27dd47b435b38b7", "335830fefaaddfa0a3daee3b4ce06b16ac1930cc7b2411dbe831d3c518a520a1", "bf4174f8c15c19be02ce4152174b1fea5ac4d471e854c80dd226a6dc098c0969"}, +{ "425000", "5b30049913f1ad030235ecd4deb6fc86120b8206e5269d39e56e6c5f1bdef8e8", "40b7b38eead88896d0993db8806af19167c6c2dcaf989e571a90cc689568e9a4", "81374c7f070937999acbb9c2f4c59cb64f5d477fd823bc45bf158bc54bdcc9f1"}, +{ "425500", "1c8c6b6e080abbbd1aae24639ad147ce9dcfb2836be1a4d5520ebfb3a9af61f1", "c6e3bb5149886a4050a284990303b89355967d534894ec988b9b9be1f451edcb", "15249bdd6d51cfcc7470babf6556d8bfd2494c18e57723a4974660afd4af2554"}, +{ "426000", "9a644de2cda849b362daeec3da5cc28e71652c6a2bbf37151d8ec938e728f2b3", "a38d8a78768bea93a802d40ee5d92753afeae17ec5c625515512f4284d56eb1d", "d1c2c919b2a3e3615ff340778ba6d3bdd2d0a177dcc679ed3f27cc28a8896731"}, +{ "426500", "4b3cba7009b8a7e4fca74996822c10f661db865afde3ccf0335607d549db29ea", "91b61ada9596f861c6ae77dcb3f1da3ea0f39dd623b58910ffbacb800448a8ca", "6538ac7b92c96a890c9024ef1072219dea4481c7d48bcc7728f83a54df8d47b4"}, +{ "427000", "6c5ce8cfc2031e16ddbc1da1b7854aa2b45d1e3a69f2fb73bb14d74a34c702ca", "ab6ed27075246d24cad1577e05b7c23f081c1be76318508cc5f08aa692ebad22", "753b425d2acbf22bf4dfd17eb1a76c9b55e0ca8f9fe4b43b89a2094e91525eec"}, +{ "427500", "8156e4220e867b6f1f988b354b5a96ad98b7f7e83774dc658aef3cb7113d274b", "f8874e6dca4d1a2e74d442999c6f47bb74a49892a0d9a1894c81fb7d1c350f40", "93438b999660e155678f757ae0b6940dcef316dc19f7e9d028cd900a79cee091"}, +{ "428000", "8dbc7ef6a382825ff9af8347d23569898d687ffd3743285297278cd90e3cdb13", "21978c24fad677e5014f13ed54d547eb96722526cb52969673292324cb188b79", "bbe888f9da80c32c1e4c1634d5261cdb85b79ea5626355d5fd8d3ae8bd541d87"}, +{ "428500", "cd56d45be8fc1eef02a601ff132566ef3537c7a69f67f2d8ca6de2fbcff16bf7", "f0b9826043f778014106dd4bc0e5429d0f217fce16e401a42ed252b1d2ea6551", "b61a9c7bfe67bf1866ff00fdbc11c428663137f8df30a61a4ef4d347a75fbd83"}, +{ "429000", "4aec842c5e392ec18423fe3735e8f9c84203ef54f2b3dc837100e42fba29dd61", "5e2a8cf8c42f6cbdcd136ecb5386e02eb993ab5314fd3410354159cb6497943c", "3b1e20816a54f52aeaf9990cb09b894bcc8c0092304f892cb59e0586951e0031"}, +{ "429500", "24d33bfe6e7a8694630a848958175d99c8c5a5fc092437ca95edb5e8f1aaee5c", "dc92e71cbf3286ffc80dd237cc7cf5ed769de81324291bb80548a79b6a12e354", "2255d534152b8491818735d41a74246953cba35c63e31e1219e964ec80d99f4e"}, +{ "430000", "64e5cb5e05477470b8068e35326c7e6779e4cbb740cdab675f60a3048e15fc25", "c622476e2285d634a82c4720d0a864b11332b9e00c3379f7001f28608c1c4817", "25f4ad4b2d4d171bcbe707177e7e5d460acc32dc1b9c95374f75bcaa8422730e"}, +{ "430500", "c7938907c4845919f2ec22dd7ff432e7e3e2429e65118a11ae5f2fdc1f5d9ba4", "5b34e827fefc85f603439e3367c5bcbb63d94aef7f5389c54e10bf41c1149d09", "c952e2ef3d66b2e4d422deccb4b16864a66b281227b6d895ee0688a244ff160b"}, +{ "431000", "a1f4642fec301e246762ea675616ba729278569d221b83e0fee38459ebb157a0", "449b183170ba71bd90a2cf58cf0fa0a61ae8d86fe32075dd4b9e80c0a3d8f365", "d7ee3255ecc8c054b8815feb6f0a70c5a5f6ac4a518998bbe54cad80f250acf2"}, +{ "431500", "012e1de4c57ac640cce243e1577db4193427c285579d43614463815932e6f227", "c5e13378fdc635b4f2d4dc61ee5d1c0ed7f60850a9de87de8307c9e7e494cbdf", "ef50f48542781827d015d7b8052f505946f3412b66836e954ee3e0bb9e09d18c"}, +{ "432000", "e530822bbe70b043e108e5101b6a684e9b1d5c47a8d0b2e5ace12e44810097f4", "211321ba33cbfd213efb8e3df7e7ea774ea25fb24c82cb757e568b756472ee12", "9daf8cba2e949ccc6c601548dea3db3b2190503041253d14c27c80cfbb90db2a"}, +{ "432500", "c40c2a8915c595ad827fc5097518aaeedb71832cfdc7f3336789fd6ec0fe4231", "37b6a9e80f2b789d61060f97f6f7b8ce019ff788339de54fccb2101c184b810c", "0de5670c0bdc09dea96ae3fcf25e696695ad584481004b0ed0d0866643d676cb"}, +{ "433000", "c471b86324fb2df461084f3b3f91364c8e4e54b9c592457044805c9c0b1b1ff0", "c3cac09940b2a846d2798df91b2e697dff55fcac233473d159da02f5d2a8865d", "4c5b4f409b7791478132fb3163f1b8de1d962d776681f9d6792a2f64fbde1f52"}, +{ "433500", "7c83482c8fd9e4c57aa0dd75563c991933b314f3f18c7cc821204bc41d4c76d3", "4d6ebbf09ef39066a45d9157273466fc6e1b08f246396ad00ca6a533a4d08da5", "d71a19094986f21cba0d87a134122b9b739dced2d253bdb86ce0654d5515474f"}, +{ "434000", "7d3607cb242e5daa146bb817da979a8874bbbb9abdffa2cfecc546bef9a2cd26", "7bbd1335b9852ee4cb13b1d7285dc11f9c2867fbe267cc4b6c1b1a3dd6a15803", "5794e0fa1101da3c9a01f3d7887783501007ed3ad3b8e100f1392f8e4ba8625e"}, +{ "434500", "0534c7881cc8c3745dcac6942291cfab024520de1159d3cd1cd6fd853a52e1c2", "b08a60d232a23a137cb4808f3636128335ccd3dd10fdcf766ae5c20b64d8a926", "31ade4612e2b6643beca1290e1b393b6cacb155eb807ded71060f50bee82902c"}, +{ "435000", "264a1cbeeed20cb538b71b99c8da4874af707bdf7591cc37e8f2780ed8fda372", "f226d8a6d56c761d1f9ebb8f5b06414d1339c17889767ce48317564edbfb337b", "398bdd3b22c722cc65c029a5324d04124d341e4b094069cffffeef232092214b"}, +{ "435500", "410932e8557a564a226ac672c5578f75653ed84c4669f64b6bc29fabcdd90586", "a5c68267fd466a48ec4473ff1c904efa8eeed2124b7e4bab8bbf83ee876dc375", "d22821fd1f65ec706e2f4ea674026ae1f266c12b8493bb4ce16d8f1d0e446d4b"}, +{ "436000", "c153195fdfcf3938a5dd5ebb0d5dd0ec59692a8decf1184083679c46569b537a", "5d8daaa7bff2de12b5d9b428e84e5ba25ef9001e45ab728ec74d6a22c61b269b", "11f2341d723906e44683e681f911663b4273f0e446422cfb0512f56d93bda046"}, +{ "436500", "5e3b108e26916d2507a40bc30211948a0bcff8ce4b40117ade096cb5f94d22c4", "16754de8c6290ed9a3e8769b8a03375448921fdf847c7f1ed6d627e614b8f6ea", "56996116a345cac41199d917efed3ffa92cb624114ece62a086043a42248f5ed"}, +{ "437000", "06ad60451a13eb38ac6f9abd2375d50afa00d4d8c5dc1c2806bb5a05727ba523", "4960cb8d1571d7c0aaf33b659c0721fb84bdda17daad04f0cc169dfe1a22ee28", "dca2b15c5324a29d81dfe54dd537d6a84cf1bc0f5f97265766e64a467da8f1a4"}, +{ "437500", "2f14aaa3e58a32d5a3f17562b3ccbf8edc8bd17193a9a09af65052be99225a2b", "8709492c2ef726d995e4a2092a2d062a849450a00582ccf51fd7ce3905ffd2c6", "e0853cf80fea64c09107b6e12394b88dc4111c7fa806b65827b5421e75fd46a4"}, +{ "438000", "87d16a339b0ffda31c75b16f3fc8f7c45d0c67ed9de0bb27027524661b1f91a7", "c21254cce7d2b9df55ce98218ab9d20d9d2afc3a450ad1f3931e9c7802de8f35", "1eb9cf7aca7e18f6a95f0d1fcd876545f9ea02c9b5fcb7dcc311c9a9272ec279"}, +{ "438500", "b84fb753cd672d1622e7384382069066410f1c27763902b5ee2c919ba3f20bce", "075834fbe8e33fb3add9426e52ca900f7db370b85651ae10ac5079aae540153a", "2fc29d34f8d996a5f9cff1dffb49255462fc1edf5af8f42fa552a5abad79d40a"}, +{ "439000", "cebe0aac7f629f59ee1b2928d8ce4340b247c0c619e3ff53b369375bfa71abaa", "7e5fe6db2171c4040cf71a4bbc598983a4892689b7b8da5e3cd161ed7696a410", "3880d26f0e572013c1f076793fa1ee719f81db61a9b5b2b901479106f0a87e79"}, +{ "439500", "7a70cbc08418eb8b711aa13b0a49ca6cdf063a443a0aace6b8f78aa0c9bdc3d5", "c7107988cc60c6c66c2c9fce42c97303bfbe3d3db9ebb17da8416d0b1a918e44", "647b6cd53b1ba42af61bf2f6e2c6d72e0d728774129422ed96e16610644d05a9"}, +{ "440000", "7649654fe753d823dc09f3ccd2157d9e9849e534962d5ec32f5a71775ba31fff", "3670ea77b7e5a8750d63d8d846cc2e676e69539125ca1a3f66c1d1573e47ede3", "e96b220b011bf5948e3398b3831dee3c7e7df23a46b3f68450be2c1bc9eba100"}, +{ "440500", "9ad49b33c96384a916c19e0b7fceecc324d33aaa8fc45b5e48c661aec09c880e", "e594489948d159bafb11b9a4151a89280c37b8f5665d6d209766ccda296346a1", "9876c19a50263b8ae919b6b7c9a0aaedebf2b982c674319b9baca1c3e89e91bd"}, +{ "441000", "2a3a6ecf5d7defaaee82b14d7073402109769a5a8c940d6ee1fd35f23303bf95", "e8520de1202a192e8f8bc825b528d2fd8805efb774b18c4ab2f3dd153063a0dc", "7448a30847d0c10547e0d79519e363cfa2281b18003306968133c9ad2c25e229"}, +{ "441500", "72fbb24c48304e9daaec1801004fcd4bb4b6c0c511932821a6d875bf4c9e6bc9", "13850c1041b5b257adf6f51551051abcdcf13bf6d674e075c0ea32028011acc5", "f193ce67a931e61bcaa796a46c0018229600837508a693a7f447ade876ad5470"}, +{ "442000", "d8d9a1091bf2e48609bde3ea3140ec19cfb7a2a14735474c6f9ef6105c46c8f6", "8879f9476a6a342e58cb8ba5e4e40a9ff6ed0b605f3cd9b4bd9e6cf5dd2dfff1", "21e3613ee1ff3bfd0f1461baa7f7a2a5c1d68e6a21106155607eefea238cfad8"}, +{ "442500", "78782ee99be29090c13682ee644a47f85f410c5a24c1976dc047f3249dc1e0e4", "b4fd6ca7a0b0a77143c457285ecc982da5b9639a5659c03ba88315432e4881dc", "978f2508e977ccec4c29433bab1606f12e4e0b324053e9f85abc6829df5f7706"}, +{ "443000", "a5d7115bce13dbdf436226400b23c30de09f68f6a5137cba50de278effa35891", "cfcc7a433eb789185f88cd600fb249d26b8c945d5e5a5d7e978ae3c1c1118a10", "dee8a4dbaebf41b33c79b1f32f679a36bc24c5c127a305ca2b1923ba121447bf"}, +{ "443500", "f73cd58af88e5cc893f5a5981888e792f6a15cc06093c14e0ed91110778f0312", "22b5b27df320f33c1856dd087c8537e5837c0686ccb436961189989d593b318b", "fb92695de156c669016fa9f27dd174406470b91f73cf3daf7be351314936c575"}, +{ "444000", "7c497c96ad4740eb68993e26ae3127c6c9e10b8625f9e759131574b87cd722a3", "e5405706b778afbf261e0b4ec0a7fdca861baa26ec3a65f5e970769a8497ac1d", "64c785620f16baaf73a811e570ccecf1c10aca3d189a2606d013947e7f5d9441"}, +{ "444500", "cd52d7101a166f4dea73875c0fa5c494db3419bc3f63d539e57c8e853e96cc6f", "c874b6d14b66ae740907a7ef12eb55dc0983a4a9ad00b27885902a11c72d8009", "1fed952263d7cb5b5ce2525b5e9f9a2adeae5beb94bbcf18fc07ac91079e2bad"}, +{ "445000", "30283438585b2c4d3409d61110cc5d400b0abc0cb8e8b65b9fd8619e54dc387a", "3664d9de72ce8aebeaf5f1e844e44f5b3362d0faa80415de24c2cf5fdce153a0", "7b642814a213d9494bf730f43b90aecc16904f97448bf5e2f6eabc288d748ea9"}, +{ "445500", "a4496d3bd4aea3dbe7cf7d2d5a3f0850f5c01b04662dfd38d3dbe6736251e91f", "8cfad175dbdfb208dc40cdc2f03d0ebcbd9f3b12847f6d069fac33a5c1ba5173", "25adb001aeda4bd4909bacb421b7d82de30a9200b70f520e4ad23759f7a2e3a8"}, +{ "446000", "7cff0564cc670e8a69315b18b0ee229269682bb0286b5e4b3db25f02ce0c4d2c", "b5c22f647055dc1204b243da18d999adebc56060e52f1f0c4d35450a9e941c68", "307379f276df96f5cc93828b4ba92cccd6d9a2fb5a54d2cfdde7ed6e2197ccc6"}, +{ "446500", "201cc692970eec864c92e5e7af036192a9562a62d2723204366bdbfdb0741fa4", "f3abf2331a35c83fb86e4484026fbc40266f5551bc90551b90be2d26b3771e3d", "1e0f73f08434857355a8e7f1d4950a3d0ccbb5ddd80f5473f99ec0698d63a4db"}, +{ "447000", "c06f8dfebb81f0cb3f19109f662a7dcaa4a023f1fbf735ed81fdd6bf9fa95023", "0799398c8a29c71de6027c446de153b17b1bb364570328bf5aea872fa246ca98", "a0f76a7d67f1f9336b2665b032cecae3e9cb80463c5679ebc28b7fe29c185d22"}, +{ "447500", "05185f624dab270906ae111fb2c43e838b70a78e0420e84fcc94bfe4fc911dbe", "f73e1007bb6e28fa8a5add7dc21539c7545ca68c600ebc62b10ae00382c9a538", "8fcb834dcb86b9c51bf43cbffb9de5b1d7c2e30b22f783c99394787524f06ba1"}, +{ "448000", "4fc96bd14509bf55922cb5d8ed4cbf372f7ce991646e5be3a086204fea0c368d", "0fff78f76cbc925b62ffe927d50cbc02dc83fd9e5405a3a77e232b55a494812d", "67e09df16c3fb0a8fac40ee153922aac6983631f99a341cde08c05252fc4e11d"}, +{ "448500", "742e9431b2ac6f0ac24e58cb8e6088ac1de875cda8f16739a78e0f1f7c05ce33", "d892c34609acf3eeaeb32a384985fd2da70c4f53f59f8c459eaa5e74b3d61c40", "2997569447cfd809ddb51792a754d7b497adb3c23ad38b2fb15082e4f09c53c6"}, +{ "449000", "335341c810fdea9e158ba78a542922754fac2e0fece92c27559d14c5c3ca0267", "8d6340cdabfbfcddacf2991913176b17513be28b9472b744e7a64b2f2ca13896", "b0cde57f64c7794da94547a5341aea6fc5680f24bb3188a01171ebc61415471b"}, +{ "449500", "2b97e9d073d0b8922e73a1b1d6fcb7f8dbcb0e22fea6a707d9faa2afa1cddf8f", "4fb82487fd05bafd111f032ee92e9864534dc93a7d0cf994928703612d816f4d", "1c5d2bcb3165e293bc70060db78a5cf299d42c4815896b65b5f54d742923f434"}, +{ "450000", "a6448ff3de412e8784a4d0590120e0727c3ef1c6e98af7adec4b687e10c22b40", "b12232c014cf52f4f8d0fdb4037642bc1ce2a4d709ae37b91d908c9d36830fd2", "d0a08ef423f57c6c0488096bc46df33cbf920226423f7930c27c813c9d34c71d"}, +{ "450500", "32343305ccca111d5b0396816091f1f169314acfb4974629e7beb8680523cd47", "36cc9b37d7962e434782de92543635fb826a4d84fb5260ca0161680523f54272", "a2ada16c0fce347e1158c64a85eafc07d49f6fdf5c91d0b1c1d973c3655d4f75"}, +{ "451000", "adcb05f8f053823db604b6278de320da2097890b386fe67c0104721e6cd76954", "c63c045a3117df4fef3287be2f66c5691b700b18b42d3ba60509faf162dc9720", "642495d66438cd4d827f29aab00729237d60adfa77f4fb3e74640b459b79868f"}, +{ "451500", "c3f6f574abc62ac6ee2b65eee953b3386808361f721ec77e4df9bad7811b0c13", "8ed2df18709fd8580694387f903d9c31fa4a7c5e3bf3845b4fa4e9a701441112", "8b317080fb74b592ebb41cc1902a0a466d4cdeec51bd10f4da17a2b263ef534d"}, +{ "452000", "b47901f63e411758d074dd4181d87fe30acb1b1623d0e69701093d93bc505b4b", "227dde0bdd2ce1659265ced176e8c5514aa1d7c9c58c5f92d18534141e157539", "f919704e59bb5bfe322594e6146c55724c38e493565745772c735583e826ccad"}, +{ "452500", "723793ff45924363551d433d63f58d9951d58791f6954a6aa906d8c61f80d535", "1a931421c2325c0c2cdea860d128402f6ba18decc20e05279f62f0d0f5940f58", "46a8f9f7cc7ad3ada81614675edceb12361c35acbe7922c7a7223d2f7dc89010"}, +{ "453000", "14a86fdf9716b2225cf80394126c1bcebeba3be4a4f103a3497c8eb079ab11bf", "c0261d2846f68bee936c5ebfb638d9d4e6bffc53519b76ce72dcefa8f66e948b", "bfd4b0429989a852b9d98718fa499d4fc75245139046162a4cb45726589ffbd3"}, +{ "453500", "4204f92e27edb642343263ee5c8265639a4e4bcfe6743c323e5915af2db0f68f", "681663c10b07fae27a187f5512c63f266d4460abd46ec1f464e8744b5ddaef67", "5a478160537a5353e374707d131b56e1fe7efc9d5baf224aee671d7ae9449d38"}, +{ "454000", "d7173ff752ac555014e60e3928c1a8ba368d9ecfacec9b302cda79a6c6162eb4", "c34bd72a990e253a26ffe68a91553b0b771083a569e512c6a46a52e5c7b6a724", "ab445849e1252ba4bef39031ee3ba2f5d874002c669a39629f7501290dd5f656"}, +{ "454500", "df134eb761013d3ba1bd9ccb38d735427a299f2e275a3a1764ae436ba07f09c2", "4d9b5dfb6baf847acb9499ef9cedfabe98dd58150569156e5bd692d1f7434f3f", "75bce4c6a1817c3fb96328aab91271ebe51ee816a0cb874a4158d72e615f530d"}, +{ "455000", "edf2fdc49b76a90ecdfcf0e238e66d574794b7ebab6a4e7d212e1884a21588d0", "c40b528799070a1964e73025da6badbda9f994fe3d83cb4ac5fae95aa2e42963", "9d6656615f986f128404fd2a501d9361bd002b72928d22f63d9956c264d9fecd"}, +{ "455500", "0728ecc53f1b1b7be2478f687881eff7e6ba31e9d565619ed628ea9263b67a97", "700384e16447d9873213d70063f468f9e4e9b1f780104d9a118d86b09aab9594", "859ce00ed105ec338d519f2743a7b3a46dc19c8e7d86a31d1e4d4b9556a42f2c"}, +{ "456000", "fee4d1a2fb2a99260e941a74ab4dc87e0520c28a115ba86c6382791b2f06f1f6", "e0487333ab303a6d155cbc61b33eb1b23a3a9bfc3d466c32d8e6793328b3bd8d", "f9e43e85269d5bb16a54bb0eab65e7236b1c1bc1fd4fd2937776d0d37af7a9bc"}, +{ "456500", "b5f05116bdbe8b51f4c1ffaff1a0e0a445e3a0f0c6c718a72d346162820509bc", "c7a2de5b71c4c7b338b04adfa8fe16857ba3c926fffbfc97dac86b0b75033978", "6c99c37c34fd8f4f06be74b129a37bf12b4ee423434b3103205b7daa4a7f6ee5"}, +{ "457000", "b414f29bc13f7cac4f028641c788a54786bc9412ed582f4aedd5df86039a8e00", "ce69e9060126b330e010d201b073dfc0e16924a8c11acdaa61c7776f0f2d8021", "63d198d0d2d1fe07d46a18efb3ad448ab9ec6aa919b6309a4009242734c67ec2"}, +{ "457500", "c2f18fb64768083a462a48b87b993870ab96a70e325cc1b7ce676a504dbbf4a2", "bcf97c78db8bc3b69a377a185a429277aa530aa853c7ea12c2ab06566e837c9d", "34cb2719f39251f056d511bc2990386829224280c0253ef19a45182af0efb716"}, +{ "458000", "379e0643c8dab2bdefcc1cedf8118337bc0133f0c938a1553088230052f5cfcb", "22e7617308101b51b4ddaebed23dc67e0d1e0b3f84c5074039ed77c466cc83a5", "09ac8a585922541577aa4698c7590b0343345a40448b854e441bc724984e108d"}, +{ "458500", "5b8d6a2de4952aa7aa38b9a1d403fd80e65f6cefb5e824c062d060894d490946", "56ff3b66fcc71ae8550fd0630fc358edf11f7afdd551d69a2ec9d4b9fe154bae", "eb82ab3d805a77df91f9aded634cc7e9b1d0e197f274587f144f6192534d4c2f"}, +{ "459000", "426443a695e4615554b95c1070f14391c199178d8be6860807b69cf2d686501f", "40015ea68bd905903100db2ed67d0a0e25510796dbcd1bfaa0b8dffec058ec4c", "01cf6151b050ac3c65f8d273b0aa9991afc6d2c99a19b73eb58c4458ea448582"}, +{ "459500", "561074bb87ee4d3132bd22b91af78df7d2cdec1c6914b43b12a4004204094a4c", "86a908568cbb19be09a1c70b4a92a0b3022e5d0008ad78d6ed536a9bdb08deec", "3d22d3d556bb349cec89c50054d81ad210e9c4d93585b8907192bacf920221cb"}, +{ "460000", "7adb9b6d14e8124ab25bb4696bc8afe6a96cdae5396ac2a5d6d859c47236990b", "6ea2894408475e17a8c4476b5084cd76742a3cdb97292eba2e2ba0ad4bb17d87", "e22e9309202f9a77ce29b5772f411c7ec5e47689496e4cb566b05a01fe71da97"}, +{ "460500", "5cc330e1e985af39a1a24602603f26535df43ea7e5e164c6b654f292bb359633", "69c11c20de0f89ada1a65781a2b7e7a1e235f964341eb70434135888794032c8", "ce3fb2a64db272c7138e730e433a3adf8dbf7b4bd754a2c1dda585d4475e3f0f"}, +{ "461000", "c1c45b5a71cf6ed3c5d9a739c227b68fdd3cb41e8102b7e99c28084776c3d8c9", "122728c928e7025fba2e58a3b70cf5dbf448e26389be3606b43f3b014d5f2001", "39ce156b16a89759e1827b550c1d56bc9f9b9b45e0c8f0c1c70922220c3ec34a"}, +{ "461500", "096479184f5b32532940e42b35c51e50008b8224b2c6d6317dc69478d3d316ac", "aa693ef567b3b7c4a7091b5bb3d34161b4235e7bb3b573a22e66bab0e622f16e", "9e242e78240d389ae4e2b845e3fd1f4aff02b280e743e5a0232c2be5a7d3ddd9"}, +{ "462000", "c78d5a646f9130aacd23a52cc3dfc5a084add7fde9dddbefdd13d5c438e024a2", "3242055c63d5e14c1efdba0effc3580106e14c443a3c39c699931a6c4a36c94b", "b586f9c9cd03b22f452fb7da6fc1f5026a53cb86120ed1af6dc81d77c841bbfd"}, +{ "462500", "b464f9105311560ac63c29a94f8a0a5f378bcf5c22cbd23d5818ebe2e62550d3", "4b91a857ed6803609c0f1d514e5793f3f63ea3dd37f84b345c3c64c7248f8358", "6e0a56c8afc1967c6e3e9eae4ac2cf0c8dc6437035a07dc4a9fa0b282e539900"}, +{ "463000", "ad7d579916aabacd745a9d48122a64e420ba111b8633119f6110a93125eb6072", "ab7a1e347245f8d9ca551cc5e89247e18d130aa0180d375673de0578dffdec36", "39d7e8e516f09f532c1eb829fc0ed11e3489ef4d42e34a14676e84805d831ee8"}, +{ "463500", "9f647ead66c59424ffdba0067d38a93c33cbc5cce95c1fb19483d3138d9a2924", "f9be09f0a7ec9832b7d2e238f0f3841a10e99967b378bb93e1e8ed95025791e4", "a0625aa3447319a563d31e3a63f67fe9a3c372809e5e2d2b6eb7ee328191a2ef"}, +{ "464000", "8239a8c5704697db70720d8227fef8093751df0e79bc792a4583106c5229d97c", "56a2bdda4613688231ea85b9d659f05000786ebd53300466da5dcc474f8386f1", "7f2658ce497a6ba01c6b9a8e02261fc39102420f84793b7e16784b2b5a962d11"}, +{ "464500", "b8500802e87f0a3d08b275296b32aa66211d93ba13dffce95a77f4d2ab6ff8a1", "87c4e1ae3a488895890a0dda084969a43703e9abb82fa8a6b0fffda090b1fcb0", "60056e3e3de9d7893dc58b07cea9258dacfe904a71949f764579ef6f9aa1ee28"}, +{ "465000", "9c5f241c6d7947c078423264cd080eebeb852aca6898b71dec1f2fe0f97f40a4", "eef3196b8ab3c6d1e3df1eeed6f857644e50f6a751843e308a86d72e945cc6b6", "ecb9587021098efd5e2df880998cc544af71206a067d1f5f5a57bb6b4964e95c"}, +{ "465500", "714cef624738d796efc3fb3fdae8f42478924d28a0644c225374b1e5f8707262", "8d68d66be9f3952f46bcbe5df4829d93eff2f4501bf422582e8594bf3f03730e", "2cf7854558253ffb17282849c66c8db530c422810e2b9a35c1df67c2a403af0f"}, +{ "466000", "760869daabeae89da11828967600ecfc92ff38d5eb79326da9fc526ff88e3dc5", "ff631213c2cd21307d635337ecefd200cc2b7767c171ba5913ecb785d6876aca", "78b71f347088929e48f5bc408ec2a2934f541481e3f26bde43305644ea391548"}, +{ "466500", "9699ebe38cd6fed8bad4e96c18eeb8bbfce93fa6be86c0c364ac187c246d47e9", "f18cb4eae80510bbccc360228942bbde0144f6c66f378e0b4bd0005ce35debe9", "15e67ba70c538b0d6a1ccb9f692d496d163390975c9c6acc4f245818dec88a32"}, +{ "467000", "6de68cf541236c2b20da6bb789be6df085207919a94074f31975a54250c4d918", "0c998a0b617d6dbe4454ad981478bc5903ace25595e5f868c6bbab61f80cab09", "2e0152c2e09f602ccc26407b314d0df711ce94d81981b4c6ee0f6dc475232665"}, +{ "467500", "34aae978a356d729783acb130e2238fefadba1789ddf82d73b87c79d862d297f", "a90873e05bcc6a81932e4562242f7ca201a07707b505f5dddb46418cfc26c5dd", "ceb302532871d7a8254e16b214ff73614ccc4274b16e9d28943598178483f575"}, +{ "468000", "96a959479e0159621c8660165d2053878cad8adccc1ea5a4020c4a1f63941b09", "ad947d10fe2c2fb1f61572586b941c872bd958499342e2e44b545d4c0faaafc3", "3eb3bd86f7ad52574f6ed3dda2581091096b326d49d53384fb62e36450299dae"}, +{ "468500", "ef36c23495b3e062fd2a92e24164f80a01d74452d2d439a23a38e403e531ffb4", "5790fe543b78423f088a1d53daf1692a7051169bbf1e469caaa7d3862d709b2d", "c7eef6ed2d806de2c40c6015e7ca28d1489a699c56def39a220660511b8c460c"}, +{ "469000", "e32fb17dab672f159e97ac45ddb12dfe0dc0bf2a2abdc455beccdfaca5e2c69b", "56f4d6e427a46b3467c26174b6a4b66e30f5d962450273ebaa598c06aa31975b", "9c227b4d82d86a5603e5b07eb357bcdbd4e6732396b6e446532954b4ac31f263"}, +{ "469500", "3870050849e79e3243d3460ea594ef741a1d6327f5d336f8036fa5e97e0cfbb2", "2e0823dd7f7a137a063f473cb6991510a112460ecacfe18aba39094d410c8930", "94dd6c074f375f6a33464439c1e6f1a2f7a5d8933c0ad2c3e971e9faabdc8502"}, +{ "470000", "2aeac4abdc914d4ac3fde31a5882b242aa26f1049c86f703fa5da279edad5a7f", "db8d47e66737aa4776e8cb857386d346d356ba91d0f6212d8aac34c9ac2e5906", "c3599f29edfae99bd37c27e39acdc17960c2b50c18c6dae37b1499e2e87e0616"}, +{ "470500", "fdab2f454e5102f44be86a36b7c2a54aea2f5681bcbe811942451827e8106734", "cb60e3d4e6620535cbf57bf0f94c5055eabf0ca48052e9728fb28f5ec913e5c9", "1af5a3097081200030a5ee02d1bfa703abe356f23003c9985464c9fa1e69ea1c"}, +{ "471000", "afd4b785fe4656f48ec1120a14136d133df7059eedf76f407dc2bddb91ab0ce4", "0eca3c26dcc9bd50d78a8322c07b18d59c7609bc6ac97258b56b20ac73187f06", "0201199c7a9201bc722195289d50bb927fbf05adae168d1e0355a1a519d939a5"}, +{ "471500", "e633efdf19faa95b16be4cb94f7072dc1238342d624bb4d69609555a927f2522", "570bc44f8e51f6dceddce363db3b87fc17d9c8ae51ab9266a3d9248b546df4cc", "bc1d5b7d7b85c5419fbda0ae3517865bf429ef7ec3877654639e6d1120a6a04c"}, +{ "472000", "d4aeba089eca88aca7c2b7cc89e10146158dac72fd7643e4c7dada43c8645757", "e49b1d22916fa97893a9f31f31bce50f96d49f6a388ee1c8ec2216aa619d9101", "7fef7bb7753e24b89110558c1711b0f93b6c666cfbc6e21b2be9e2d7de78964f"}, +{ "472500", "a1c6bef24a340e81f3212db55e9db0bbe8135334e14f66839123c21fa393ea57", "1b5318294e73812e157fd78c84b79a31d076bafd91aeda00fa49055003be7e91", "6bb3a2ec06a00afff5bdfbfb4b4ac00397836a5d1e144ccb39b9c81f65145db4"}, +{ "473000", "c2f76403fbff7b3601c0b2bc71cc00963cf0b012e09d6be5d8fcc12a8f78c8e6", "be2ae59d51ecc553798bcd9c82f4e747dfd1782ad18021dadc24e4838c2b0666", "0422e26c8a7eb63d5b18dda0c3efe7bc646e75332413430c532788704507625e"}, +{ "473500", "5f6ff7d98fff43942ec210bff0555d74768aff3e5fd5ab6e0b546d0bfea79921", "b828dfae2a89c1199e2cad79165f815f8d858620d87aefe17630048ec05f0bbe", "5c85d46886845128e04460eaf50ade9e4c8f1c3ca6456e74f76061492407c9e1"}, +{ "474000", "2c191256f2a1ea617517c81c3133a47d2fa264586885b2ca6a7b782f9c78a8bf", "7d0b4169707e36667345fa68284bb9eb0dbbb726b9391ec0b3018c71a343ce0b", "e3f7ea82b53a82fe22c0b553fe30c4c5514f5a4df2bda23b6c315d894612822c"}, +{ "474500", "50b6c4f4c1da30ee2043c4a18b0dfa1da9aa33000be4525bb07b2462d8cabd2f", "9939b0eb461196a4ea22dc6c0e2d3c776cdf08673694e3d5a520bb644df71e9c", "5a123ab254ec518a34af619ae78a6caf68f12ab08ea1cf8bca8f9ddcbd5bb862"}, +{ "475000", "2c38054fd7a02ffcac28fb8c53ad84b68d50ef30af030e597414e15b59bef269", "6faee9c17b651d220534dc8c66c0345d162426661af23bd6be235d1c0eef73ab", "68fd23bcab5583cc821cc1e2fdfbd4630eeb912e69d8d3ce68fe22c0d8d55881"}, +{ "475500", "8d981411752ee6b44f12860a9975ef23df0c7dcb5b5c621368be19033de81de2", "23fd87f81163c7f0580a7eaf5f74b7501a868508ba60f47836488f5b72716608", "2efe456c536da42607c5d527fa75633d20e07ed10e8d747064e21e866f115e06"}, +{ "476000", "27aaae6fc04f000f25a467ff5c2fcf62a6872b3ea96a3ca445e0947bc912d050", "061c4b35170cf452518590f1e96624dbc031e5eec8b9de1acc81a477bbaa18a0", "026f245193b14cd91226fb93bb05307b3f84c121c3b4cf979eb48a4899e2329b"}, +{ "476500", "84e8616d4259371a11abc9625c4f7d55ccaf949881e017b663f249d29aaabf70", "6e6418118d4d34c06bf73284c95f2e3622c87c42ebd4a8e1380939e6abeca428", "de01d9328991d787e797992316e87257c9925542e3b8d15a992f185f5f4556e7"}, +{ "477000", "d459f75729583c8259ea66e8dcc7b8e1486b0a30e14864332dd014757bac1f5f", "9316f02e5bffa72a4ea6c7809be57001db28415e75048320d33dbf23c3a39e86", "6af818c2d7626e65486a4f77f8962944a3fb51adff66b53fb70630225b0ca9e1"}, +{ "477500", "329e7c98cde787901a05bbae8aea2a10fa244630640182eb9fcb80e83ff47cc8", "04fabe2b506d1c811471d88cb7986d2a67a988e0e094936d398af0b20dafed91", "2ca5bd042acdd1149737878821deb3ac9ec658d4543b234dbd4ba50499567e8c"}, +{ "478000", "8515a758d83284a93a354e91ca1389d0dae0914aabde4c7069180dac0f88ece2", "0f9d14354952b22318f9909502aaf188e43c511ea6c627724bcb7f0d14550233", "9f16c907bc9e804b8d89875191fbee34dd334d0398c5d10f02ee4669d85d6fa5"}, +{ "478500", "e0b6428a55906d115c2365630e7a748422b1309a75df0712730a018e138f8ae7", "75327db1cbc6d65c203eea4cf697e0e8674ff0cf180ad7730c0f42fac2cb2259", "7bb6036c936214f8cd8d4fce9355d6892e7ea2f768580f890a4e09d0e9c3b5a1"}, +{ "479000", "acdd6bdcb3e05e00631aeac70db0beacb5ff7339f9efffe5d125a748e050cf0a", "2f4a8780e4913da0886b73e399430b0a65b84e906eb7b47bb14ef6139699e222", "6d47a71a51d8b75b6949e5b95088de3af2446e78cee21a33e1ef090f9429c04c"}, +{ "479500", "173ac0f8bef2de4b544b42c3506aa887ddb348e6f719f2b4fe16beb569b6b9a9", "550714098a237e5f2a2313711787f7037937081893315ca43450ca64c071c798", "9b628260e5d8678c6d02155837bd823d326a33c57c01b120f2b3a31d198760be"}, +{ "480000", "39a37003b75d37e0588e177d5d5566dbd2cf4f1ade343067de439e4e60d401e7", "e90cf6f99b06ab2f396192723accafe62f0a7705a8795b39371238dc660881ff", "2f6ac37efcc941311dd89b57197c45e684d33750139e46891fd25f6d0c7126db"}, +{ "480500", "675b1ab9b45350f0db5814692844dedce30a416b0c5a6b04e3ec778de1c54476", "0cb43e9d578692ced5b3c43a067a09dc8e582a12e46208e1a26841645ebbccf4", "dbcc352ee3e2b565c678cc858df6b3ca0898a6ee07073ae621b1605803aee606"}, +{ "481000", "c49b18c02ab6cdbcbd1380535c394567b0fef261db605ae42584fcfc5657292a", "e45920a96e78f6ef20be3f24d9a8b1accb6ed9b0a9ace38694eba826aafe2bd5", "4e13fb32c6795e96ce1576e5b38f2874d22609f4fec41fec3a63a8f1ac98351b"}, +{ "481500", "e70588e89d0a3a15d7de9bc26e47768a94964a14edaa0355853f5629a500dffa", "f623feb088592f1cc01e94f8984e5bd7f5469ce71ff7645ed81648dcb25ecebe", "8004dba192b725abd95366b8f0dfe62ab4a75cc3fee5c1c523ba12f765c33f5b"}, +{ "482000", "bdfa119169d8507d41720ba8fa40f5ecb75267570ad0ba58e342f4351fb74575", "f28b44f2e70183e19deb6562a107d204531edc8b46d4f5aac76884d7d3a9e750", "881e217cb102b28ad20cb8bfba39b8779f7e857a9bb94ccfd0ed5ddb61a1bdaf"}, +{ "482500", "14e2be2612c4290229084f2c1edfefd0e432a91254abb83ef8ddbe8d7bf2e661", "aa012dfb4ea0b0d0a565fd8f2f55692135969aeb6a9d3f34cb17b31e32ab22c6", "6eec8e5808b4e00484134d46ed734f238f979fcbf3754d9017f79d718d1c4b6c"}, +{ "483000", "8cc62d490274477579f93e8af507c07b3816d393200aafdbb6b68755b763c2f8", "3bce0766356c52720491791bd9cc5a6584c48a39d620bb185f368eb7dd7db697", "aa99ea2b1829fce8adf1831a2416e7bc33a6859ad82269d58a3d3a5f023df47f"}, +{ "483500", "72c78ca3f93bde96a8afdc199714ae18e9c15b92526ff48845c050047343f548", "f4c218fc750e8b31e2b4f56ea5bdd7f027227b58920c7d08946d193bd090a366", "c7564a5ba5a84fb5d02ccaab954ca67b1a37d88c7b78cb89176fa968c40fceb1"}, +{ "484000", "ad5719becb74523e16221adb2353a4786de357612d9e2ae86753be7035d1074c", "f040df388303fff9b7c97bfd38d55a94c1701b82ff4f2d594b1f4637fd8ba964", "9afcd022cc235297c99a8b00e63d94cf20f89fdc1532c41d6012e1fd42672caf"}, +{ "484500", "a143595d89e542b00901e959c20b1bee243c6b7f2a8bd930401a0a922586308e", "1c50e70afe27a5026a6ae968118f5141448e69955b431f74c2b94af7bee31ffe", "76628ba63114b144c59fca247c50c53f4bdb06cd34b9b311473d078aae6e7159"}, +{ "485000", "ca0faa2c4b601116d3e03c898bb6fd6de955e9e083910fcbe93303702522fecb", "98250685f5d2fc349e6088d617a7986ea28204843abf4e887ee121b3f89a2b36", "9db6d0fcaf950249c2dcfafb15777159cb589101637f7c76752c04596588ec2b"}, +{ "485500", "1d2f98bacec2bc91b7ffcd9e760c49bc18183ddf1bfb4aac8145abcfe2f91adf", "c03ae99bd105f3c8154bed1630bbfc10d56a2aa4e36a85d4a9fb2e629920e285", "422ad706d5de44123c1e68becdf8757022af0aa1d64678c7787eec828ad5d214"}, +{ "486000", "3f9896825fb06766d9216cf1004aa6d2541642253b2980c59775fa720e1af9d4", "e8ff26003f9db4ca25d4a5e8f22c615b6b376f2aba0b6e3d3ec1fc54bfd3e8c9", "1e16510e1f176a888727956adc3c041bb83fcc512425f57a6c3f558ae2f46dd2"}, +{ "486500", "8387046d6d520535e933c40c8e7a9b253dea20d1d4fea49c53cca41d13f87b5e", "29e01fc49acda9fd49203e03a86fd7fafff8dba947e907ca41db1b6e2802081c", "b68d45a08f6fb2acc92fd619b0dc8498ea81fd57d3c5b971d5b31803afa79a6e"}, +{ "487000", "3ee4cfc2068bfe1472bb2345900fda4ce7d99aef724ce5c35e8dafc97472a163", "84ee857e054c6f118f897926d53b546c4fbaa38576d66eee4560d88f90f2ac91", "1fd96fa809024f42da38f6f5a75fe6292b9dce007ce635ed1aa865a5fc20a330"}, +{ "487500", "7802c03efcb4298fbff0c05c7c2a2670e2b5c5c0a912260fca95f5ee401f9fac", "9c507f7adb01fdb9fe8edd09d969ea7b12474cd9f317e6e0c8d1047f720cfa01", "f271dcb04df54f998866b55a7d0727e691c2e51b6c1147f668cb2542339b99de"}, +{ "488000", "6c0026aa2c04a1ab5ab59df72d9ac017f559889453749c95937e01230628ff22", "89cd039f94be43a6d229425daa26daef3bee7688fd591dc954ee503ebe2f3573", "3ea3b7011c70b0d49b9f36bd7b83265128b7a1c5ca9f69ceeb5ceb933cb959a8"}, +{ "488500", "ad7a33c68b62d181fe269bb58ad9f00b48b4b19f77cae3c68407ba81af9e29f5", "e26367c609049d5cd867041787aac089a459ae2a39e420b791b778f49c4222e6", "1978075a6d69518c80dd58998a9f9636df40421eb6af7670dbf683db894118b6"}, +{ "489000", "dce5e567c4502e3b3344804468bd48900df890568521360b198e5b7e48c4a7cf", "497cd478db672eb3f6e975b722a162b26d5f0fffdfeabba6dc28664d4dc76bb2", "d1d75bf13e39e9c5d4dff8446d5092619012d2dd19ec4f53a886946b47772c1a"}, +{ "489500", "326013c6ec37ad623eb9c5a35a51c154447c8e180d4efc381f02a791c8dff517", "81c2d130a11e3caf98c5d4af0ae7c05bd5d79099d5c959efabe7766a211c87f6", "27814c5edf60b9e069fba619805454722fb7357b50bba2dcfddae253611c4a99"}, +{ "490000", "b0ddbded4a9bad235b75d2dad597b8fd87b80cb721d2c322bde82e9bb3763d72", "5abf2e1aa1273cc9de5eab070f0dcd5b082cf7459de699a96e7b12dae3311265", "8a5c2459345000c6403134ff5743329cae055dbef1466abc5cc078187e8fb304"}, +{ "490500", "40f093e9a8e074fded5c67276c85a0261d15f3e418e492ab1452e340da3c0469", "0d79b5359c16640713fd6b885d6327bf67971e99395eb633ec71edf9f67a0649", "37231655e968680404305a8056c5abb98d300996f657362803b1be28e6187664"}, +{ "491000", "42ff56a78710f1d58f555a7f55001a1760c7090441dd2657f959a67b2d8a8289", "7a167a1f0656c972aaaf079ba002f35ecb7d47aed4c72a7da645276ee21f9ae5", "68151c99713577c18520079cb48c0d1ca1b2df2de1237fd16a153cacebf98b2b"}, +{ "491500", "38a42670dbea9a526f90e8a824bb52398335afd259b0d89f287687810cb3a268", "c4f01d0a2b59e7cedc7957ca4dd510eb692cb5ef4c257a76fce04c3e51487e20", "831668b7ce58262b8741ac9bc0a07cd87ef253aa348af5f4c5ef54ae26428ee7"}, +{ "492000", "1aedf52ef4f42d0e049cd6f2b564a1416ff737cf792eef860c4678cf4b1929f6", "a6c9e1dee9d08b510553bee2acf0d1b8b2f0bcd202ae4d28110fff8dcedd85c8", "c83967d6ff555c205f808f7d9f632bd3460e7e5b88fad92e61770c772eb7171d"}, +{ "492500", "d7c8c52fb1f9138293bdf0c28ac68aa8447efcb1246b8896a1777e5b20800ee5", "0d6687cf95402d4df5a9115b6786b1fdd27493c88b0e1fba921bb7b722084a88", "462256ef01f138f31dea3dc2e783f733c65cc02d6cfdae0e71491e903bc0fda1"}, +{ "493000", "e4265d17c243d4e4dcbe12d216d7dfe7e4e3b7da161226203881b0c007f2936e", "a6f9daa6f9635dcf4a2cc894a4b459a8aa5dc2ed487d95d733bbfe827aebb0f2", "7a1c0950c21786b59d9de46274908bff4705bd18cc0b5aeef2b41fdd27ec3c9d"}, +{ "493500", "9c3b415ad45f42001d88e2dd38748048ef9f40223e5c1c62caf5eb7912d78b42", "e68eb0e1b1b95dea2fff359dc5444930588ef743a58da356b8d33d8e6a0ee1b7", "332360bfafa171fb3f3f7333d63b494e7a7e7d6642a5d1932f9ced9df92dfa13"}, +{ "494000", "e78ce6a76a928e878b6cb5a0ca25c6b9a8cd69d4e2db9a066e702635c11ebe17", "ea5640b26510140f3abd04e611f124851c15338caa163bea3a5032fd0d16b160", "517147f19ca77c35290433c196ad20dec0bcb92db6751efe04549dd1f9207971"}, +{ "494500", "cb62ce4407ef63b81d3afec33e7b57b31a6e7c8b3e0888b8db96f17e4d39756a", "6600b14d7f4f7bbc0f680587684f9fa7d5a7acd26cf9d103ac31bbedf9d6afed", "9a6c67d7bd9fe4f9fa89540b33d9db8c61db8154018f6ed22b0c4f6abb1f885b"}, +{ "495000", "0e8a7e8cc89426af75740fb8469fc9616a8e75401fc785a8e686d5ec0f4e5732", "0a1ce34d16dece7d7bda04e5b9bcce126b08d7e514e0fb37c5c1b0871cff4cda", "94539c965b7c4e0272e499bc3eb27ca73c2a77321813c6c9a3805d5b99dd51ac"}, +{ "495500", "ba423afca93230eb911c2f4dfbba40b893b938a7365cfc2068e1ecd3bc770b5f", "5720feefb7971397896c9a270a6318f2adc667cb20f2cd218b2791778cd50680", "a3e540aa54bc1cf7419598be27ba01dc1b7b295fbd939b9ba74dba091169ea34"}, +{ "496000", "352a1fd91dc52fe0cd78e2de4240e75a785420049e7b95e01adfa3d1ac4ad512", "781da1ffa0ccbadf08f451c290221fbef9b440c52b5f7ef5bfa3dfe51562de47", "63cc34ac782e8fe5e1e18aebac8cac230295662f93cff675909b338c9899fd7e"}, +{ "496500", "d0743556e112656c069f2749baef59ef56225b6bbee44b2336ff106773fbe965", "ebc3df7a34a4a4e9d8a60151f4a5bdce4f40cc8864851520f5161abf9b9e6d51", "dfe11ad63217c9f1b6fb08b45a4084081340fb5bb9d284439d2e3276214e0e74"}, +{ "497000", "1887117917c8adb81cfbf85bd4950684145a964a12c81ca89a44fa107247c275", "e48c07018555f1a8be3ad71f6ec7c31932eab7aedfb414c99bb793715ec36e4a", "e29b08fff1fa075aea805b5799be10d3dbbbb23afd76b9cedd88f5fa2555ffe5"}, +{ "497500", "2ffe736439e02d764f544aa4f86a125b1567ab7d24a9d944313877d2d7c39d14", "a2b4732449a3ad1488478233895bd8ba26b72f14bf839a33d5fc0f2934bcdf2a", "524c1cd19b37aa1c9d5cb5da2733d04ecaab6230db6555143fc8ff1d02657fb9"}, +{ "498000", "0bc8b494b42efd68080fb3d3d83cc8156b56439c10fa789814d751d5c4f7d9dc", "ea1ad23e7f85ec30d138ecdf527a5ec5ac6d925eb888ab061b9ae24e48e60b2b", "a9ff67fe494fd28395d671744bb1d60b38ac89b53e4f66eadbc03c5d5dd31bef"}, +{ "498500", "5440fcfb2e8888508c4fd6920d0e6c7c1f3f1095813d45b691edc3a2a475722a", "4c2c9c60a2a43f9786004a9b43275656b60a70c9643d6c676ede104b9f0cec12", "de98b78d64b182ef34488808079e358e30189df43bff459894d14b47382d85c3"}, +{ "499000", "d84c475656720900a0b3765c4ed57ae1f0ba17238d34ac17b1635c6c95064750", "236f102f6f2350128916d138401344233a7483a0dcb1eb39730c6a5fa22fed3a", "88c61322be07f9b75d7a58001e4e7460dd34bb2a72214e949d28f184007d0c97"}, +{ "499500", "8b9aabf8cb60c29c4b60a942812968ab80ec48cad4053de2624d42372a547756", "540651876cd6a44a6de24fe75706bb959b3a701ef281c7b8a3ba083d6e329dfc", "4d743db021924f24501d20e27564a7dc2276c5978e0000af4a97eeea092703b8"}, +{ "500000", "bb94f21cd879e992217888fa56f0cb57bf585f8a41f845fbb46872fd7ddd4a40", "541ce9a7c0f8771a84281db66fba7cc2dc43fa636a39a840fee5bdf987a3348f", "254e33a659e25fb647aca414051e33f03899a896d032fcb7d307b90c9080d023"}, +{ "500500", "d74c1f7510c4307c942906d4c66ce5fc542f2a1944659c1ad37a0eb82be11751", "976e8ed703619833f8d78889bb8a3a71a06392e257b093a01f7a1b7036d22fb0", "fb7d68808d45544296419dfd89b69540cdb6df0917827d982ebd72adb3042843"}, +{ "501000", "3383f0c0456774cc529b5b0633a947e0708156bc873180f56fe3c32008c8bdac", "69c86425b5c47c2bc3a9fe3669b0a80aeeb72bad8179676a55dae6445b7bdd36", "22618e433ce9b9fa9bafacecf096c50bb49978a2fa883ea1dbcd2211075afee4"}, +{ "501500", "d076738e554cadcd99a14287f0d0af18fca6f893e6ab519fff1a9c987e3aa7c9", "9ceace4059979133e529e2e33930ee2ceeb2058633e06c31efecc7d2112a2437", "78706172ed2a93a0610e3f40648b1817d60fce479eb8d39b12cd99527a069090"}, +{ "502000", "03b70f8f87fc995b1f25c5979cab284b112e66ebeec690dd93e6c1f238ab616a", "5c4442bcce1ace2848f3bbff98abe5776b58af7da464ea4d8ce5c681ecb99261", "83307faabe36b7556ad019e41b11f1078ed9f42050728c949934b0cf3356910c"}, +{ "502500", "99130d7f62752e1e0a7318ae3a933b638ae37528134af7b76590d477bee107b5", "206bd50bea02399a5ad897c4e1190e96ba7c092f83cbad5e0bd65955cc253219", "a858f0c5073b29aa642dfe18243bfd3c1a488c2e18379e8029ca8f6c723ae8f2"}, +{ "503000", "3eeca5fb5aa1f44a7a86e9c2756add708089ba817e4ebe983da92bd815fd51da", "fc3643c494c343939f26a8237b3df02c2b96235e034e92e199980834ed4a59b1", "2fb413410aa7b7bdb682e803b2c3d4f17c7588a3c2ec33b17853ed85c2dcc299"}, +{ "503500", "8034c879f7596a3d9846ce1ae028fa596b84c62313f9b43564ada16c3e2f547a", "fd766d22b34e5e391c7a3e8c1318ae469a763ba6c49b75d55b0f928c83e5f992", "1776e527de48623b8a469082e8bf087f40bfacfd4ccd1711f14f7d39f121e8a7"}, +{ "504000", "bbc5fdb678ff466da54e09ab29562e16a798ae2a05eaf776d97edfa35c839a85", "b6dce69571860fa8d6db1cae19087b3232b06b8282f5b905a6ff462528a1fcc7", "94f9788f4ac548a410b0a32abf35971813f7a3cf18dbf06e3eb70ed23df7a0a9"}, +{ "504500", "956aea829d066998cf96a8b8edb9a0323dfd018642692dd7daf59d0be1b31ef5", "f90a6f0b96ed84327fe33e6edf930a439d1843046154fe1fdcd65c011aafde2b", "565c856c4321080b6b270e3d385f85ae3cdc3b0a2134f4a0a6b32a8be8370259"}, +{ "505000", "0a3445456f4807eb2f234e51acf42870aa7b6a2eb96749ac3cf764979d3aeb14", "f6977bf4113ff5e28895c0f148fa0ae812a4dfed4ac0483419d08e3493c90e4d", "32c3920d7fb47fcbe62ea2491212b56b8073d3c570380bc5baa3d6237794169a"}, +{ "505500", "fdf15fb92600803d9d99b54b13c028ebe2a39d0681e7cb751496a155b11a9656", "6fdd6b0729448d9a5dbd5b5ec1198c5f89d0a437c9019c94e0cc4b0cff9344f5", "631072ba472ad83e323cbcd05121a6459818c95c77d08d40bc06f19333399386"}, +{ "506000", "94533d7531d5ab46aa3ad4c03ad71b8a6f78574805a683be4021d3648a56b0b0", "7c1f8200acab1aa87ce1ce548b727d3c47239045d9dcb6d80ba58d908af43c99", "5dcfc85d934f268608d9a3ff0efd0a6b0ea46c24c31da5b41fc9db5bd9f417e2"}, +{ "506500", "0f86a6ffdc4880c047c73dc16aa8d0bf27d1dde7700c2fd77e4cdd7e7d926cd8", "e9c9a93746ec3a17feb362c2dce6e9a9c51a0d9f0d9700d21bd8aba906602e95", "397c09bb2457cdeae289fe4bd827fac0056e60cea33a2a2616007bd0a7175811"}, +{ "507000", "431e08381fac05624f905ca38d18e788204823803e0607106e147bbbe8bf688a", "4ac228d8c9c41f4e3d3a3c4e320ed04c13be367680f9fdbe8f6e5a7ab2a23f36", "93d88fc835441329dbfdfd0eb847f44a30391a86945ac792211e0271ea4653c0"}, +{ "507500", "a227a08c0b6d0818ac30280e4cc9f422bbb17cde711c371acb7fc19c8a642276", "6dd10139c09a88ed1692aa137b788336a80ccd60753eb237e90687a15ec987cb", "ba460e1c6e185f402765688792e23bcc17f2411db8e25eebaa4d43fd239fc9c7"}, +{ "508000", "ac9eed373dc35d2906cefc9e3ad2c8044253e75789f4d028b84a5acab33f8187", "d4fcd4e62b88c4ef4e9609e8e5c85ba44b15b999dafa68a7cd45eea0b9fee193", "bd867a112c5c29790dccb96c03a55ccdd2da7feddc5d9a3fe946bb8af6fe44c5"}, +{ "508500", "82837e772818deb177c58056f9b8eb8c42b42c75053c206ce64d4cb0caa569a0", "088031bb4d6c8d50690782746dae3a2894e04749cb8073703758bf84403f65e9", "7104cdf4ab6dc7991d885ecf65601fd63540005c3b90fc40d356ee5179559484"}, +{ "509000", "46d4c946d3305147e565ccd6bcf5049931048ab9fa78fe64a45fcd29df7edeee", "0d2fb9af0d18a37f8bd0d90677391033552038c5d24a58db89420c355342bc33", "db50d238011cd3ae24649f78ed23cd5e597dec6c269d02103488fe12d55c0d05"}, +{ "509500", "dd8574ebf8743606a8b2692ca8fe7c406487b6ba9a0eb1194eba2631c7ce67c1", "2ff727ddf8cb09ef0622821c1886cb8270d4401658d2249c402f48a6ffbbbcbe", "3a14a7e0da7f1e829a3a42aedbaa7d19d7913bfcd235a8c62851942dfdd651dd"}, +{ "510000", "8b496633b233a6ff9deba1fc40f3e1ecff693d91d8abda762bb165b4f10933e9", "3a409f0d90719857a525deb2038518acc44e2e710e3f51830c11f3a83c89ec22", "29ecf4fea155a00149f0394f8a972cdc29bb090b20511e214e1db1ea2e3185ae"}, +{ "510500", "1052dbabe3ecd64ab6a4b0b05f41c6c4131f5beee2028096f688af8da17151c9", "0cdd930cbfb6e609de9a22d029c15c5106fbb5603222b8e470a43594d1ee1dd5", "df8274c837ef863b3be71eeaa914d08a305b8080445467986fb0d082e9efc681"}, +{ "511000", "e1718d99ca8b8c0e1f84663aaa6ac9cd8c369e9118bd6ea5919856382019f5b7", "8320100810a7678c08ef0003dd4f057369386278d95ac3d9b316a062b1cd119a", "2bfa8f88541e9201f152753e37a77308212371e9ee9637f6ca5494835375718c"}, +{ "511500", "df937a1ddd9ab676d6b958c03e97b7789fc0b486d52e1a518f4d4e46d22db830", "e5b333e553b5a4bca5ee6f4a3ed9d83ba46d981a3ce30fe8fe0578788a400f42", "a28191834653d7ee866bc1f494d2563a209e6ff3ab47481b98fd97200dd52be9"}, +{ "512000", "38982a86cf02da0b76412cd5bc52aac39854cb1d000c7f24e6b66061c9552820", "7b4b3c77c94a5b9de5a7ce479a1c15ae56663e655104b0f0efb5f3adb971cd4a", "842759a6fe200e67aae64ce6726e5ff2ce631bff7094456b4b584dfc985a363e"}, +{ "512500", "c668fd92e5ab8abe4fa8c66022eaf0b8387408849349453ba8751194bc9ea391", "aebb86a20afe467e4959eb4704849a076a8e02cbc51c2dfe07648562e42f9f5b", "23e62a8921ca4fc780d6323c4a18d14eb845f3a1007392e7b7bb76b18e503c87"}, +{ "513000", "fa2042f44dad2c0e4b243fc07a60172d057c7715b7d7f73e9cdab068df241dca", "9bf87e1bf1a619c55107e28f3abdabc3bb3267a0b0225855695ccae2be2c8492", "242cc6413f3e77fc4612f2dbbabd708b8053589e852776a2bf64b49e3e2865af"}, +{ "513500", "3ada907b4eb50e027c4dce815bc8464aab74eebaa02c3fff63e829fcbcc06790", "1504730fea3476e4a5a65059e9e45acf9fde314062f93761273d0d47ef900b5d", "55f328b9a86f6704d88149b0a26c708e495ea614fc7c5874d8f45cf4e1d26350"}, +{ "514000", "b690974d95cf519aa561d59afc9812bf23f8596633d4e43638aefd0a645cfd9a", "53527239f3915f67eca6a1f57a5b82564ca7c4c5344668140b960adb23246528", "557fae97a12d934a1802a877e722fbe2e61b98c388bcf5785238414582179dde"}, +{ "514500", "4efdb833ed17ee35a5c830945a287adb464a23d60f16c1f1d6d3488d628df9cf", "f6990f581fe79ffb9d1bed01f84a338213c70bc996261e07507624df42c528a7", "d3f812637fb609e9c825929ca166e72fe21804ffb2d76b081ca43e9c6fe388ba"}, +{ "515000", "f902ef1df4acafde6dfad28852fa03b1961241be620aa057860c9a70a0fffafc", "f8f7c7f68536f87056eb0a199f0112974f80f4ca443721ec8c1d67c3cbb7fbfb", "ec115e6892b1887bf0c592c1e8f756c40dcf0a6f7e11898940d20377ed9b56c6"}, +{ "515500", "df363417aed948a08fe0c6aa48dbc5764fd5cfffadbc7945f1a6ae310a9a1d50", "d55f6e43fa28f97008367107abdef40ea271780e5d19a561db5f3af215e60ae3", "e3875a934a00bf7597f8a4d53a768e9174e1ca7d15c460c18d76bb761f99dc77"}, +{ "516000", "6af0f998e7b95f5928801133f52c03133ca1d706f044f545812d0e64afa7eb56", "79daefaf210fa29d3c633094944a6ea814f73589d3d477a38fb6d68f0380795c", "8652c12820f235e18f982ece7b8dea102025e48240aa6ad15f33e3c83928ada6"}, +{ "516500", "c7174fb637f35bc6822a651eddde06e842534badc1d7a4c2d61090e79510b970", "ed427f81415ab5bfc57f4cfaf8461c18a23a2ca0a7ec9b48002d694c70137716", "c89de38183c186ea1a1c82c9fb12b55a96d1fd66d71b0220704278a240c1bf14"}, +{ "517000", "f4055907d0bc72d6e28eaa1b566ab77904495bcf286d0dd6d7bc297b8fef7a63", "74104317e7c69033b643afb089ea06cafe18e13f125bb7a2f381ac88d362eb63", "66a856aa315f78489bd05b7785d0df90369e3425f1fc15faf09db747b2b4eb42"}, +{ "517500", "dfc6759e8ed2c1078dbf08a64b71ddc9ab2a04fff41fbe9a5c82a250cb3ef4a9", "5a544c7180a99ca77684597ca3cfb1257ee0e3fccd468e3771c55e4fd9a1152f", "1c5d3934a121c421245ba556b78779072c690c8acb7ca76c5487a04b4f5b8aed"}, +{ "518000", "3f867c72bf194f1c257f1476aa4cfd18cbe3a5df52e374b1f705e496e06840c5", "36fc1c6723e3e48773e1bd8ae04210fdf0a9d22cce523387250deb28c3793a8c", "7426d712b994a6cefb5f5103cb758d3df26f63462a6b40eee0f909068cbea6de"}, +{ "518500", "941b4dd50e5124b756a381e83ef95106d15522461c348d5e032c1b61d838e50f", "ab5d00a5d8df0c54e297611a063ba4357b4686259473accba2b139ee69dc4d8e", "4be2dfc858d43707f1aac833d26a1b451367b8f3d81915dc68db87366f90df82"}, +{ "519000", "2136325d5351d77945e009193f054b04492a8d8f210eef016a51630313a17c3a", "ceaa807d0b581d95060026f8ff02c392db4fd0ab5007a86053f9e0b93049aae3", "6074d6a72d358b551341996d6647c7ce0f89acd0c3fd38d9b850e6f0c19288e9"}, +{ "519500", "8740a71b16e0335054adba609b5df4dc066d157dcb0511442d8d413c2333d883", "216da33354860bd3b2b44d9f217b89d2a203836e5f0c04de39381776c78d43f1", "c8d27f5a757e018ed9f5e4ebdbb9b97c92f45e15ef33cc8335c9160bcdd7264f"}, +{ "520000", "21557c530c9135898351f2625779248d5c5ad1fa473d8989e8795cd650f3b036", "02327cfdef960f127b2a99811b52f651fd5f84d3064dc10b2b8c4c528a362c2b", "e44f6a53c416a47a1f4f3ff8fccfe6816a9042e7ba588c98f223c2da74b0c906"}, +{ "520500", "fdd0b3a9a08562ab9256162fdf1e8aebba6589b585f34ce26ff0ac20f3b35715", "cb7b802cfb533b7191e892348f4076176e842e2a598e373e6653c92b62b4d5f9", "8312f8654d973eb58dc5e3a9565bbadb47312966a776f619c9f8fb4dc238dfbd"}, +{ "521000", "4d45b8b34e350a098a5ec1575639465783982db7710d4ad07f7a299a19b860b1", "587836bb3390bf2dc472a0b9e20a5e643cb270d85ed4286180f358cc8d0dfe88", "b3099b886e7d7ee570dd7ef18190f281d69cf8af4b9222ab41dfa51fadb786ec"}, +{ "521500", "8357476f03fda1bb1f346946484bfa6cc9d80a89b508255c3c4b583c71ead128", "2c2d08c950c6437e2f9ff89d0c3b0d0467a7761a0f19d421e0c0846c2792bb62", "ea7c47406b51fa4fff9d4dde4cf1a312cb7f9bdd136b3dd1a0ee772ee56a7743"}, +{ "522000", "a12936a6677badc6d2c8e83d2058abcbd2deb580e5147f1e742e379f0ffbee7d", "322277c4d49c9c37e94b84c184e09dccd63cbf0154e61e36b497369c4c7f3fc4", "2e88c7b5e944e7fbd2d0a39f57e39fd1f467a7e85013fe3e3f0970dcdcc648a1"}, +{ "522500", "f0770540ebe64a0de99c169cd1a7d9c8459eae0e67873510f1a8dcf4841131a3", "25ae4d82a8a9089095bc4583c9842984d53bb4b0e6a162d369a70802b7f9476f", "2086480119c6dd31340a4ad53b39d23e2f357551ecf188fe077a4cdac405caf0"}, +{ "523000", "72d57e281db8b4a79f566fb587e448883bc1d1325c9ffc2931f1100b63e5836c", "00fcd8bff8a5e19824f0e98fca489d02ca2d27fa2b4fd9a73e410d935a1b93d1", "cde20a46475c12e517a4326e85632a956c9f5a2a3af22c84ac9ffbb0b088366b"}, +{ "523500", "97b2d54ba68ed4a14ca1fb4e4b697b2bf8f7d0332272af4531a72c94c35dc932", "04d4f8ef5ff03931eb5c0eac18894a9a7ac8ac7f6bc0b34b43420ae9d7802a1b", "21b276e5d11eb1a8331df44a4cd05c46d1868c573f3f82c8f047f67d3858a7bc"}, +{ "524000", "f5c96b25808ab9cbbcedecfe467e163e3bd9d771a8efbd3cc414c7adf1b7d380", "c11e17455d687b0dbee864879ffb41fa6dfefffd54d339fff58dfa99790a78f9", "b2bafd7f61e6485200c761f5ed481e768563fef25f82469c0c67ff1d1cb988d5"}, +{ "524500", "cc5a17d877467df92ed0b3462d0031003c642f64896f4019da641d1572d693e9", "7b878f323c00d5b6d0f73d89cff64319ff2299d310a67a2d046084a77b411101", "8f9c19111567dae6467b3d76132c1f786e278a040099af2ff5354f81f7c1cb6e"}, +{ "525000", "1b009804fbb8489d23d5512262d7536375873ef933c154a7058ec1c934f61892", "d583cc3f0f7f01c67294d2e98d28e83c81824cee30d1252816a7828c0461f350", "f1cced480702a35ee83501eac3168b6331c2a82ecf69f2387597d21eafb011d5"}, +{ "525500", "63de360342a1abd256b2f4a3f1a74da8e5bfff409282c8d06cadfea596220f9e", "124aca94373c78ba91a8f1c01d89d5bbeded60581199d3b12ac66b76c37c112f", "35bb495f4aba29424e088ef8b4ebb7b4b10e69902ca07c65f83057078bfa8561"}, +{ "526000", "25464aef8a123b8bc5dc4b9f6b83149c84511a88da41f7b5f6ddf4cbd340dd30", "ca911108aa51b78a806e58f876767baaf341c9844f31da71959ed4ea2f87d62e", "53ad3900a8a89b100539e325e86c7a7a515d77ed8d7bd0bea832a1196d8a2c0a"}, +{ "526500", "54cfed1a647b8513e845b57381456d983320e1f6dfc26bdcd4e97da73f31bd60", "a5639a2ead728587161e02add9b047738a8534d0725a84c5532bdd054e715ee7", "c5756392113ad44704a3691cff97601b8d7d4300ac2f0600cc17fd83fe74d0cf"}, +{ "527000", "d601736c31be7964de7a76ee1fa2c4771d804dca1c1a268b608f3c77971893b2", "1831200e768d735e9bf8b5ddddb9119ec19c43e22b966bd969346814cf454d55", "29c80fda0b25d26f7a5c2aca063a6702151d2f6af47a8af74ca4b38dd4b935fd"}, +{ "527500", "dbfd9c8fe9edc773e210401cb7341166fda6e1153a1fb47f866b919dbef91d31", "5f15be969fa28b64f5250f0787876b05adfcd2c64ee1c2c72eb9724403ed6dee", "2259567111129402e6f857b636fc0b58b1f732b522738ca1fc458ba6208b6e7c"}, +{ "528000", "92d74a8d4df0a8f7510fab8b5d02692442d1fb8bb9046cff981cecbef3353585", "b67baa2dd73a4061188c5cbaf13ed1c063e29193fedcac0b5440e042d39a45e2", "959f3a09311e382c55480bc857cf511a99fe3e6285b66bbffff01e97cd5fe527"}, +{ "528500", "b4a034b57dac02980cec5830c0718b0ce4a89bd3ef3f5f36e8b4181c1f42ace7", "de92eb4a468c264b4a9ad63eb75ca3702af7c023481c829041f328797d2e3636", "2acecdcd0c7fbd48c8bba8229d6f1c0a03568ae5fbb77f66716a1c3b574c9ce1"}, +{ "529000", "a05c9409ae06d5bc48284e5c624f8d6f6b001cc6f887d459043f442367e5e1e3", "dcb56fadb166de779d9d0e4e5e4d30dd558b0ef3fba4f9afc8023ae5715d30df", "b8c359b671bdd5ba67e8db94b747bf8bdc065f4dfd40ceebaccc0de8d7513f31"}, +{ "529500", "f62867ba72013c202a9a61da49b6e4eabc05e6d247f2ffd98235b8e4d862e795", "915588450e5ec1300605afdbd6dc47954df1fcb45a6a10953db21bb54bba5797", "0a21fe5e0943df74d2453e053ef4f5005db902996d852681c5a2f9bbb5dc85d9"}, +{ "530000", "35c57a8e961f11ffe1cf6712861b43b4e7d3cc3107c28d6d8722de90506a5b54", "1c060c7a921b2d8567acb70356957e7aa044d8e37abe1923ec1ccd3f0f7191b2", "b4229e26f05148844cf0d38199e94f5dab81704af3efd1de77c757b5b0a74d66"}, +{ "530500", "0aa4f3b5419e0844a7316ac4b76e00f3230781c8d320cdd62dc1dbe21875dbbd", "a3bf6f2508bcf7bf8a6fc19b2a75859a8c2d3a68858d6dedca2de5a5c687b94d", "dca35a1c94d6ac0857f3cad6f04b3ded87442aea24717a1b41d075c559030a8d"}, +{ "531000", "b65e6fc5a87f8d30ac2203e13e9e9fa450ada17650d6c639fde4f71d2832062f", "6c4e276f9cc20e4111c9c45b760cb529b12e6f6f9d984c6338e47ecf0d1fd5d5", "481ba258b254237c2af95e840b28ec971aa79f07255c696aca3d9212de6fc74a"}, +{ "531500", "4fc020cbe21507bbfef6eb1cb30c11359f8ba8ed0fabfd67181b596859a11fee", "736ebd1d9d616f4132934784dc13c0ddd6382616a501f11f84071f39bb794a0c", "396f8f1b3f89cf10e886890c8b5b3eadb5343e7df8df1ee9a5030fea95ef1dc1"}, +{ "532000", "936bf25a71f4f427a32035e860b049c5e0ecf36b0dc007608b31fb9a496b058b", "9c412485687232293357f94ea0cf8a76c84e8757046eae59406f5ee225651a55", "c4c17ffcb5bab52d1d4c4de9b23499080682f8a0846dfbd3939a6ee9c1c27e8f"}, +{ "532500", "51b5d1a338bf32a3273b45d2dcabcc8fde6bfb68f80624624b8a0ccecfacf751", "81559753a06dfa90b7ed984962a88154310cefa89233d47edce8438601051981", "c6cf7a820a418397881aff15b8da6023e70c44347cd440ce3c470ff56dc10ec5"}, +{ "533000", "d80bd2b8d148cc346bcc49974171c998a30bad85878c6e508d16c728098d5418", "cd8c0e674768e8afa69fc6366c3e2aa66ee31b8a10cceba75d3148857442c30d", "e496a4c724bf9f997429bf080e3fd5f7f5580b524d1e6c30639f8cd1cf7096bb"}, +{ "533500", "06cddea66b25e0387bb678836918cca4be53f245e84c01fdd8194ff147377a1a", "cc77c89ce8bc38a702e21b00df5e4e65f2217fd7e3d330aeaea89e67b2906d7a", "21f4e346e1ca43a731c5a0b8436f2330a3208906ec3466f50549e8aea4a14c96"}, +{ "534000", "0427f67b170428d1d33242707a2a8273c6447a2762ed42e49580526cee35bb3c", "66b923b19b1dae626b62a5c76dc9710d396b9436cb8cc549b87a4878f457e561", "f15ffb3d566f30e326febac3bc791706ad96b2a04a35a2792eca301bcb0e5c83"}, +{ "534500", "de3c914cd38e7fee1888806ccd3d4cd5d39b81cdd22f869cc5c2d5335fa29533", "77b2265b37eef1e316d0d480f28bbaeb8faaefee270991fba6bb5680a65f5298", "43b3d5d782029b1db91507a16cd1b8fa86d02d86761ba0d9e3a310e80d88a0e5"}, +{ "535000", "b4c2ed2b12c9b6ee617058231e9099ceacfbb10e344c8060df631fc42cc276f8", "1cef714d86e11d17fccfa377f5550acbdf781a19f272cc8917c3c9886b99414e", "779c713030d24a5f0b3477edce23e0ad33d798be1c5f70bd65cc5c982ad1f480"}, +{ "535500", "9515324744b14c233fe0463842b81e99c1c7bb28d99234d0c2126ecea9a3250c", "c96091825c57b11639c7eb8ac6f6c76d48c4507af32c1fc95a93fad60e5b1a78", "e7d3dbd4004dfd8cf66cef4a21ff7acbb71c07cf50f87ba69de6a2834231cf2d"}, +{ "536000", "ba4a67d76d58f76b3cb47b9f89792153db68285c94062df446d924e59ccf7b87", "6208b177efeaa145f365051fd3d5f9e82dba8c42f1d0d2b67635c4a908b7dd17", "ede7352ee474c6077c2812e5a598051740e885e16288a5426ef9d4a25f80fb87"}, +{ "536500", "865528966307aa0504e45931d75610ae56b4c4490c763198c1570a66f75b1f1a", "09c2e4d9405d693c07371d2eae527aa1c2311db979f6d2d0abfdc5467b81cb65", "d2d0a63b54ff19d1117c4fdb9d2f11368c1fc79f251ac539c05adc085b65e04c"}, +{ "537000", "c3355c3c49454bb38156c96fb23c13fe9e5fb73129bfae6c61ba4e6d1e46ef00", "29ce20cbec7687f75730f0e4be6c672d1fcf96baa9168eefe3030116e7f06b63", "818cdf33ac00f5a623486e47a6d74b145e5c61595b57055c3cf73041a111eb84"}, +{ "537500", "895be1cd157309627c65fc37e677a72fd82f27d0418e6b43998aba564d205369", "d5e4a2bc8d014079e205050f18f390c776f5b45940c5835ed995817dbcfb9da3", "4156fa1dff52b59ecc3a803a3949a5d2a100791e8390e10c10199d93e278f15f"}, +{ "538000", "99248aee8ec1681099e7018b3f27ff7d48023639c7a16f846ceba99bfb8b6794", "51589b8c95d4c555e3e85904368362e86c1ca65ee73cf4b3a56348352d48187c", "405b2b52ade6f4c8b82ef01114817f7d7ed72fc57cfb977ffe2316c62364cab9"}, +{ "538500", "8ed90c82d16b675f2e1616b4e6877fea7d223f4c6049c8abe24071ed0cf55cff", "0952515dbe216e7f8705998796c926f16186b5d911466f31d36255852c2a1740", "6b7c8f5da9b0681690e1f9e2be83d1b7ce20a9cd4a2c060ec17c7dde95464d26"}, +{ "539000", "5eee066175978a2e04f8070ec0a1c5e215afe79e6342f882f272e3ab3e5088d3", "a8fcd0b0db8bf7fa522a86757bc674077b64491860fe1e1c346d48b5056c3625", "50e3d3f8ccd7d7bdba7aea9f18af6b137ad7fd5e4291563a292a43a650601f1f"}, +{ "539500", "1fc7f87c388bd6e524b114ae6bd9654031d2cede075e50c5070d5f7492238b49", "86203c750603c2b64073e488e635049afd299e58642bc90cfc7bd562fa1372db", "3487bb31bc0ae1e79c810aa261000875d1364fb97719df7e5ee43b72c28520f1"}, +{ "540000", "c7c3d0e72955da1daf3ed29a7f50e39bbc72a97a7a3b9657151e2180b297bfdf", "d8789c0edcb9150d9cf88b973a2fba35c0e8a13a79e9f5e6fe67eb527f100dda", "65b14ecc122d122661553dd1d71b49450f843080dba874f5baa6fdfd20467c4e"}, +{ "540500", "078244b881a7ea8079cee149a21afb1f3e12513eac743435b26fca944d1f8c0a", "b0d2681f5339e6747da87fbdc8eea0947f09458e9e121fe715050d97d5380b1c", "117d776ab41d5019ec163153f0abef5c27f093f6b88a8a278c690f856f334cdc"}, +{ "541000", "c1fc5936f601dbe88f86537a73e3082d817270cfc534f985e6aadf1e69017c62", "c5025d93f22d3c16cf3f1be03756c8a04da4c330a8779bb156b6d6812b65db25", "03884521ced22f201c1a1e326eda5f100a82101bfc943109cc364b7ea7ea0ea9"}, +{ "541500", "f06fc398ee363680986ea85bba8897ca25e7d7398defc7ae5dea8950e5e10b9a", "6eb30b839ec9f6b85ba6a68be9a25f4ad0d72cddfcbcf5bd4346e61905e1ce37", "275cfe4e765b4c188cdf7170de44f22c15b868f25d0d6b12767b748a1b6513d1"}, +{ "542000", "f1133f6d4e5f03eee2ab13868e8a296ecb14fa9a0fb0074e5fc3cc46a1f7f2f9", "b1827592124a51a20ae293f4e824c8030eee78ee82ea039c27e427fe4d2da5c6", "c656ea7ef821db02521815d458246f5f692cab0056c7b754fcf9bf610916f4b5"}, +{ "542500", "7892e32548d849918dd9946be8adab0f8d0842afa1e9f62c066d27924a96153b", "421009927f9b4183293a0e7a57882322f87b30137239b6db48168b25d1fc5ede", "93910eb3544aca246ca379af94f4d0b102ce68aa282f899386d656059ac38370"}, +{ "543000", "656da82150e03b0f6920c13ae9f012c768ad1db9da51f3cb36cb08f597c944ef", "3fdc935dccb715960e745f505147ea8508aa5ba7c7f2a657a14ee46eec52732e", "0ccabbaaec21367052451bbce72072144a79388d4ea4af9af60e0bdf370632fc"}, +{ "543500", "9c3e877261982dd30c2c1c7bf6604e64b22fcb0ac6f1f31d133ad853e8b2475c", "058abb454a8f38b333a57e220049716ddcf596ca81ed33fa28772cbd87968bf2", "8edb00afd9e9f985db0b5e3a2fa076945cec714937afea659a981a36990c6662"}, +{ "544000", "1ecd239bf3296b13b04cd7aa240769324beb8a9de6e35f10c193ce60adfcd2b0", "7321ab6022acecdd7ec7526d7fd560c768da79151c01e409de85f70e8d9d9bf3", "1f35ff2be617b3d5298aaadb9cf600876c300bcda68dcef1c271c2a2e1fcef1a"}, +{ "544500", "ab6981fdb795d866908290b102477a670822935da8f8af9c6a32ee740d69bbe7", "c1eb309bc65e67917e1c46e7d0f232900974267e048abd48a1b04e1d4a3172f8", "960d00f60661be6b528eebefb975b8901243626368ea7f2507748e9c091a389d"}, +{ "545000", "00257b2829d7c11f95de86dee675a7edb80dff9715bd2ab64d7454182f213a0d", "bf13fcbf0b1247b11accd940ac8772789e081f0bf1cb70b1425d6288c69b1e76", "8079693ec5c445cf8ae5b353b0cda42cbdc95a417fd85f7217f98d2b42570e76"}, +{ "545500", "ea64a39237ad3d242cb2db3a1faebecd3b20c682383b014227a3f230a3345dd2", "09c175ccbaa02745d5f72bb6f68a9b32cac259ecc88aa1f49bb30d336d79bf59", "f2cb03e606e67f0f17b73375d215ac36ff167765383812b927792c3789d92c13"}, +{ "546000", "efaebeda777c28c7e35347e84da7681aaa14c502d53698838eea8aba6e55c1a4", "79194dc97f5c84f2a55ca245e93b69b5caa44c6bd5e581044e2e26580bcf561e", "d937a59618f4f848d0b4e37e1bb1239e1a036858240f70dd164615ed43af6f4b"}, +{ "546500", "bffd9b66e5207f5cb60bcdce5dda495ab78fa6206aed6981bfeb3ab4961ed56c", "2e133bc3bb1e140288f0abd4ac9fa18fc4e30ba6fa672f75cdea8fedbcf093cf", "157052919d1a72c7c79ae5494d54655b76a4af0aa63cd2205a819cdf1302958c"}, +{ "547000", "b7c08bd8cd06070b6b52aafb511d26a3e4dde18e15ef004576de6c06024f2a30", "6aa7c21876ee2145c6b97d41d858abf162abee2f179e94e354799664f38be6b9", "6d4eaa24d3d7467bf302941fe3210cb2702ddb5a57f6e1a79aab790c72bd3d44"}, +{ "547500", "77b94303d50c7c640f68812f0dd13cde9cdc2b43c5f6e3fa4c99621be61279a9", "31c6dfbadc919ec783b0bdada382c4c3e1204008b245b6455679b08aa7f2a6bc", "17987eb01c4bd98d605cb76a32be640687e8ec900b36680bf6dacae55bd32f3b"}, +{ "548000", "bf973366b8395a897b56bb1f9160f8144c40ba17934fb14b46d2bdbb32715fe5", "a732ddef1fa97dee750cea03675a6eb9557af9ed6314a162f5ebd8ded9407698", "d78fa85231b0fb69790e643c079cb7c34d1c114fbfa8c1d7712b01ff71805749"}, +{ "548500", "c2f20ed6a252cc714238efd5531084bd5555ab8ec65169a86c9a0ba97b2a7eb5", "d029d1bf6706c1b298d9f7ffdd53a26b17704433c42683bc02718ef33d2d70b7", "a2464ef54773a2cd6dfdbf05187ea2b0e1723b3dc22e31e1480d414a4bd13943"}, +{ "549000", "7e07ebf8ad3697390d81f7381637048377f461e46030c8eb1feb17eea4c9d3dd", "1f2183d7618eabf7356a08a0486675b0163aafe13e6b27bb6179fdaa59685fce", "ecb2f323e8f843183dac9fda0ddb68aed54277bbc0e5de60b2ebd0ab37a0cc95"}, +{ "549500", "7ce04ee7a21eaffbe862646c3a301460da80cecad0e9a66a157bc1d0c335a18c", "989d7ef547727ed49f342ae3681e86247ee5b6ad009a863ba0dc517e7977790d", "7745d4f12b75c63a7213bfed8d46bdb2d0ea5f75d9765aa47ce7a689a456be59"}, +{ "550000", "0b717011e4c14ba25388b6be779ec7a7fa2939c68a49ad5fc8cccb32a3fc96e6", "d95f6b2500300308ce3f44e53c38e6f0eda793b3e1d96f698cdfd8d70888e277", "1446f3a94e8fcecd1819e47eda64932ab5f7cd161f4801b96d751bd11bd8edf9"}, +{ "550500", "b1388fa70e3a79143b985bbe2587a8a36a3ce7f90dbdf93c312bf375b04204d4", "2f81d9add40226b4b3d3f2466a2330e412de80bc31cf3242e0f8e8c1f45f1a88", "2e0c55c354dbfa29d8ecc9611013fd969f5a843b8413aa79d4b5676d9a79b7a1"}, +{ "551000", "b0f768d89c0f0e5929e41afa3e9711a2f6dd04c71519c718ec5a4851f13ae4e4", "2b1fb05c01f17b3eb7268d552a99acd306e4dc0107985d6020dfaf4443dadd73", "4ef4d4f9a0fe87fa3b1bc65c582fea5eb43b00e4253b97bd536eb342a3dd3457"}, +{ "551500", "891da4a1108be080247fbc0089c4cbc2922d25cf2285538261195b41bfb48747", "e5f1700d6fa46e80db5586d1f3261b758d374d43adcfbfad70ed5112bb1bf603", "a7d24449924bfee8b65e9f093a2bb9f91f104687d03bf464ac13500b995ede8d"}, +{ "552000", "8a4da9058e5aa3a483af0775ddb984048bec5a52dfefe711d620a0d179856ee3", "333c9af8ca1f58b6185db26d60b4fbb955176320995ce208f18aaacd277b4f1e", "bdb844ca20bec8acc9248d5af27b3dcf24dcc409eb510831d512be7ac8edecc1"}, +{ "552500", "f290fd729e75722394720a4b82e34da44d640af62c995fe6867fdd9167ba8335", "e85093bef089d344639461c61bd1ec7819d5105b4f984d423041d035335e24fc", "690cc872111b3dec9cc8a048824d722043ac13ef208e12d83b596977cb444569"}, +{ "553000", "2558178ee645f229d1b39f11e8bc8e423e6665ce3e7491ca195fb72d8a13034f", "0a823b23f9e2761e8f32e42f7bd569ebb56869af3a1093d7a170f792605be7dc", "16413e820e03f1fde3817eb61868061671bd12df892e47edd173c9c9184e7455"}, +{ "553500", "001c1d53874f0032ac25fabae2f92deca9235bd409eaac1aebec39bd798830d2", "d36b5ccec99827a8a5d775d707a82836c0a10d13bf9199e25a3c31bd17f66370", "29bde729227b92003a7c09dc8f78dbc155f72129129c2adc973277ce578323ae"}, +{ "554000", "e2710db357675cd18df933733e23992517017ab0507fa218fb45bc9f5d812224", "786326555bcb406ffe22d8dd499684db1b8b70df508572f1ada7dcd6eeae85d1", "418767697d50c0e474795dd78c354da21c5f71eaead7bfd37d8f74f282b581a9"}, +{ "554500", "cd244e1a5feb9d4f3a6c51f92f1c9396b8871ac5a20cf587092abb68b4fe2eec", "e7a78e8e16dc73cdf9064f039df1a67996bb3eaa744f2fc0598bd07519078b24", "9782647f3aa642046e2439c624bf99de6355dbdf5bab50f74ca65512369b6b05"}, +{ "555000", "1a6ebd86249e3a3837d8a1eff644e240333704c7f9c48515e849578016d8fc8f", "b5da194a23915c042e044b0d3e5e1856f7640ac8344a013d7a1c459d967d6eb0", "8a70c7be79d5edecf987e4cdcabae2f6dde5118fd8b3fb967ff40fc054197ba0"}, +{ "555500", "978b357011addba581355b92d3faf71397a7c55689ac4fb0d4a6eebd8409f714", "519677a9eca60cabdfcd5e888ecb570d09275bb7e2585e9226a9b664ad0d7fe4", "675bfea85793acff321a1585195718624421451f27c0642d964ab066a1db35e2"}, +{ "556000", "edc28b6ce373cf5a5d13e86ffea09ac385d8d2bd251ea07617b10abade558e12", "7b3f6c61707185443f2565ad2f228bcb006302a1bec5a203f143e730c681a9c2", "4e04bdcc89e6827779bfee9bf287c347c564e6bd2eacd870b59e22fb6fa0dfd7"}, +{ "556500", "95ae0bac1e11d4df7fcb554f665966b3bb2195010c0cddf48d07803743149578", "1c9c7ca6f9c8b40134151daca7a7cd1b7cc24deac24aaf2f3a450b34b74730ba", "a8e00ff92f14de5e42fdf72a2f432c30cbbc9c0b4ae93b6c44ab753e272b3c99"}, +{ "557000", "a1cbf8cd746fe3b27616f6515149cfb57408d82b8147c19510ad13806b7845b6", "2287f21d56991d98d17edc545f93a85d01b7919fde25d726cc9cff6f62d97461", "dc13f0a7ee84fdc2a585797efee7a60066331d73320701861c538e9233ca36f4"}, +{ "557500", "1cd1617ae1474529b7b4f322db9442763fcd418410a3c3e918e17f13966491d4", "e71635aa05a9aee0ca857b41574d348954419959f8782b6aa3b7a3e0d3b6fb43", "1a0b713c663485f64881db18ddbdeca1fb0ad1804e79ccf3508b95cd57a2e2bf"}, +{ "558000", "ecca0843b0d748735413e34ca513454ce2497271cf04a9d12455f0bf07c09f22", "c3a7537c5ee0d6615a53e3e30cdcc6433a554a120756be6247f3c3b703f023c9", "4d1e23b9f0015f6f61e2dac4b1cb9eb95b57e341b648a17148fa52009f76879d"}, +{ "558500", "0bc0b2dc367328ad409219afddf852412ecedb43e048ee73449cdfa5e152159a", "64f4cd8ebaf6f492c200b11b080c521f4efe87e777818f9012e969eb2dc0fb57", "e431dfc02248b71de80ac7384a53e01a05ec14e4b4fb45bde40887fcf2704978"}, +{ "559000", "ac95a1595559d38fc68c9dc48d9af40b3e31d71c292a83998398af38f09b3fb8", "a65b3a0e37cadbb31f367a83edbc4c70d0537633af498c9ece211c681fb9f671", "2b96cefcfe13308712200f32876b7a6256bffa98286c8764450ea1a83a442067"}, +{ "559500", "06afcb286229def7721d7a5bfb22cb59f1b25c6aea819bd26456d5fe0baedf74", "b871a3c694108b366de593c52d6a1b3c38af1849b0092e5474275258239e6088", "24417d305aa20fcf134683ad23b967f19e186a64252f3bae6eca3e4e4a3ef57c"}, +{ "560000", "538bfca7649306c7ad77eefd31a7cce9b81ee7ee9d20d97322e9f785cb555afc", "e08954b12673a8e87fc4db6f848c2129d39286fe856ab80f3a11480a82772963", "7b06510d88d1fa90997ef87420a1d1a1bdc5928428203a648429b628d781d717"}, +{ "560500", "05fe497d72e403e9753264fa5d4a7348843e07afbd260e21fdcb9898d9de63ca", "b538d81ebe3d0367d4820f155315debd0b078100fe17f3ec6a0c1b1d989fdf8d", "0b1da1f2ffd782650bce992b478854978c6664b6c481bf27598afe744302ca7b"}, +{ "561000", "b80da09d4fc326223399fac5659ad647dcf37232eb63546212c7b951d429effa", "014c43fc1995d966785af2772de5f8d4738b44785a2bd81145d32236931bc978", "d14ee2fd9bf678f965b7ef6d3f22b032a66ca72f433ce8334d2845190aced1ca"}, +{ "561500", "998927d54433d0ea4fe19a4ab0eb8e08ae656e8cac608e3a824bb084967a37e4", "a7709319ad385d1345ee6171bb57bef2d0a648278e6cf763068496eca01d5315", "8e3a7ebd7addc79667a9a8373b6c599ea24a4ed13ce6a936535a81eb275691dc"}, +{ "562000", "a005e7c48077a108e353402f478f0f3cdbadeb95f360f6d4d056ec8aab302f7a", "ad678ad8a4b421f5211b5953c3080ffde18f2a395f5f77a467a6a3991e155b97", "15d1e5baf244b9c32913691d2c2c300104b18857f5cc173b53a4d9306c0b8c55"}, +{ "562500", "cf4a618bbd1d4eec4f6ca3993fb2b3ce901592c365c2b7526c9de2d0c98cb74f", "05921bea10fcdc426b73459e8ea0ab421c1635c93b60ee8d950cfa0efa91a126", "e99c2a2cab3e0d393929fda25bb77a7d21b9660e78b02f36bbe6d9a35ab67f9a"}, +{ "563000", "ffcd676fa825e67eb4832cc72b5767f50fa306f1dd251055ee3f623d9fbf4d6b", "f3fcba9c0dafd172664da1d0e692cb1f4e898f23eccce5a265104164a5ece2d4", "26ec1364d9b1312f0adb2908c1447cc89c4afc51db4b238217b763878b353532"}, +{ "563500", "5f96af414cb11afbbcf48a7fd1738fc1c8ae91dfe58ccfaaa7149264ce34c5d4", "54756714dd75d4cbcf87b452238296c5acbece0f991ff2cf3b239d6af4b7f4ee", "5d10e1111c38741986dd46de80f42c6c2410281c518c46ec13810ee566f6082d"}, +{ "564000", "0345b35925619ae8f774196dbc6ae52b2d065ee4ca6f9ab87aac366307e1512c", "7ccabfabcd36f82cc3195d587e6b530f2e303525e253d84376f02b907e1bf611", "1fc483c4037a1e0bc2d4b5f638e53c9ab8cd1c1e0743ad3613797c307a0cdbd7"}, +{ "564500", "478fd153799b8afd93360f4288321ae7e82aa7bb5474f13913274834bd4b1ba9", "b73b7af475c03ffe2bd0e9b09f32a966126d650007f991cde96bc8ae208d2844", "2672f60ea8969e06815e56c9241a79ef6249cbf7be3bea3752394f008799b8c1"}, +{ "565000", "4bf82342209df889c321571400c9170621b17c9b88b60b609a7a9a31a4e6879d", "d33e0ac1f8f8614cfec0768dca67ba99561976ef142a62171bd596ca26265462", "d638ba536ad22a53e0a2768f80102d958b1ad4d24205a4d617d9cb7d082e5537"}, +{ "565500", "18ef43d2230a09c588644154757d4c3136a0dcebbd1e7169349f280be113ec99", "d3cff22fd147792fef86c9d94f7b8553c555a925e7038e738bde608c83ceda53", "0b5c5018ae69065cd19e245914afce8cea9cdb05f2c26b1cbe6c5ba0764dca45"}, +{ "566000", "178cd3b2773545e457ec933671f4b7e0cfa269454371789d79c4c73d879fa497", "776636ace5ca4a51abb4f04c22d5a2a0c51d42368f43b8b776299b087d1bafff", "9bdc510f5ca8f1205df553f32a927022ee88c90f7d2c69b4379b06c4b62f40a4"}, +{ "566500", "6e70ed03c1ade6968a6f18aed75a42130abe4674a9cb3d6715d5320474a310f0", "9e51b370f5e5b6dd65ffe6fc854265dc071b7dddad6a68e25a6082d60a4573e8", "c7f964bba1c9b43b1ae9018d55f6b9da0d900c503d266916ba781616e67069d1"}, +{ "567000", "6a0b1d677c5cc0ce3f890ae8495c70403ffae874414fec9e3ec8b3aa73bfbf12", "44a2fd59a3f18b4d59d7bcabc842bc21681b3c82613c95038aec10315bfdc050", "382a6656d846da8d438bc7223b7461859732ab1b06a80b454d78fade676c7c64"}, +{ "567500", "aaa507e4d8344e885c748389b8812c28ab49533b13fa635bb345a4495be34850", "f0b2d2e0f7477c8703fb6c7ddaf4d22c17da14d6bb1be606d96b4fe23932ff61", "e52ba28cd8136cad574b671e145507841135a991c1888fec787df0d544932e1a"}, +{ "568000", "058e126ea94bbb99030e2be4364db58bbe0703c0fb4c3155ee7c386e19efe976", "e68dcd0c11aa8d9b09161d9fdb25196b0b02017743235c5e77c83314139abc6a", "49d5e2d66a782195a1e12691f6ce53d9a07e338eebfce99008c280917ddda751"}, +{ "568500", "369e444ff13a9ce379c2c98e70e2e50e18c823b4b43d51e57224f9d7bf7c2a82", "e5755456750a9a92ffefb86ebd18fcb6d4f790bd51e47f1dd92d5d0db8c60b7c", "400e3e42c56872793b2fa5cc0edda233f746bd4c13f7a5f89a02d07985170c8a"}, +{ "569000", "50685dcbbd12f30781fbb546d1a4cbc349244a2d6e14ccb1530059e4073fc0d4", "5841f99c2648c1075709873b22b8bc25695c01fb146b0e82291b6a0f5cf16fbf", "273062f388221c9d500cb7532dedfce411ea6129fae1ee2ed43d54de4aa6751b"}, +{ "569500", "452253574aa43c9f3ecd39f7122789bcb9c83e343843540860b950ff27d673cc", "2ab70f1d2aa896e8a8495df628e675c983e45047d719a9e8fa0804f34a8f82e9", "73e5be387bfda500adb062cb6229402555b29d5b9a83a928aade50443e17c68f"}, +{ "570000", "c1b6627d3100900dcf795d2b684e83d11a797d2302a3bc058dab61ba109e5d08", "997761e1d03f77cee9256dcf268f308a14899d00386cf1cdcd9df39a57ade810", "781e60d9004ff259f5c679728c36e1824abef28335ff874b89d5de2a02f40eb8"}, +{ "570500", "7cd59e7583d4c4878b1dc3171dcbab4832d2c4d61512d7f313ab88782a9d9336", "0a439cac39577c5f0188a201ff1ed831ed2fbd5d819c6682d7aecb2e4b77b7d8", "51dbef7173c663e33c223a0e5cf70cb857efc63c4cc9175f9ba9b817552c94e8"}, +{ "571000", "6aa099647512a9654c54e730e3f1d4a1fda25ac58387503932ded2817e5b446f", "a629a59a6420e7edf13f0a7dc05a918f86f9fb337459a1f85b65cdc71b301d92", "1413e4b5c9ac9c379a8c558e0e20eb284818837e07799e4ca0d01fe5d53429a6"}, +{ "571500", "a3d2f0b075cf3e735e586c69c3eeaf7a07cf0f391e1a6ecada1327abe8ab8c8e", "c97c75ac8bd884337edb7011ce4a68f31d1a06f477d821b9e473614f871e059c", "bc488c752c8548cb78aa967bf11e8d2f8c23c6f011a4d609746ff18f27f0f3d5"}, +{ "572000", "154d5a1e996a34d40d3aaaf2244d5df055de5902201bbefdff166b63d440090e", "38fafdb36a68381be6d3a3f358ee61f1998c8647949eb6659f8794c5d84646f9", "34bb1f2f2e84acad99d095f9d37904ed8aa9a72cad03f6b6a20051184a53639c"}, +{ "572500", "05d47c51813cee5f42bf7803a627ade017772b7f4e734fdce5a824edbf480359", "ce6eeaba07d4a7d43ae137f3f66d7bd2c3ff0b55b973c0e87283011f58f94fc8", "d5e8c7f3eaa1dd7e2e9e86c3f904fa18066afc90f19f5b09b5119ceac51383e3"}, +{ "573000", "2cc24da51032f6db15842996a46a0f01e17e7c1fa178d34f4d520e57a1dec5f5", "814f5511a95d2112e9d6f5ff9147e4af6d2d14c674008901888a59d77adc0127", "97cf19530e18aed12569602045be833d526fe06530a6358c515603de77834b91"}, +{ "573500", "5a412746451823e5fe7cf63b331c59b6b1808d176c1f3562631755a1aec62267", "a8a55f440729934a987fa7bcc21e4bed9ae4cb4fdda5bba05f328d33c1c93dca", "5c9ee5926501ab49698c54a8eb543b5f212b2a65dbd6b3d71bcbd04e9798c411"}, +{ "574000", "4e71a21262bee73564eed3938de4c2a673ae763450fcb183bab52fc3739e9307", "f5fd0fbd347c9146a3356914145926887833b394f0664b2e5d098660848e8b5c", "cc86ade9b13e059ed4015a5481ef18d63069f67a52d67749e4abe1ea165d62c0"}, +{ "574500", "bee3161612969794e4cc7811c35fb9fd844623da6a5b5f2dc38f32d50728ab90", "ec00c96d649a6290cd6b929e1a71251e4519498493fa0ee2020ed494012693b3", "baac4866328b40b281dba068cb2d3682cde33b52ef2101df94ce1883d61bdd9a"}, +{ "575000", "0560ddebf2a1fefe36dfcbf14c0b9e2101445b34e79b4d2d2f7c329c1dc5c97a", "58a5850806bdc8a70223873c23aa3a5975634c989d8ef4f4f78fc0b71c025a59", "2cf5c97d7e1dac4ea45e91316928d92e4b74440d2c059bdade7bb7c1cf1d45bf"}, +{ "575500", "077c9db46dee33b8fed0edbe55dd09ced1c04eb22096d9a7f0a8238b764a9005", "a527ce25eff18c724535306c76670e1a44b010183ad970d41e4168c7e47e8ef7", "db44f4bd7201dd8e1b9deb53e77c7a93787e9a992ad6b9446a3eb12f28bebeb1"}, +{ "576000", "f9762a0e8b01efc84c09bf94e0eec3168852cac22bf5e0e657957ffbeb857c08", "41b866640d3804e09ffd386d7f6b0cfcc5e95c65991fa0b753c875676eec7c37", "363b120084d9530ed7d17cce535866b196dc4d39aba6ba1cc875778afedad3ee"}, +{ "576500", "fff9ba66ac3dd62ff0931e644ac522896b5e86c2a23e04bb4f2501145dd96b75", "def321280e76f1a8aefd6607ded8cb73769de57f19c641b7c6356e60105d89a6", "c8f349560443ad0a472731d00b20f77881ff0000d4e429d8272b13628d9879fa"}, +{ "577000", "69c48c7908b7b71bde3ba3aaacc99951cccbbf4ca98fe699367cda9c2101efe1", "da1cfb6020117eb45c262bdafdc11ef962f6156c0c95e68cee1bf1a2b7b9a1e5", "b6f18f6a70537b73dc145452ef80a31555c131c5edca2b7815a5b9f7985a07bf"}, +{ "577500", "9c563371fc767b2343d7f1cf6f23e4cc7b42aabb564e94a5cfa940cd84330cb2", "33aaa085f7076d2841dbce57b42bb7c61739c76f041c130becc350efcbcb5138", "045c19b336f55e018042905e862fe43b2b2dc16a1b8e4adc317184e91768251f"}, +{ "578000", "e5b36705e126028107e070cd6b748d0ba1820ef3f0b7cdbd8c60a822011afbe3", "b2797c8eec34eb94ad7b5de3c93144e6511d79ec389cd2b3037abf705da704c0", "6f8eec5d3f44c63f9f3a3756b7458e19608fa7b2684463a59daf70abe2e08a13"}, +{ "578500", "0bb4c3b62c096285827dd7079f91bb367f08fbf323f01cc27257c6ad1b6b09f2", "2709c029d1cd3164ac618ca33d9453913f52247ca266755995eba29516fd6693", "00483a8ba5971f1cec76a0d4981b68ebbab3cb8d85081f517afd5fb6459b9357"}, +{ "579000", "62ca69f749191230d6588250d41ff452312e141c30bdc253a4ba473d3736c8fd", "9690b50bbb4fae4acf7114beebb9c8f012328638fbafd2f54c18db4983c019fd", "2d1d6f2e164c7f52e9d62d9822d503c15fc45afc1b5cacd362adcce8c11f989e"}, +{ "579500", "ef36ef78010479cc9664a2e7cbbeed19da7b60b990ae1d6ca1c62815b74e4ac7", "dedc37c50f5ee81e9697c49243e55aa6ed5c5ba8d1d56305c5120b308600fb6c", "46275bf5cd6ca0c8c1d87fabf04278cb022408a213e75a118a33761af59106b5"}, +{ "580000", "439f43597ce36aa161cc2c4cd7c25607edada72003a7fb681be2f6d8b714d14d", "be5636a23710b20c61b3aa181bd75a4e0992dbfc1d267be7c66a3bb459ad10cd", "055fd581f041fb63c623e7a7405d178da44d129f6d854ac6e3627230e177d688"}, +{ "580500", "c6b2c13db62622a7c3ac9e8072840de5d24c34f6337fc3d8f826933501245deb", "25eba3116b640e04a77b843ad79a25847d31c2c5eef7da98952ebbb526440eba", "6da7cf2ecb2cd071163c66ffa5e8eb3b392b48992ae3b8a66070394cf5d0e167"}, +{ "581000", "4dcd0d20d94245063d630bcf6d8079cbc52dfc522c0e320e39c16ca18853cd6c", "ee3c988f0ea99a39c2cf69e88ba22aedaa2710f49bbaccd1ea0b2c1ee65648d9", "58291224ca13b2ff40bd30df8edca325b0e3ebc5564b218d472efb7c50837a6f"}, +{ "581500", "44b084102871018a5db5f990085f3177856a38a8b727a36b29837c34e4a8ce59", "6d6899031aab90e68c34f4bc3c1458960c7debc0e5e88de13bc0d29d9a4f1406", "7f6af65874fabff02aa73e1351f90945b167255db2ada7ddcca6192a39fce9f0"}, +{ "582000", "4fc26f1bccf775fbc7314ca86532fffb93b9be94bc6f1bd75fbcbe688eb9dc1f", "07296b68ecad02d38df4dfc0c927b430ce4c978fd42772740cfb185d1f73cf08", "2149719640ce63893636f94b837b785d177c0823c548b7fdbca39467cfcf43ec"}, +{ "582500", "fcdd7ac7dbd7a3ec5bffcf498ca341ea6f45eec4f07fcf5d838805979c154e75", "1fdcf21608195ac2f0076e8203f72e8468099613e8edd350440efb4fa495de35", "8f746c3c260e6c70bede298a49413b678bf3c5adad82adebf03c73efdbca9dd8"}, +{ "583000", "d32c77f1ee2542c91734ccfbbba36b35dc4b76db17374b52d514ab45e03031bd", "d7414a5f1b9e801ffdd889f95d91b381486c2b7bfd718907df3e4f3c16f831aa", "a786bd1059f0d53827f3fc5b95f44a302e30da16bde84a9b9f6b635b0b57f1b7"}, +{ "583500", "bf8b25a2a0b19d293bc739d63786a6e5be7cf111d60d6cfea462dc2cc7cab22d", "c03d273bfa3ebeff31d43a7a1fe34b51a5c968676dab85910f61691ea66cd879", "9880b1b9a9f0fc497d0116b07708f56601a9f0d617632b4300327e8e3e3c220a"}, +{ "584000", "b3ec434425ed197a317fe360d7f2bdd065a7f167e5c57bc9623cd150df2aa5bf", "42bd629da8bdfeaa2aff0cbd4092f1db54db6da4e4487a7460ca7081849b1d01", "985da906d7a0a79f9960993d47e5627543a6d53921c96f687d065030e3fbdbea"}, +{ "584500", "f09dc804f47fc9fbd5a391883d0be1d3ccf5b71a69e9c2571ce1ff55b83422df", "28cec5b73ebea11f29daf62db2ac9a594a7497ede4087e0932881d39343d15d1", "fa2d4b9a933dcb66f6e57dbd7a13f7c2ddb67e9701aa39a77a520f14586159c0"}, +{ "585000", "5874d180e9c48959e292587310dd81134eb03197f0257be1516c7c50248fc3b5", "c5e42637b4e90535090b09f2d90d7ab90ce46eb3255ce6abad941ff07ab5e0cf", "403a7015bedc6c32d9390a083ac82f7b7afb46aea0a4a83d5167ec7a67c2a447"}, +{ "585500", "a6dd4e58143b11d190e168b1dd20fd7da47ba2af0d089f70bdb5ab423c8f47fd", "134ef498a9bf87099abd879d68ad7d67ef4dc45b63bc16438aa0f95092e34c8d", "d2ee92dad9d11746f6f8dffbfd0809108733f964b345bbdbf7694a0f6e88a17d"}, +{ "586000", "5fc5f5de827b01b620304dc74ea53a0fea4f814bb51ec5fe3b6c74ef560a5917", "e1d0845de83160f08be85d114882976278106adf7a3c16ce16ff6f08caeeba7b", "9d3de6f846271f15a037a646c6332b33fb288dc3fac8dac4e694f5c903543b35"}, +{ "586500", "2d1270ba120a5cf1427736d7f89cb05c42af508e0a0038833c9445dfa9c66fd7", "be7998a06e1fa3910cf77a7cb385cbc6933abee919664bc52a52afa5388c5b0f", "8264179f305f8c60ad40a69140749aa1353fec67ee02e3fe09b0b9f51d5c1d23"}, +{ "587000", "47ae47f30d7d51e5b874e5ae103aa38208203f2a380b624cbe1ba122d222f9e5", "81558ea382a62cc93ccc002e8ba9d88058ebfe683b05be16fac0d84612ad2152", "8acf0fe6fd5d74dfcc4c012fcbf80cb0b93b7d212c1113b6a3f5796f9f54a319"}, +{ "587500", "a558bd54422bc5d0a90c20310f81d9901a9d3956f5d5505a5dc50b6459ecaffe", "a8994820ef7c6f2fd8d9b6d710a0f83b537ff6fa1368060418cb00ddf642f357", "746fd31278c09ebf66550d76a61464e1dc2dcec233acd70ced2932210d715156"}, +{ "588000", "fe5749f9e8ce47f885f4335cf2b24a6659913ed62e7d5af026ef0470004d4983", "87e2b4277260305d5bfbd921b2d4592e180837e092f2acd3896621cffa5228d4", "46bebbbb161226814d223a33cd8e0a172a30febd134800c2fc583eb62989464c"}, +{ "588500", "4c798283eb8cbfca17647b16a919d49b77a999d0bd319fa624ed665b30172e21", "a4c43d466e6429ac399cba93e1a594703176f7d1d7f86990936973120554c72e", "6b6f4b3290e47a69dbdbf251a00df4a2b7afeb7adbca47a41dc590d3a425429f"}, +{ "589000", "f8c9ccb89cd751d66c9e2b053cdfa670556f6dafac1e67a12f8bf06790c9fb93", "ef76c7bdbce08ea6dc8dfbefec9d64b2bbf3180dc4304ee7e39d8c098ce3602d", "b69b5f0e54c78368bf62eafc60ff13cb2ff8489f8421583f75097968784f1aee"}, +{ "589500", "0971e83e6a813fcc290f352ada5422a0f48b12e15628f9522d1ce40b2fd01e85", "cd5ac7829f9c4de5b606b3a5406383ab2634f09661977f867c47d58f89f16081", "31182ab94364878b63c1a91f2e0f939202bf757bd02ebd22d88ea7b555d077c1"}, +{ "590000", "cc8a0c71618970a1cd40ecd78572568e8522faf1c6cdf597def52feaabd15eed", "ede2c72e45aef2c244f56183b127ef08f9137effd46386eb8013f1435de42f08", "3e67a14b9f791f361630904de1369a3caaf2472a593ca037dfea9e0a5985eae8"}, +{ "590500", "6c876707aa719eef0d5a9534f9961ffceadfdfa16e75a4a8c7f5c7822f8d9945", "44d6b98fec0842acf25460f93ac90ce132d3600c752bcfb18d3e4bea90b9e052", "c5a46e6e838d286e58975e95cf4a8e300db9f1485a2c8e1b1ec5fcb853ae9f6e"}, +{ "591000", "5c5a7be46768f7b29d8912feb8eacabb2c592fac374fd8b1c9d74124a5bde94a", "b725f0ce70d650d386e7fae730da1d44a308d2517c91e0f6d6fc659316647202", "0877e7e5eb963694dcb43790291d82c01af543e18e14f4692a01f4509f7e3f54"}, +{ "591500", "4df0cd912fb5772a508f9ab6fc5dc26ebcfc8e5fda9026d682cdeee3350f7f99", "1a9e6cf241740c2f4f615bf2017473e6eccf52ce14ca3c244609c83411749374", "90e218efcba04b935ae73a7e1311b084051c3c2bf61f811a248430377237deed"}, +{ "592000", "5a9465ba2bf3034272ebb1a8b742abe5b66607193dd04f838bd9a2e9525081c3", "c36756b7c0b4f7577f33bb7a6a2cb06d444e5bfac823242a2208a74dfa4a5264", "0d5e09dda5e7e93d41364001d41b24b7ac3eea27c446208854aa5636a0a65a32"}, +{ "592500", "8e712cb434a6086e1068c5a36a70ac8382f8bd2df8f3328e869b5f74c4d3e268", "1f6f8f8c7b6abb35e1bcc30443a2112a1cf6711f020c6474ea2b987e122e2710", "3294921e4f70a5a69efbf0c3133ca8da617007c78f066f630af08aa65bf2a38e"}, +{ "593000", "5d4b59deb55edff702d98ceafe7e74fb2c27a9e82b3b8f38a747c0013210125a", "397321c39e0255bbf2f345d8c410a3a75f0cddf11f90b04e1fed22d57313f436", "b040ad6fb241b404d089784c592f8459a34cab1d98b45604e259f97cd2455979"}, +{ "593500", "efab77d82b76d1ba1f130c61a5146828ef22808cabae00e8aaca746c9701756d", "5ae3383c918a2d0de41ef7e68ecc81a14448ae6265fec8146377b88c14678583", "5edcc7b13d4dc057c9ec45bb9092d9edc9059ca7c66cec27f98291a40e514839"}, +{ "594000", "2eddcbffecddf8dd19c6183606ed678b8d3c80b3d18a03d1f6c98de436465bbc", "313ed4476687d320b09ed8f775c84f848b315ec7051a819b7b5db928b06b10bc", "85ebdce92d77627fb4f70f770b45eafb2ec031a0a7d5462d09ee5935aaeda4ee"}, +{ "594500", "17c2823062fbd036efda8d7a6cf9f02177470df9ab03a1ca6a49a4feceaa813e", "967817ffd15c1eb09ae18be9c89af301d4faca27bd1435a4c1b016328efd7452", "1629667a82436cdebe1c637f4b12892d0ccd4bc70506da6c4d8112d75508a8cc"}, +{ "595000", "0b2d83d89d4bfcf2ba0bb0d6f4f002f83b33532a9c72d204b84c3624b82d1d12", "ac1ae8086c27ae5dcb5491883fd2c00dd1936ce5ebb753bb9721795b51ac427e", "bb234d094a4a1a1fe506aee4b5db427ca92a0b608841d82d79e3bf83e2b9780b"}, +{ "595500", "94e93ae2421b77bdb8eebc5a889e0dbf64bf0af3a9d7d718b92c626186186adc", "58b3debd63420f3503c3f813e1fec6e2dc9de31eabbfe6a5517eda797c5a1381", "a58374ca77ddaa4242e2bf68a540339e00323538759b0bd33ca68f127fb8d638"}, +{ "596000", "e556867900ceab6ad0fb7923aaad1331b8a44fb432ed5479bc8255a9f9889db7", "5608f70ec745d7dd10b0d6650661ee7db9d15ead665ce8062892cdb60c51b81e", "5bf82ecb4e612f1a1290f08f79b9a17c4f6e705c54382d79ef4828d8a5174e2e"}, +{ "596500", "e07b8c8db8312393c02cfe1bc00a1a5ee6166083702d2db0fd24297095202f77", "3df091b27bde63d70fc8d0feb4da1e97ee21915b24f6be2a60bf702051c243d7", "4c713e21bcd71574e8ff3d13968e2c1ff86cf69348872a9319d0d879d0462236"}, +{ "597000", "8e07ad6645a83dc63b311fb7d39bb583980164e40032a0821d0acb50953b8ef5", "96c796666a2f4c215410baa022874914fd9c04a430313d38e98f6c5b743b969d", "08f78b239d3bd3b934efa4ab3eb676dca0e24e4c945416e22967d6bad3c01a74"}, +{ "597500", "6681cd271934d16f89af3d71bdd886f5d3d50f6ef9fbe17c4d95eefb6c770974", "e7909149c034c8ea84b92f77b39a9331560661cb4c158edda770306a4ed7cc9b", "dc6087c2c41ff738c099a11f2dd7e2c641f97f6bfcd2c343ecc372a0b78e09ee"}, +{ "598000", "92b359d658152c31b8c2f32c4509f3ccb1cc18b4544745608da9a230327c109e", "3f75a2b9ea70de0fdc330ebbc5f83301dd507c4e0fe536200402cdf30fd28a12", "5788ceff503809b984ceaf32a496e51bba2374ba415e3f459590a1655cefffc1"}, +{ "598500", "be474d552a4f17ec673478af48534ad3c65eef1752223ed3012534dcc4274db4", "9c304d0d24348fa013c7223f1e05fc9092a773e6da14920e628baf05669a0f08", "67e9375d6815cb71ebddc38da5965a779ecc8729333b33bef2c4646bc611a7d4"}, +{ "599000", "275ca25666031af015670734cd4fa02ea0e0b099921240991498e684bc234940", "83b44eaabc822a3d26f168dabcbb175357e1a37a025813fe30d5e6560418dc4a", "3d2abb751cfd15a5cad35fcde5b52b4e82b32c11a567fa0860a25f83b69b5cdd"}, +{ "599500", "f20a2a85028e0a3c65f118e50296794ae25821fb5dc0a59f415305d826a827cb", "937a759ca109521f0ad2dd2bcabfbdcd08508b97d2928a81bfe79962c59f6e27", "504abaa85e6013ad139e47771e947acf3c858fc49e0b99c5236d7f84723f3c6c"}, +{ "600000", "fde9cb0677887e2f966c3be87d1780db88353977fa2e426249d9b26b01be1db1", "74fc8f58d336eaafad2f515f0b5a5eaa679c82160f2dc54f35fed44bb845c395", "3972038fd2bc0007c3ca205a21ae11ecb66096006ab3cc9ac2350e2da7f1c506"}, +{ "600500", "ed2fdfc9d3b07cd7e4d4fb46b5cde484b7ea5cbd436608698ba0be6407928d45", "78eebaf2d54a3f5ef9c98b58e75325a263d7040a85d2757eaa6fcd9edefa8bfa", "ab51bcdc56ef14d0313de8553fb8ddb2b9f8d08f8e9fb42ee67b2365e2855cfc"}, +{ "601000", "3a7b3e53a5c38bb7d0600352a71701c8c7b961a9936d319ec1f39eacbfa317ea", "ae8e3de2cdfe471244ac6698534f60a82a93e59b36ff22135ad57f5ffa9eddde", "131208c6ee4f9db5dbcb53f6b21d9de4b1bd8a4ac785684e91ec23446ae01489"}, +{ "601500", "9ac84b004712eedc9cb82e4eb4f459e92634ae20ded19ce2a01b5039bc9be041", "b1800a6430feb20276c6d1f65b1042d5da3d547a575d7aa8f8515985e793cc8c", "0534f69dece37746712175d940492ea534954520282a439fbb88f81e1460d4f1"}, +{ "602000", "e584426ba4821ce97899bedc37ebdc5667d94f796853b5dbfc8597123f61cd93", "670512bb3eb55350a01e55a614addd9a1936e220c349b5fdf83ff85d36ee4762", "b9e225817855b7fe034416f3c8f60d6e918699f9fb0268d5bab870ae293f3fb9"}, +{ "602500", "98c1693b6c94cebd5e17bed36779a7c1498f43d83c3fb9f833ac42eb3b1f148a", "4335ab6f363d6556b820a8527702f5b224789aae810a9799c40289f088d876cb", "ede7bc44211f6e62eed8f645fb0f102572e32287eb96203537ea916a60d28838"}, +{ "603000", "cc90f10fadd0c325018a7f5b2819ef126eeeceb29cfb1abac3aa4d918dec8ce6", "c323abc97d8ddde6d935f4c4a3748fd5df141948b855062c0d557814b6c57582", "22b9244f3382b385b197696db2b875e2fc0c12b0964100a33cb60edfc87e1840"}, +{ "603500", "88a282051002196bd7e47c2d4d05acccc49be9e0a1958c608bc8857b0752d805", "4a129ae3447c19b8a4ca1812fe819cc571bae08dcee26b2f312bdb2292e7567c", "0f0928f3ee33d03f8656fb4f47003e700e63cd4a1f38f0b395c04ccd0bf32589"}, +{ "604000", "8423befd6cbd718339237b9fd01a9bbc7de101525a01e45777cecc593795e76d", "10125b30e2a5762ca8991b3ee699bc69e552b65457759c8b0a85468f52575c2f", "af73d30590eac4ce33bedf0d830a2b525e1831475360baa1cd1b1e15313e6b45"}, +{ "604500", "5f07bfc38f07c663a551462ef3fffbbe9a1f01d54e4987727649b2cea7ea3716", "f17db8519ba7ab7e3cd0442a008bd05dd5354ddbfc696dc9e2aeb07385929acc", "b0ac0adc0867e94b14759e51d7e7a5e217acdb0fa27b5637e74befbb77abe463"}, +{ "605000", "691b12ae780daabc6228123ba85e5d4ce2c48d1f6084a428ed5d310d644ae101", "15ecf51f40220aff461a2662902a91b0ff974c6b5dfc6853a37d492ad0e7c507", "b15f1ef422d7205ea9a75e2a755bdc9dd9894167da2b3714596e6f72b961dca7"}, +{ "605500", "52537e09d147a2eaf5a3e843ce45824f3a0db686f36cbbe72f69fca61a2b1c01", "ab643490828905c7be3f1c8afe6f7755a27c4cdfaa5c8488fe2441aa6afaa70b", "fe93785d20e88a156d61e58fe667cd7d88b799235170892fb73a25021f9d6900"}, +{ "606000", "945062759b3b417205cfff5d9b2e1c29d29fdc235efc71971a5c930ef5fac2a6", "5cf40892ca34be01dfa549d94b8784051375b2949ba916931a8addf7eb3a9216", "7632b191ab5c86f8921e87dbd6e044b353ac8448f26ad1d0e341b6cfcab681a0"}, +{ "606500", "284cfde9bc92fc8a9a75636ed0bb98a68a7d26fa82acfdba09391939c2e9acdf", "e0d8d1c85bb390ccf48b59af60483c919c08df0f8830de5befe65a43a53a99fb", "d354e0802e7ac9ac517c773c45514b91c3e8fbcbc4f159ccdd842e52236ab02d"}, +{ "607000", "fabf1c22a50594542dd8cc8e0aeb6ce78992e1fb97dd46f25b1f766392b8c466", "c42f95954963685fb338b1ebf0f0de3c8fcbada7fa53dbd4c0472b7cabb75eee", "8fae72ad94a28231f967f2a8856aac31fc33f5bf9a062bdd59faf431ee62745b"}, +{ "607500", "a2af7276cb9398592a0f0d137875baf3d9291a606f583b269540f9ac44a17ce4", "b5170fbaafdd9059ecc043f1c4ca714de50133bee7054f8c119e0eed79e20ef1", "da9ff721da89780eb2f19bfa0540368764e1867c09d9bf979229ffd3b9dc00e9"}, +{ "608000", "6a78949783e00a8ac3d832c24e69a2c6fe028f110e8f1a7d87d652acfd5b6b63", "01ef19adaaf1a1d75900879f2c7bd5366ec4a6811ee539db16e81a2b981c192b", "bf5cb7827f5372036159b01293e6b4f8a7e6a95136b3a809007f99330ccff831"}, +{ "608500", "1941dfc27e96aee1848d5fc8ba94bad2507ee14f8a24235e4b35af5dc0559f05", "559954098665a3b7a698445445daeee8967c092ce38be59cf1fe78ce354d221c", "f137e99fa941b0e0170565f9e9d853c421908dadb65ac79d59401791ee909cb6"}, +{ "609000", "ddb824a17fcc47e7312cbc0b80838b8f4fdc077d1f8cad5b08008aad8a25afdf", "528daaece3c6a912cf0859f93018845f781575fa67f27479ccd56480f40b8c10", "8b95320442ebdee812dbbae0b254fbcdc0923130e39406b06dae60016d37053f"}, +{ "609500", "3f80a004163aa45d2c9d2a1c8bb238a15b9db4214c8b0ca08effb0f37697c40c", "e6a2eb1304a43261fa54127676cdee58792115ca1b400c4a08261f1e170f19fc", "530edb76f0368d187c0312843669fcef70f6f53547d58af9d47eb3d99e363db3"}, +{ "610000", "0362121a825d39875de7eb528be247603e5d93922f21f738f255ad44171f5edf", "3b57b352f45dde9c233dae766260ea380cf6114c7682dca95566e656e9be1511", "ee0cd70b32d25b140cd41391341494bb74ee64d0aaba36c8dd66bf47daf6efb5"}, +{ "610500", "d39319109dfd619800add37b85ab545fe8832c50036eaf1aea5489348e749f18", "14c16bbd895be10be482c66ae8444f39cfd67f9c3c244f86bb3f309f3f38ea3d", "23a66b83736092b91886d548614c6ccb4df931deb591ef60b795f3b9ffd59353"}, +{ "611000", "274d0b2789a39a2808a69e9c7d4fa6b2b34b7be5ad55d541785f6230103a6110", "610d4811e3da6b704ea224ce3cef798b3fb9495609971c09971691d88b714885", "5ffdffaaaa4c37919493ac9e80821fa240fcbc2d006b16544b0bcaa2e932695c"}, +{ "611500", "c25930007a1325f971285a32257362f90f6b5da474225d3cdd19b9053a55e6b2", "c052c3e6c7b866d2212ecc66d4956d8b3c0a9b97381a822ed203ea796ba58581", "db4f70e0b89e3b0552027680b9fa09bbb3b65a6fddd5fb35fccacee1b069658e"}, +{ "612000", "8dc46e21fcf1b95e59d6be6454adf1db9d141d9e78d583c0f4efa47e0b2e38a8", "538c9ffcee5485b309bce281d6913a254331647ab43d492250c66318503ada14", "66bb108ff47b96dbcb4ab0e0d49a2136a263c1539f67cba6cc5dd699b2da393d"}, +{ "612500", "48c70c688ae362b4ce2e19325b0bf5335301f45cd6f0f562ff263d5d57324a2c", "06f90f226b98bf0fff455478d39513800ed400dc9dbf41c3a6e498730c883e42", "c43d539f28c942ebeb575494bceb18356d322d6465b541fb1ef6bcb14d1d1cd6"}, +{ "613000", "a05ec2324bead1349845a8000c76ff7705e0ed1f958dfb46c92eaf3180f301f7", "4d6d1eefb176cf04b6cc0e9554cd81bcfb00e1f737ffe5e25e752f9eacfb20bd", "b4c6888c5232096a5f117b09b1b577301a45b99636d8556dbc03a833805ec50c"}, +{ "613500", "6d0183915fa23fbe61d2cfa7dc9ba9c54c164b246d9f3ea2bf28c675203896b5", "e233a4490b16a593a62853877efc01bff2e03b4e5017027fda754056171236ee", "f90d236bd564360e3964d4c1658aade4df26dc6b185285edfff8b7fa85ba7faf"}, +{ "614000", "dc4d72e154553d04502271aeea36609af31e967faec981fdb7aa7686b194ef72", "a20198e44d09d5a45d18b1b2e20911f6d8840ae7618e39f1805dead4136ff220", "8e805b125d35cbeb91989a832fe0573c60602778acce51c2e48647e3a9f44807"}, +{ "614500", "401187c2be8053257741c3c78fd751d5aa80b74239ac1a5fd7c2008623b8056e", "b3d69a8f679aa779dcfd6b03d44da4318c10241e1a87c8de46dc2067879e7561", "a7e8e2c3fb0ac16f1d4dfeafb173fc49e6d1dfac2e7a6dbaa750e27954bce7d3"}, +{ "615000", "a7edfae28117b555c502b1b0866e70c2e45b2b53095b0b3ec0518f76a3250e96", "180c90afe2385b2149b5622d702e1ae33e1908e03fc9ac457f18cc86e3453813", "f2883eb378e2317f4c587e7f6094d2c87d758d88f9e55bd202027cec5b0ddc13"}, +{ "615500", "247cbe6b3a28a410c816bbf3e344fd707f5b98c9fc7ea74a653e55daae43aa7a", "675ffec485147855367994e9f3ab4ac5ad7bedfb39a35959ced78034e9a04318", "dba0d9a788c2a5097c8bef58f8dcd1086721dee07ef94caa587e988d0b4493a9"}, +{ "616000", "091e39d1de4719fafc22075635a0ed10d1d8b5636a21927557b2baee8bc453a3", "5cd5dc9688dfccc2024c771720a75202758606c6c2b62b3317eaca215338eb9e", "8538647a15cdeeb27b070f34e3cbba6bd910dd6ca30acf41f4e8fcc69dfc2a92"}, +{ "616500", "245d68d439cb7cc9d17d41d8748be112448c1c3d757746c28c32e3531a23a66c", "dddbe95e870b48d8e1d3be72da7976def8a5f96e20846bee2ec8d3644de876bf", "67b7c47a006895547c671ee3e3078f5c4de5d8b54184348240c7ba7ebee7a49d"}, +{ "617000", "9a08546acd2859279fbf0a140d792be72040b3b5deccfdfcc3a40d640c60f35c", "3fa1b0094367169cfe3c3047b01a8bbe5bd1179ea5252153da7113477dda7bb6", "5f9e7e0db3ab571d518ba8918c74b343400962664b97339322d394cc431a6f0a"}, +{ "617500", "ec4c7a99f349f9b610a1c2c94f01fd8e37bf98d8feb6a68874517a47b27a199f", "ada5742a01ae9d78a4aaa0fefcc2542633e90bdd178f540e802a4e5bf96368e8", "d0b9c218ad2796ce4d4ec1716498d747ce2dd9fadd75ece154de1c50932140b8"}, +{ "618000", "30bf0bf59fc693f06b630ff38f55f5788f24b27fec1c171fd5f63b6a75729f83", "a4d0bec878322f07128ea1f7318a28c492a27649b4e216332589628ddd9053ae", "d66ecca88efc3eb08f52e332fd0fd5fb8ba7115b815bf253f0e39eeb514494f0"}, +{ "618500", "095af87395d73d93df9f2531ad54c6a486b0c98fff5e59a75d9f468e2317b989", "c98bdb9ed3f618281b60f496fad0753ed0610f95899058a5662a45bdc30f2c2c", "75076658902306923b786eb552a2faa289486c9ee08172538b170aa59ba109ef"}, +{ "619000", "53c7aaacaaf469764119760051cbb7be6806f80d51f75099d8096831443712aa", "8e52bf819476612fc0943a9b56d5027935ca897f9a5dfb686cbedb8dcdd83bc5", "8d76699c08cfc5eaf88aa13bc8af9a9b16e92d6e612ba3580066f24b15385f46"}, +{ "619500", "7e55322d59a65d0ff1be11ba083fccc9800550a273a52a77926d5a67c383f429", "1cde548b5fd12717415c6f8ab191b0a73aa77acfb6c8db2ab9ef1f374bb8fccb", "8173cc803d6469a845493f73a951754b2cfa9b5df473772a4a77e56a104697fc"}, +{ "620000", "ce46ee172a243c059752e237dab267c4c95b111745b808bb9ad1f8e99dbe84cd", "e14873bf1154683503d0b3a1d0180742f3eb790efe5a968845a337a4877f9cc8", "447b50d4296c156c2a3cfd7b4c8694a143361f7d9ed56b1b2497e81b01462e5f"}, +{ "620500", "31fca5e075086e3ce312c78e4e67a24a245c48db04b7d07688a46be3efd12560", "d5c066fadd66b4053f35e728308e8e1e9594693f9afe8f930e342f89014e1435", "9e53b050cb6df8118681c205ce2a3beac7952b65442e2ab7247a79c3c3c75702"}, +{ "621000", "c27deb337c86fa6c1a9c967c1c0e967d66ca91c3a605ee42ca9ecaa3c7801715", "4bf8d5ac8c9c275f434ce687e9aa2e5bb0e1c1a8634ad7dc0380ad74e9f2a471", "47e53749b73ad12c2671c9c1d544bd4758d8c0f7b0b30c00f2c4610aa21fbccd"}, +{ "621500", "6d6de5c0c183af66e09203c1f851e005b11ffc3e65821a0b0c53ddcf0577a86b", "f8e09ce62f6793636184630998b1cdd6e513174a268fedfa3c23d1beedd6f127", "933961fc62855e5241d0586e32be4460534b723fda2d7d0865e089a1c4324bc4"}, +{ "622000", "3bb4c331c1c410066bfc9c84fa96f35f008d7ebbb8630f35616b07d3a8f6bf09", "2625b34fe7f2c205449f2ff67a4bfe036ef5f479b520c16f0fc16ffc43e5e713", "328d4df64c5d59c971737f12d125a3d32d4794b506132e08a09a9043b0907e50"}, +{ "622500", "b69c590df86c64c53eec4355ff7e4525ab0ede7c40da8cb6304556c465708619", "ea025a51dbfa831f98ebb1597cb43dc29f34d18f5522b57ac06d7e19bca1ed39", "e7339a6249253a6fb0337bcf5fd188fd50bcfcc91fbd7c80cb1c830d711516d6"}, +{ "623000", "248e12a541844945c6b91e45f24d7f63db3dfb41016952e628c647bb82562c91", "d2dcaa98eed5db5e34581c8bc52808819c5cf98bd564661252e24fb7f98218d4", "2394ef40993563da36d854a0f5f06c0af1dce3ae7274d3a3d6655264d8e1da54"}, +{ "623500", "0f6332963afce6ea94d654d103c3604c724a5a6bcdf6e32bdf9a708d10de519f", "80f5b0685f010693bff7453273d0cbef3d878e9753b19e05a5d2fdb4984f8a0a", "e7705c345164e7069e9529e3e5d47c12222a3df70d0f1300e39f12cf6d361337"}, +{ "624000", "3a250bcfa462ff8b750d0a725962879d47832f0c77b46dfcd27e3eb4bf352257", "f75082779f75cba11e26f60eb9556caf48daa15221abc2b4a83a1cdfff9368f0", "7cc8074a65f117e7942ce910dfd07339069627e317e1d4a31106ed5847b218b3"}, +{ "624500", "6a0ceb40f1277b4289334b6cbd593aa5bf593160ea960b4887e40afd2b06d767", "cb0565ee88160d6c0a26057155cdb2f9e2b94217d229cdb627fbe0aae9aed145", "9802ef2c8e15d18bccf977c41463ad4cc0ff9af9dff0a1104194dd4ff18ab9c0"}, +{ "625000", "c28164fd18e1087787d2e3c7d67b8349aafcadfbf815fd7547fd7ae8da9e7937", "319cabe08b33898fc3421e1cfe329711de03a92bdf21828a59594e813e71393f", "894a1464c80bf83652ceab26af7dd40661b1f157f1a1f77be34cc57fe01f0505"}, +{ "625500", "00c9e51e1237a00f30562f40f8d7696876a62523a7888f3019103f97d27c2afb", "cc7d1fd4e2d9a95e3a9a7e23f44a96f6840036265a29cac5b4a364ae1ee1b806", "de6b94caf4e70ed1bbcd7722a4fa7e0cae7b2490f07a815eb2b4c9278e0b3600"}, +{ "626000", "452cd22905dce67c27114fdc0b6ca64f4127abcbaff999b7aed68be214fc9313", "c969541e23ade41ed8ab864eb6fba11ab9ba5c6f29374e666af4912c2c076de9", "1c307caaa8f2730c6bd3c202a15e94a9004ab2b6f0ae24d58ed678afcdbaaf00"}, +{ "626500", "7a3f9fe36cb72b3529747754309d2fec46a8155a6f297bf5d9998336ca26ed2f", "9184cefba7d61de4482fb57cafe1420eaaf58e3f2fe370e9c22f2dc235c26763", "44910dd207c9b780f4295ae81102f25cd2271f810d19de06cc914409a6fb3756"}, +{ "627000", "d8f9b2f906265aa50c5eefed906e89c06856dd2c25bfa2df52f402fa029b6c6a", "1c5dfbc7bb572903d6eb6a400fa50df3c18c87cedade5b4ac63be7037f050a7a", "3fe4aa644342a4d6f4cf92c6e15eb94151d403a521b58fbaf90dc0ab2228d530"}, +{ "627500", "711651d2f7440f20927ed66e680d833755ffecaa905c0712ed31e1e06a81a4f1", "6de06425cf412c7d272841f1b3de2652b15d3300902c0da6b7c1b08bf4e14112", "c2feec57979a5febd4e028b999c765b3b127a5c9a31154c2884633149a276485"}, +{ "628000", "1f04acc62ae096325174e8ae11579d88e65ab4f435e3bb8c41896a1cdee6e231", "c87dd969f7dc7a3a356d7935a69e4c8a4487c72e7c623f49cf0f60cbc438aded", "7a91eef62edf2d9c9752b0c433fce328a8fc4d23595a151c6ebecde64a55435e"}, +{ "628500", "f55649153110900f0fa6b7d2f9dd6c293bc44ed7911a6e4d52ebe5563eb3a4e5", "de1bf3695afd590e9ede9881a431abee861f4cac9ab8b42cfdb8c37f0e02e19c", "a02b318a4219df923d40ffc494d44c4fe0bde49a03743c588f816e99ce01b0a9"}, +{ "629000", "8e7208c5c406f95dae4ffd540aeb30a111696ed10374f03cdc186db66295f054", "5a8b55bcbfe3fed8453499ed4c4a51233f65626132aa23ff6acae30dd5cb3800", "1ec2dca991d021138b1b9d70a4d1f4f39d0dd4af1e6741c74fbc84ec2fe02552"}, +{ "629500", "30b5177f1554053efca360e8acc003ef0cc4ae26820331715fdfeeb2003daea6", "f7e5d1c5ed411c3afd3a51d63abc4f29fed49ee8bc2f810481491c138cf09183", "aa3a31f783a70cfe04040c1c0147b6e4f31820bfefc6d261378f62ededabf4ed"}, +{ "630000", "9bbdcad95ee5cacc45ff51ca8d627ec7a971b1040368ac62a4616f873623cc79", "306b7845856f157aa25e14e34165e75ee5abdef7337cfbfb9611f628287b83b2", "783038b2a1ddee91c807f00c7cd9206c7bc0209f70cf8fd93f9e87df6adb4ef7"}, +{ "630500", "cf2b412c6c992847944b1fb396cacf61bcd03aaa460cd810e3f42a2866e8d729", "8d2c8d7be61fe16d9f5c0f5ea155eaae7f926fd8011209de27e41cc67055f5a9", "a6c409f611781e61ef4b35ebe5fd1e3548bb181779a5738d423ebb2f9bc75156"}, +{ "631000", "ea5e4b4acfeba1f4a69c63647cbb45147ba1dd101b9fe58843dbc6fb09f7c12a", "2ef37567bfb65be1417d9b5914570c55bd88da0bc07f7ef7389e6324cb0b528d", "5549746df3b12cd08b070e6aac9a3001fa63b7a4c5c407fd68c66aa6fc12ab94"}, +{ "631500", "539334450cd6eca49473d63e4917725250afbb6a546a025b57b40e4ced8ce63d", "865fdec23689d881dac49ab8fe9a20c5984f42b4be7cdf3e94118a4baf4fdec1", "9bbccfea4bf635276eb9d1aac8ac9e0f4de8e9be30d31425db85db1f0a8104c9"}, +{ "632000", "dfdc58aa41d2ebe7751fe2b3ff90f0496e602cfaef1fa0f1c25181a3be4cebf5", "8e3f86b2b753e8f342046b61d84ed4d2e9ce107d7f30a47361e983aac874f448", "376df1c3dc60d76149265cf188e76ab5bb9f90f2d87e6e42927586c7a5e3d277"}, +{ "632500", "54f71b9330b758d881d325e8f3ac9e0f042d8ea1222e52b580a0337a3b4f3fde", "cc0ff7cff02212ef316bb6fc2a131b018fef8b6dbfac01b9e2eb275c9008c613", "18ed8351a297be31c3a6b1892bd51312d42fe81ae28e819a978c5a97f337489a"}, +{ "633000", "67de40386baf1179b74ea2a750bd20d6de8f6ec3cffe5100aa3307ec81bf3a4c", "7d69bc05bf967c291b2156c18c0851caa853110a8ee527bb9872001cd8179b34", "ad0f698fe88881abd872a3c74332a091fc1435d4b2b986a8feff93ec2510ddd1"}, +{ "633500", "4414265aed7c038b6f7ce24cc86619b0596162ced270a87c70a59ee3089165a5", "09970b09ad4958924d24703ec56fcf49a7526a0916cc7f0f841ed9796bff86f0", "bab8a103a1151cce8a253688cdc8c93a700afeeda79861febbc767bf4a95a2c7"}, +{ "634000", "a55d577e338fdde481a3cadfea26ee6c1777ddd6e35e66040a4d99455626d9c7", "5da3e590cd7190a473f7d61027754e5bc50545fceb8867db96006d3773a2b746", "3e66c1867ef38484dd98188fef38caf9097e6f29ba8719e902bad5187d1d483b"}, +{ "634500", "571d3172a3095d0a34747c18c2e2cbaa4173a09ae3a351736b2b4802752cd9b7", "6799dc3c2b9fe39f72a22e6fe27ebf46308c887e31245a5cbcc2a55f1060ab44", "8509597ffc90e9faa61e2f11dfccc9b81388a9663d4197d9154293219653af26"}, +{ "635000", "6786a43fee0f379b103bd594943f26eee0f0ab3af9dadd36d6afee547d7ff8b1", "60794659a5de639280735ce3ece1864a66e5754bb1608b2aaedb9874a6c34d51", "e71885bf66653e463925be8e6a1677b27c0daa1ed1f4c23f12a18af7ba58f8e0"}, +{ "635500", "bc5896373cd6ab14f28a690a7d59366ee57a625cd6291c502d64a3a9a5969a96", "cf6d7eb9c0306f24bd7a47fa0660804b633f29fbfb647e79d03a545518d5ba17", "e0ba3988d8f5ef59399453d1c2db9690ed32f25b8d06b718d2645dd770b0e277"}, +{ "636000", "1aec8a1d1f6f5abb68d49597795c24102bfb767822705205486829ba50940cb7", "348625a773758822cae41638d27628bed89a118fdff13dbb773ba28471ec914e", "d1b089ccca6da98d2f12777e9c39bc730aa0fba9eac004d9a09627dd60dbd566"}, +{ "636500", "cd844ea294ba265e14ea515b603d35c2dd13c9c402a4a1a13628925634e81f23", "2c881b78d84e98a3a6dffa6d4e55c347947053f184c22f2a75bf62cd779febe6", "56c67d302587bd787e1737e66c7fdc166f4b83d2ed88586c08b62c04d003b3b7"}, +{ "637000", "7f0393f05b3ebfd7838740f3030dd915d2125e9546e39f503e288a20b14d29d0", "ffcda35e368f4784c75aa0e6a98485a2b84fa1ccba37f7fb5a6b4d4e187a5033", "5cf175683ac51572c2fbd9d3ea1135b35288245bfce82ab8b20d93bd0d56a7d5"}, +{ "637500", "7453182caa6345472aebc820d839d70e916b8e01527e69d2451e68df9f5fff94", "df9418647903ff269234df3583ba76f054c7fefb3237b47206f7e25d9ac118ac", "aecfa9844364a499e2c72ac729128b46b93ebda616fe09898ac8283a62e4f800"}, +{ "638000", "2917816bff7d73f4b4f03a31fdbef162ab7b2bc38e2539952648f7e9b66dfdff", "c7367a49d181f9e332613c76cba3371c16cff94c10a6bacf504c8ac404358b74", "c06bc407d795e6252326bd4d1b06ebe165cb853f0038ab172a59f9d7846add38"}, +{ "638500", "e10674d6c53842c520040ea608584860418908244a9203ea9e726544ef6dcc6e", "b67a32293808e06725a391d616889dc4a438c8681893c17646896d19411e1cba", "b04d875cf1633f696fd0167d6567f117f0135a6f60ec9f3682503843b5931925"}, +{ "639000", "a4629de92adb7ee055af0b7a55a0690efde637a84e9c19fd423aa74389c7ca4c", "95ccb5ef5e2720ec5ce9635d8eaec7d000b16b3abe24936fb8daea2def31b681", "6cd590a9251fcaa1b3f807a7bc4e408ae0e826cfc9ace4d08f0c9e08e3b1412c"}, +{ "639500", "dffba976bf5db95ba5845ee2863a8f60f855391a80d3a59cff38762f0992b38a", "589744adb3b63b274b63d7c83913c65d121c13dbd8399aa7e0f317d4b37b5155", "051f5245a3d1b1f09f0411957ae16eb2eee1116d8e67cc0a5d8c25e3c2b60583"}, +{ "640000", "d5c3942c19dfae03595dbc0683dc712467c00e5307bfd96609c4a728eff4f586", "33aee46df3a2c807e3fb8961929402532d1f1061a5e1df2f28335ab40002096c", "344191b74b6c5c4374ea484a87b81f881b4aa24e72f8e3d55e7effcfc672a724"}, +{ "640500", "2efd0a03b8098ebfb96870e4235206b8bb428b5aa568aab56db36e3124c98c04", "e67d6fe1642bd591df2f838f07190f8477622358706dce1a631819c828dc4980", "fdfec92daa00d4402a8a3368a31a17784aa85b10da7222e283df9c7a0641512e"}, +{ "641000", "91beaca7dba7afc17cc193cabc2fa7c34be665d2d367c9f0d17a8385903c5299", "b90b505393575a5869ad32b498b2fe7ae026db5e3be2ae066ee4c8a4e50ccd0d", "2cbdde622da75fc20c993e7cd8000470b627ae3dbe0531ffb156f1260496ae0f"}, +{ "641500", "52a2ed25b8afbf07e9bcbee8bab225af6bb0834b500ec30114697924951b9db4", "0d30d77943438dfd2b1d85adbfe26de36a3f821303c50717d3a7e55abc59cfd5", "fa45abae09484832e3b6ab1510a79f1435e3f30da6fb2dfd5dd3e2e611f028f3"}, +{ "642000", "24cc44ed0510958b23b614206b702fab53cb7681905d1aeb12fb532fa850a415", "05e56dc42c34c44ae0c67c45985004c753588fe4588a4060444532194840e5a7", "1c5f05780ac875c2e6d90507d6f1ac2c62bd0a96ca5cc24b41ad28282e205ad7"}, +{ "642500", "2cacb3c0be5a18667d5972d99182b87eaf485c724ce81cb59f3417691a920977", "1d5689874267933eb1b72a5696935202699416f5f064b689e7221d6dd4a2c3c5", "49a3abe7968ac7db221603d4bad3d8f6f47e8b3dbf034429c335711d3a729a18"}, +{ "643000", "94ce4d9dcf18b532dd9f8a490fe270dab5697c14f49b7326efb3e3f82ddbe7b9", "f8466520f91a0a9b5136c8ba589bf7fa7a5ddb292516ea1dcf7820d3ee7c0cbd", "83d0fe5e99e509d48e6f8c9c0736d98435fd1cabc81f7e5a4c70c31ac4af433c"}, +{ "643500", "e3c751b8fb071c5ef4fd1e7ebc9e902d365b88c3dd5a90ca5386d7cc42813b39", "fb799e659716a37ba6e9982fd09e8848d637ef1d85555c61af74dc996e1c6908", "d312f2af49d0d8b7cf4959454a72c004f42dc06d5347fd311da1d484441b726f"}, +{ "644000", "2873489104d5b817e24659b1c91e0b4ed350c388563670846658b452e279a44b", "bc4bee8a1c8a2b98d32ec490a31632852f7935737bcad951d741e789ef99d15b", "8cbbd8beae20c883085e1adb6f33ca13eb867a2166acbb1f948c82fb3540b1e2"}, +{ "644500", "2996cff77ae12636ed2da94137e2dbda45f5db09c968e13d9002d9d5e8d1bc8f", "1482ea5ca89d761a9b99c8e0a5791d430478b289ecd506b3b1ee803d90be7f94", "b87e9b5e245a76d85dd89bd64fa4cef1ecf892b39828c415c76de1cb04385788"}, +{ "645000", "db1d293ab843d88849874e33883a8236a8bc4bff1d93b7d9922cf1f7dd3d0803", "b13760cc8ccad388e7a35b3fa743b2c07b1e40cd5604c3d4162695d02bf601dc", "a3aa481cd7c2879b8dc135f770e3f611288e8f0a1b9188ddae6f2476a7570d6f"}, +{ "645500", "0c98834ca2fbd0b1f4b7e708c5f9bc9e820370fdc2b1126aa50eca16a46813cf", "95b1ca36aee7f85aa247e91eed0bfd17f8ea675c5d9db342d9087017117d73c3", "f12775baadc6645e0f97bf551074b02b56fbb7dd4d33c9601f254931872c2f0c"}, +{ "646000", "dea1a9883f1c3af496fd37570580c5c9a1e1ff7e8822d70188737f7aa45df488", "ebab9f3327181450b58a388214d86b56c395f2e90be9f7d595ad7ec863e6c1c0", "f1dd6f32b53db9b62e895bae55320726b8879bd31da4df74fd26cbf77bdc083f"}, +{ "646500", "5cf92252a010e2d62030e5d74d6371e873f7fe6353a010791c21307d8236a3a3", "392318738e04bc641e4375f47820bb59664b62c88a0f62a3f1bcc75be023b3d9", "b5ee3b8caaf574e852f227a55e690159cf5c89d2cc5575d58105abda3e86ff0c"}, +{ "647000", "b0a00219234dbf1942eeceb7a31565ed117dd8a8152f1d343277433fb3a19233", "8cd4d156025aee385a9cfd46d38594d1c4825f52555a703031c99c005adb1513", "3be48c0c754c349317f07393558b718ba29f5fdf3709334ec95060fa3a912aa1"}, +{ "647500", "8cff85fb1e3b4a7218a58b6fb2e7d0168fb5a4ce4171bf3f0b7f1e7a5f214d0d", "50dd61b46e224a437159c8faa7d18cd9c100d1e3ff75eccd770d8debd7723410", "91207635925dac923650f6a18ab01456ce08a74ed238608894f2f0179b95f51b"}, +{ "648000", "133d2255f56a3c2737eb94f337c9fac97214a7e1f54e8ca9b4bbfc6e056443cf", "d10ca77595aabc294483ef2fd07975ec43cd2e0764d0df38786d3ecb5cdb810d", "4fc0a58c1832f9d5ca4992f030e43cddca4d33b9ee9028903e347cd2a5b672f3"}, +{ "648500", "37691423db6098cce3ac61dd2e0ad5202cd08d37e2a810a4b7e259742b50f561", "4fc55c6790346c316db4b0f1a35d067052bbaed3932cb8a369f8263791b9e749", "69958cdf79d3bc23a0f7eccc268248d1aac3948ab5afda1d409ad672f15e4484"}, +{ "649000", "e8f43ecdb6979574c66b478a2d3ad028145349c43ac18f67e089f6948a48812d", "7609d55e10c1b40d62adbb39792b58b5c075f1c34c6f8676cbbe39e91a7e504e", "a388b583005de4a80b25dab466f64d532aff83273c495e02fd89e94a956f0fa5"}, +{ "649500", "18f631309a2acc38dbd4d08322998f0d4fac526eadbb1aa2ef1ccf75173adbdd", "83794a76b25f0ee49153d50f9bf6d196d1b78bac25dca55b9d3eece5c8c1c3dd", "e68250eb6a12a699b48123095035f869ce12acb5df58bc82ba22d7bd79d1b261"}, +{ "650000", "fffaaa151d0634fdd830e104f884bc05d30160640eefd126e0e01b43bd5db5ef", "7ef1c36f637320886b505c0ad5847bf0a345c6abbf4e92432d863b0ff517bb91", "f8aa7d420f5288f135088e929258b2af97e9a9a569beb546f1aad5da449d3dc5"}, +{ "650500", "bae09e49248acd64fdbc94cefd831ecb2a957c0d5aed72644a3607a198c77740", "f1ca4b8b2e74774fc3d86ff3f2b5e6ea8d59e40a683b993fa638c6770aad547a", "f2e5d622db2bcc3a30dc98b50087fa2d1b1d08f4f056a0cf95c64089873188ed"}, +{ "651000", "5d9f45be4e7d558b3133ab3a7d01a96db73f6a16604f4e348fe04aedab48fc1d", "38c0484fb001d8039ac07895bf04765ad79babecb93040f8b45e18629c1fe566", "6302f913b0ef7b4ea4363f185260008e6a8bba77326b53e6ec21279b8d1d1632"}, +{ "651500", "7e12af704c44d001d842767b49709eba23ffc53c8a20bf96b0cbda7955168521", "3e563eb1f016f0b9a83caf023067785be15032588fb1ed9d6dc2e7d47d7df8d9", "1b2277d903daa8ab2a72e3039c5c782d3936b27776dbfe11894288c5aa34d3d8"}, +{ "652000", "6577afda5b1a2535cf30f91faff821b56dc9f969e590d406f644518ae4dff6ab", "a6aa3534f3f962041d6c88a5c413edb0860aad04ae8068ee31070716e552c03d", "5ff9539f10d6522936100b9b48090d278bdaa9cf418d511fa85020b2c7aa3868"}, +{ "652500", "f60863237c82f26f35682a510882c8c8b3ddf302e479fd201a5532fe02993d3a", "623ee7add095d1a51ccbeacebe34fde662c727a14ec2ce8c856d2da57ebd1537", "7532f207a5838a5053a0f396c10b086764cfe595456a80571f043c723752599a"}, +{ "653000", "6d2f869d3cc7314a06868edf43473c3eb2a4ffc902b6866b2b6d9ed8254aca15", "ddd54a91243a02e778e23135881e1a17a5829d6a698410cbc91c9c70047f5463", "c74489f4dfb0ab0b6edce234f2613ac2d05840b066af94bddb47907d3aa85673"}, +{ "653500", "32d04fcd783380025ac2f7776d0868e44808c446df33e7790b9eb06edf1a13c2", "9dce2c2f0200948be45127d74dfcce50bfe2787f01a1f62cb304cc7644754999", "3f8e85317fc99b79ba87df971a91bbdd0af877a37228e8e78bc094fd441ae077"}, +{ "654000", "ad3da7c147ea7020a8854d4768937b46b2e9ddca13d786a2dbcda5fd691aa264", "15baaddcb66534aaa738d7370796b82234bd7d1a183081ebd7f452a33254bb3c", "b0827747fa4b8eb0fed8ab0dfca523be4cf55bb6d96557e2cd9c5c844d4b2992"}, +{ "654500", "b38fc7f77f763e12c55c816230cb83453e513d7ffbc2f71cb18a4b970a30b6dc", "8b8acdaea52986089352c0b17b8479def4e4e01d8f797609fce1c737e36f4314", "bc8c0e523f860ac258ea93eb5e10ec62f9f2ca18eaa053cb02446fed76634eb1"}, +{ "655000", "58642d4240fc44829a1c5fb427e034890ca40c5097aaff77eadcce464be04701", "11f24474492b2851fa79a42ff8d8685162e2b4dd1099722f3ce9ec4d5686cbfe", "85d330044b1e65610ebba62ee60be75dbbe7dbdda61ede949847d790c44763cb"}, +{ "655500", "d71e2ed94bdc78741559fb4c58bb944dde0adedc05e7558d7de6ab254c332fbe", "7bbb488685c2ca7c84d98149d2383b157d88304c5b34aa7679ac24ad5c85b006", "c504fc50c50248a50d4a94516c198cb7f74d6a1b4ff7f6f5fade4ac30e4807c4"}, +{ "656000", "c1d7426dcfe8733c72b8fae49fbbd127a6e257ccbe4120600f8454287ad26105", "2f8f7af5f2ec8a3e0333cfafc069bdfca90b0ad6b99ca970b0f458bafb0dbc3b", "67342b5de61484aeed62fdaa4377eb6df94b8fdc49756aad0a3ed6989475b5e0"}, +{ "656500", "c4f911e6a72381235e92a8c58ebf6fc654e35c3f5f4b2851f7f8a9ed3949e047", "3d157f3d2c8158bf886bf994e549a6da2db2c092266c7050b831c8888d62b205", "d20439a0b162598ebbf5671096b2532ec909b9a1644cb13a3c2f727087cfb59a"}, +{ "657000", "da224ea959041cf5d98fa040a10ddd7a1904725a649ec84f2ca403a8117c7f5b", "9b9b9bbc0221a24b8642fadd26c1157ce903d7be532aff91519f431e886f9ebf", "d4fd3b6288248e117b86a9f9274dede17ab390e22d2163870067b3e4d8d92d42"}, +{ "657500", "61cdb241ff295b25fa6a478eaa78f111e8d7ada328853b0af54bb1b20a2a427a", "482b2e9a549491f90026f8e50ca10016dcc78e4c3d2064e9f730b23ca9520a2f", "0a5db2f0e89291389e3f88013e6081cf19dbfee7217626326ee90f708d135b47"}, +{ "658000", "1c4498c323201e26bfb8a8955f29cdeb66cd43d6a2b2befb1da4a6c0647d1c53", "931ef1f4868a3c5b54ef4354bfa791c3ffe15c02b3c704a6a281154e2f5be98f", "62cf96eed491499f2f2a8e734efb3ebee4cca4491fa6ca8e57ca32db6ef2546e"}, +{ "658500", "33dce694605303583aeadcaa80db0d8569ff712b588875d48edb395520a43981", "6247bcba2c8883551a85e364e30b4104edb0318eee718e0317dc42f2a26c7451", "c3c8ab5c1d3efb616f9e90d79cdb90009c8306c18a01bec6c83de9e0539eda38"}, +{ "659000", "339aa922137edb48aa37b841e956adee6c9222ae9bec106ed49ce5843b179681", "ded7991d424229bf67cbf220dc2a5a5b223b571374f52d14bc9e83df72ea4753", "dfb79abf0b25756f3b77e701a1612b433f44f18ad96e3aabe52dc4de4cb73206"}, +{ "659500", "38dddb9b6e5dad4ec1f95be3a83a156be12c5dd9d5e74a20bedee990b3f511fa", "7815a077c5c8a265fd122b282139e3a13ef5951482f6d550a566ad74ec2db369", "ccab21843b81bbbe14e77170588ea2b2f0d74b7c312ae5ef155fcaf844d07e34"}, +{ "660000", "5562a936684fa4976fade44cd5eaf6531bcc844027c9ca01e33516c0c87be6e6", "0af9d5b94d513c095d2883a381746ff79e47d5179cc95165708ad37dd0615764", "9b596d92042930a6c45911e3d8c837026a2d342c5d326c4fe3084f4e58511088"}, +{ "660500", "de362a2665571bb51834a5e8cf65cc0b436097d1a640ccb9666fb41ee1694713", "b7b39581644d06d7672965e189c645b4396f4d50b223eed99080a122b22c2f1b", "9dbee44c5fa617a8a911d2271446d5bbb614d5820c260b7605038f37ca0d7b82"}, +{ "661000", "7df5c95f34efbe842ac26e4252440f4f315b342bd66e74a3d1bc3c48ca0f3844", "0a4f81f5017d079725470dd800ffe7e955bd82df18b6e8abc325165537ead1f7", "4a11f1341ee66c1588979ed0721d87ea8729579c5a8752a6d756932bb38180cc"}, +{ "661500", "dfa40eda9296e76deebe46ab09b9d581445d20814c44c42090766c0015162e53", "88b577c05b1a5f27b2aec225732da967a44e30dbb463455bc7ed223bfdc76025", "7b8df039fe4a7d90c694b545146afef89db880d378d0e20c45711a514008d959"}, +{ "662000", "7cd8f5daa828803f06d2ad8e7899d4993999d0ec37e8a37ec52555d1c64acd8b", "d0a6e4b8cc44620fbb80e061a949a8fcc371fd1f2a0b05138978d234a99fbc26", "96040f6351e9a1dcd55787e4e2b20b912037f2024e86f5e708583c14b0d63940"}, +{ "662500", "057c9dcdeb7375f51cdedc28740c881bf6ae644ff17c0aeb77ed796e89db8672", "c749272ba9509a09bdb7697c6197f132c1de0c58de5130e8c3257288be94da8e", "f8c160085e3a1d45ee033f8bcb723f059352995cfd90f96c619eb7fc3bd353c8"}, +{ "663000", "d9ceb13692d03610ff6e97eeb643407840e27d32c389404cd3cdd14733756dcd", "05b1659e97dd91ccffdf180d8da3a35f6b2fceb9676091bd997ad363210e2f5b", "f5fc3da1820b598d7287f36a0f0e5e9d34e61d42bb8dda0cea45b86217ade9c1"}, +{ "663500", "cfe8d9435ad14423479546bd4d6d1e8dbdcd62a8214ab922402a86838a8fb3f0", "cf68cef0e01bc5856468753c4df42bd16f3d33dd68783e012c1b012a3cfddc48", "2e3b740dbf19349cd135c765330aab0d6060250d2b884bcc7fc7d28f9049b672"}, +{ "664000", "e18e31c640bf36f6cce981521fd55f42761fda24538dac34285fb02e69c427f2", "f237c6c072f16f524d90aae138ec3a9176c2fa8f3049ac9ec009ecbb678e4f77", "5984215039409092af394adfcf7eb210753971e61de048b0e626a2ee64415b53"}, +{ "664500", "2cc31198ec6c3fe6e286f01d98f097e19a5c23d3f478916414e83f201e724e19", "1805da29e7f7e8dbb2b5aff1e712b3a447106db48671120732111884e0783b5c", "66387d00229b4429c099eca4dcd9ceee1a889b38365d5b7454c9219e30bcb40a"}, +{ "665000", "4b332fdeb19f5d2fc8108c233679e861bd40df746262d5412b8a6800f50ec073", "b2119ba9b25aa2a5921c7aeba1759395795989824a5d6d204592d0ab6ee8ca12", "76b874e1bedcd17be5ce3e206c8acb04123e83f94910717def66723ae8126633"}, +{ "665500", "3f0705d552dc4294997339d7015a4897e55790353236540c775e330c78cbb34a", "9595abcff6a155b8b995057dc725cffc3b283086ca65a6213368073f7f5d2b34", "c8118d69d2598bd2c6fb0ad7b57b1f859d441a090e152a4875691e0486dd506a"}, +{ "666000", "df535e0c312494f9f1a288cc54b72779ec7ba745bac09f7b952191c5a904c56a", "a545eb072527dc053c0630dbd820c51a2c3a22510f31a389abf75294dfb34911", "7dd43421d30bb27da111d5034dd3a6e104533fa5c0dc158ddbe17e79ea46d747"}, +{ "666500", "ce6966c65ae25a88bac2a35c95d1943c482febdf7f9c28efb57eacf2dfb9544e", "4d6fbf4b0b9c493ac96d63f97dee48afd60c2c847f9aba07110791514b0f4e21", "2f925e0f1db7403d712a85ec861255352dcebb1e770acb878eea6552358c778a"}, +{ "667000", "e7a271b35d3fb008b6938cb618fc6f57032c92aa1e09fc50363cb181ca53e2cd", "0f496a3a120f9644e6e3c5d371e6e01de4afc4a85f010306919bbef0aa323942", "3a8150ef67e892d5ea237fcd135b0c903e03e1e0f087732dd7d8ae6ce25aa9cf"}, +{ "667500", "783bafc58044919edecb6e3938f0ac69dcc75bfc220bfd8717d419091bd680d2", "b22cef79cae030286f2fd4b62c409c6d9a801f65e377d66d455fd814628d5ac0", "f438fe81453f186f7c1b1f43b7d906e489cea3f970352fa1da36236ddfb0b5bd"}, +{ "668000", "beaea7bcbb6c4c3a18e0c9bcf6cee525f9036796157c8b4ce5748819c13c2967", "a81cfb88c97c1489d9193801faacea720e98d21981856d121ffd5e75f7ab393b", "55cbe60a2b86bd7c1b4e2e714b07f83e2438cd7ad63a8a27d26b2a01bb221056"}, +{ "668500", "393c647b49312eece8839452c0874a2e82aff7169a3a7e1e5326b1993a5d1af8", "212bf73b67feff4a971dde4a00c12b32fe82859167687a3cfeeb03a93ccdc14e", "9089b9443bdd360e32feda94a28ddc9e33cd427381a62602207f0fc97e5511b1"}, +{ "669000", "f24c2d105f11f385c356455d460f8b74d466885118dc0e1ece8bddf624cd5246", "d91bbe1649788ea71e0574f15865868289b28651ab7e28455d823a515492ce0a", "adece8b6adf69980fb7c00f59598c1a43be400612cab0d9a67700342f9a9056d"}, +{ "669500", "3dcf0b942af949fb37bdc61645d89efd6f72b13c02fac02a96ccf1375cf3cc21", "81fdc3a3d66e72026b4bc01320881275584a05be5b0a5f8edbb2a6f334126024", "5cdd39a3dd6d4911e9e6058ba1d0357937124cbd0f8ad2d60c1069b730d4660b"}, +{ "670000", "e6d5cc2dd441d4b9f08b05a582c291a01927bd1a945f1a43557e3bc70cac59be", "c82d3be4f90e23836110348e66a9224cfe135ca4408363489f3296dcb8c33f2b", "1e45718efa408302e479fbf9478f8158fb82b7445ae2a40b7c3de67e0cafc261"}, +{ "670500", "c420986426267474054b56073135491ad4381376c64dbba0c57deab84ef61846", "b0c138c7e5b8bf286b3f5b6ad0a83fafa7ba68d499fea78553241e741a05d183", "8a71746fd8b18bf6e792a4509813c920a3cf481d503cb8ae4cf1c6d3e637b586"}, +{ "671000", "d21e66d96e08adbb61bbdb75a7e8971ca9bd45a4906f3ce23dbd84c2e5e8d161", "ba60c1936b7c35369e31e9fb6be2739cf60fc4685d210a209c4fbcf341d5c9f8", "833810b0f9d5c89970991f55a0f07946d068ca8faafe5afd64d48d4a67f01d1a"}, +{ "671500", "f7bb538d49e99ee06136105edfbd282e2f370d3f4f4c6d2f20b75938aca43040", "9c1b787f1413f483e72003c0ca97831ef1e616b86fc3165423cc84e878d487b0", "da656f45090a6bfb6bc6959639b25a1a26e0595ed00d554eabe1c5da8e727f20"}, +{ "672000", "8c85db8531cb0e6bde769d488b6c6a639f4839a819abe23ccf88f3756caa6089", "598752609771c022cecd036a0b8aab8caf8fa3e64724dc20815a827b750daaa1", "7c8d703d1655a7ee2462c82f78a4e0f2f8bdb370a6dff19f28d98f8b1cc839b5"}, +{ "672500", "efd3aacdf98aa1fc4fea20a2f4cdd9ea3eba6dbe03a63a149610d842793bc85e", "93df0fed7bd2dfd8ca6293601d799ea9a54af7b0d45997c821e4a8a7ab7d1f9d", "8337579b8d6bba63893d3aaafd5661b224a808aed129aaa36216f583e29832b5"}, +{ "673000", "3109a32670b3c1a796f9c6cdf5f3744848e8ac3ef0ee2ea891fac0eb69223ae2", "baa8971d22821acd1fee4649f702edc70cf1b072517f4b69d6bf4060cefa34cc", "fe51c93dc781185d8a9fc3efe07271096264f598616d69407d0d85ba17ec633d"}, +{ "673500", "8064bdf0c36a535d5d7788f901ac0713b627e2f8b80c4b20d26cee0daf02ee6c", "5548c9d616e98ed4fcccb300d3e35a78d66e61aa95c6465fc66a98c1e40405c2", "b5aa467ee5592fa80eef3af90b239407d7e31fa4c6cef603ef50598548666cd1"}, +{ "674000", "b409ec86b27b1a828acc7f056dcece326a7892314cc5b0d6682d21c06d4e4cc5", "a25e0ee6404f9db371913c15348e3aa8a9ad4b3cd99cca3fbf1e8f95b6e152dd", "5d62ac697208e75078a5f465f2feda182ad6a988ce953ff4909ecad0feb96e0d"}, +{ "674500", "0c8142e02a8e0cc1667a81f4c4d08ab7577102481f73d31b9d8c67589874e970", "0e31001e8d410c86f7a525b201f135bf6902048a0a4a25d3f283b2b1ca9e0b63", "ae1ef0b9fa438940e44e4804ba785686e04250c675fd4bdb76b927156bfeb9ff"}, +{ "675000", "f200a64f03ed78fdfb3a35be9133cc144cb7621be76f0a470a6cc451d31de7d6", "2dec2d8e6cbe5d122786b9c571751d54ba1d597e23dd4aa03ebc50212c68cf8b", "f841d17cfcbc629ee12bda00e988164571dd7a3b8f9c68951620a62f378050ab"}, +{ "675500", "44927533602536ec6857a62ddd2e7ca31a05c733cd0699a078c5106620da51f3", "989564e602ccbd682fcf993e4ca7691f049bb6adcb099860f9577a83cbe436bf", "997061d34d9e259b99c7911924177d59e78f2c86d0a57743e5ca07c1f1495ad2"}, +{ "676000", "1349301af96fd291f3f6cac4d6a6a94779a2015ee9d63989d79c813e7bf3ec81", "c196991fb4a511513fcdd4300dad73d556daf8eaaea1411a5c4b0d0382e96d45", "e332be471e67a22109327b11ee3002dd4d151fcc0ea5355d6189e3529bedba04"}, +{ "676500", "7a7071dae50a8ee6f25b289f3e9d15d53661469e5379b56278f391381f2b5ce3", "918295a1444f694e137f7f9653f87f1863884241462386fffd0037927c3779c1", "748aef72e32a43e6a0c050dbb046d7cf06a095fda95ef0da741e704337667525"}, +{ "677000", "a816938aabe21e8efc9c41ccbe0e7de2188e0bdb3635541e05b9cc8e61ed3dec", "d59c6134dc9539b3cc6aaff9870b30ba12676fadafe95167bf90bda3f074bdde", "30ddfafa528aa4ed1e213e7ee40c5a1d10dbb5c2b8aa5d4a980c02c6b16f717d"}, +{ "677500", "d06ed31f2f1a7dee027e76fd419c93a2c80824f31e5b0bf09e85e10362cdfa8e", "30baa2fa7e5834e442e8445c81d124018eec1ecaaeea695d4278263ae60ef134", "821a14af37286851070ca1113303366d270a1f2a492fab4e70da8a65092ad2be"}, +{ "678000", "356bc1b553016f0a17399fc531e9d5a86bb273ef944843e8aca16d16480f1e1c", "74c26fdb3397f25f794bb15595b8807b7d4a4500ddc941e7461bb106a69daa62", "274c911f767c18dd29f34d01a8ef4d35d2fd39b5935f054f287f98674741d69f"}, +{ "678500", "e7f83fbb9fef902caa5ad499746100c3422842f793424bb2b17f9431b0a3b6ce", "5177927957f3b258bec01be88d817c262ee5a64cee44e04b6d78b5f227e44442", "4332c38deeb9febf6fdd3a3b9641b7dd8da1e7f7b870604cec9ffc4470549394"}, +{ "679000", "1ced7af5a996a7028c63fe45238dda8c540295b48d082cc278614f68dae0e249", "cbc8a6d5c9ec62bd0d50ddb90e7e1efc4b62dfef8d7aede6279ad95186497f7c", "2e75ec964a78a7800b7eab5ff9cffc0937e157ed47e3ca60f24d6e200e085201"}, +{ "679500", "a00fef7924aae620536c387899d8628d4eac6fb45bb1954447e2de6a4fdb2ab9", "69b47a27d041a54b0be2406df7be07f3fbecfafc0d58407a7946bbfb0f65cec9", "54a2dd370abf726f06c0fb38f50a2ced851955467d7e935101bd3f8b092799ed"}, +{ "680000", "76831117aae716df313e1e7af8c4c8076e2b7d37bd7239c827962cf903afdb55", "0ba660526d75f5b1765967a87119f6bb67d33a496e23b13e58335e960610b38e", "95cd680073e4611d1f8eeb66fa540ad018f933cb2a943e533d4f352520ea7d25"}, +{ "680500", "17835aef913aa41dfe7a49e91fa7bdd85411356233f5cdda375771706b5a4e5a", "b88eeb3ef96d4ce4adf49b87f88a5c835bdf4ff88aa3a45bc46d2970a14533fd", "d145a5ef679bf4a4142614e122e5128852b20271e4cc77dfa4db939f4e2c7791"}, +{ "681000", "86ca3bca8de152e4ddd4ac3171ed463466dc040afc5e2f38eafb7fd0ce49dbdf", "55a9a5b5ed90ef00ce658b5fe52373ec23b37e7ae1c477decf0e8a41326cad7f", "780df69883c475d6c0eef972e319d1fa9e4b6c9e29b6f11008857f0be445f7ed"}, +{ "681500", "5b31112aa2d9b190844d109c44f8a4845bcb0f75e567055bc1368bfbae9bd427", "9b695ac5b41310d05f09d0e5265f53b4ff475b10d2b0e27928d81543857a1f0b", "3aa9c40fcd4aa12184b3d201806a0437f23c0976423e576223f6c891144916ec"}, +{ "682000", "0f036f94ee9dccdbb0ccfd4dc10663890af3c2b7da67321baf4919f8da0ef388", "a9d70e8df288e875c0361d7273ff846b54dbdae0d6d6459831e71ea4a41397fa", "b38c91a8d98c4586676c2aec47cdaf95e9bd7b8d752bd41f289df6b89b44f5fc"}, +{ "682500", "18658069c688414684b22ffe62a7e4d9b84b3f27c28351b57c8c5763aee40ac8", "c4ec9845b905ddf71c374d400faeaa649ba8b08751f0a5c6b9780d4c7d497fee", "87b2f2714cc9131438ef6de56a30fee9f1639269aad00ede70c922c67ed519ab"}, +{ "683000", "ab2a4002ccfc546d80417f9c1c66dca34d8de7df714fbcd4eee134659c6b4261", "5bccf1dbe0d677d06768a02a5bb6fadf5deb0075582a97e4524e2128a4fa4363", "675687d470bf255c4244f6e78d4d70e7fbbf5c58a0caa7f998f2e186179bedc9"}, +{ "683500", "5b302ac27ba940456860fa752bdeb27a3c8494c1fec08578c6d204588ae18420", "ae3de94a6481c28aca678f115b73c830ecbd163fd2e11a9d85b2c3132911c3cd", "77d7f359371b5ae66ecea9019507163255c1744f3aaaab043096e5856fd1dc27"}, +{ "684000", "15fc8d38546017ea2ae0e0b4387d74bf702a396b52cccfa879bec7c415a164b0", "9a6e35b63f814b6837bf67d897103f320a25e5cb15dee8e5524d9961f53368d8", "463822c866010eebfc3f7fb3d71bda605c22e62a78d00aebe68c1980454ac87d"}, +{ "684500", "e40472171e3915e9518f1646a3ca09a46154b226443848605a4d8c78803c90d3", "2c7e33f27973f6345dac95862d63006b4b1506d5979f60d8c52fec12b74a1b78", "506e99d0e80bb6429b76bb4cf9f33e7d97d6b40ce4459480b1797952c1347a89"}, +{ "685000", "742e161c4d772ed9ab9b2aa95ab7dd4646e7fa71a7b71d0062120791fff3d538", "7854ab499956e6893c2679a3393fb30e450f2cda76cfbf08bb3e77b586b10599", "95c2ebb16170b750592bdd409dda3ca05fbd9afc895d6bb9dc4ceb249a146864"}, +{ "685500", "697224d799e123de9da2b93aaf6a3f00ddd507080eca2357c7cde1ed1ae8f189", "1b02e1bbb85f1e71e1a1bd1e58e4eca588997cddc1f545ee293b17267fe5fa50", "fd0d4596fdcfcce21bf7a49e3207a478679656f202d54f3244d8803a70e2e110"}, +{ "686000", "7a7fffd9aa90d0d9e7309ccc0e450c7544dde058085bf4bfc9efde0cf8fc7b3c", "fd10b3c2c0539bc586cda1dbdc454a1597f4acbfc1d9e7e7b472e2d3547c76a3", "eae66bdb96a86e3fcc78a9cf04d23120bf80908c41a188a26dfb0b9b26a6a6f6"}, +{ "686500", "3dc10029047449d4411fbefe15a7f25864007511102972f14697dadfb914d5d0", "8064a285a9ebb460f864525434c5bfd94ea7c437f67c9eb6268c3f3e4737b798", "b81d605dd67e0b7694f979043719ee9b5411be3bc6fa73ab1ed224cefdf4ac90"}, +{ "687000", "2e2c774dfd40cd18616a82d3e5769d4f447a2eb5214bd8783a5084cb8ab38e20", "52379664d91e53a60d1b1a4d64ae2005e6549972c45af11ef2ecf2f2faf82ba3", "2ec94fed8848b9b2e94ad24271c6e87c223f85d092755cb9b3dd2eb75cf58186"}, +{ "687500", "295e12eaca70c7eaafb7cd25efb6b461f5aca68665832ab9eb652e6fe476d809", "43763991b8beebed72f3b7215ee72a2f074daa83a27c8db1decca52bbfca7b15", "30007826e0b6d9e775b8c9743c2d8fa70ec45190ec1269b0f6c10b3bdeee32e5"}, +{ "688000", "88efc791202d8e4a0266dc8114487847252ff2497c022ff4ac237aabc6602406", "560346aa44e4afaf2fa9a4e1506534bce8c0e113efe4b19c6aa26804b405bb11", "ed8e66e7265bf0879d5e0a656eaf6151281760412b6263bf0c5802973b535dd4"}, +{ "688500", "8bde3d0d7f23d76ffb10e59c43a9a2cd4121c3f5033204c4689fe77b860d616e", "fbc4d97609351dc9fcc8f4e08b5a0c79624c9e81989b684e219245878ec2fed1", "eba83125c427d7e7953d6e91b82344841b5c59a441310b893011741f00165790"}, +{ "689000", "01a706323f362664abca40cfecb4c6efa65aece3270fb1240e238f1e93ea3ca1", "e4672adb018af124ae848405442ca5e255ff9af3909d258bba12d29f3aecfae8", "2b3e46e498f4c7befa001bb3d16d177feaed83f08a83302e1b46f0761a45e297"}, +{ "689500", "3d25b5834362be1296b92448e3d2ece79f8017708479f56d7e28d602817c82f8", "643b9f9b0a754b768ff504c9941c627627b49aecbe170a72590179536840b843", "d9fc0a70fae6a96ff522389fa7855c171f3daa166e60dc39ac2eaf861b9ce170"}, +{ "690000", "0e622f16da74d548cc9e49c20d072a9a8a6bf45dfd793830fd25369adca29bc9", "fcc1d77406d58f3e1e5630871011b389449597e41f1df035518c1e25affcdc9c", "ea81179b8d0250b07cc04be0c567b863d5f693f5068562428d93b09d87662c45"}, +{ "690500", "d96ee19654c250c20011f56dff3850e61b9b01a8c3be009b93c0f53c79d6ad5e", "d3b6058792062983ed59720fa58ca7cafc890e475e2411a01331a4e3e8ddc580", "bf7073645256ba35b58c48af2a0a1da2fdee8539ec0670c64573c791a6a29d9d"}, +{ "691000", "0e02a80970060ff139ed4ce0a83bf5221895d80de69da89bccfd720da52793a0", "20279d4dcc8aaf7a83a59d70cbfdc4c51e8d034467a956cf012349dc01d875ea", "92bc507ac9395231f1c4387f393428b47f03d79f1cdfa44c0d04543dab744ec9"}, +{ "691500", "6bbc975ee40102521ac8b041e481797c83174c5f2b5fceaf3090895a6301f42a", "4ba322db9723202338d5c0e46427fdcf24c8631f53f3db590489cf5cd74311bf", "65216ec91cf0206711d495b52d5bdfe54516c33d5c5a3768b67b5246f52da328"}, +{ "692000", "a36c0ce45bdbfbcd02fe25ec7c199be6e01f6edd8e5095dd745b136e1a1956ed", "65fb3e0023b45c838637825b0e95f461b02f90134e875d85ca8f084bd30d3eda", "f71487796ea260abc5d1356e178faf08b6f91a8f537fe2d0ade5537b43dc162d"}, +{ "692500", "2f8577c57b15cf8c176873a546e1451b379f4e09967643452a37b037b538a0e6", "b15ca73e362e6394166b6e104ac474d1f73d4fe671117a77ad3f9786ee35488d", "bebeefd2b5f2fc70448c02171877b83acc0882d38a5714c4fac4ca3e0728cbf5"}, +{ "693000", "634e96cae2b7253783b3ba6dc65bbf79ad87782a46f07a11ca8c3b2325e2d2aa", "08db37defef7bf06dd75f2d8e4f8d1be0f2004d24e816a71ffa4fee43fb5153d", "e14c7fb41dc5c08b49848f994278fd52b1a64eaacc6095e16b089862e0c0cfac"}, +{ "693500", "c472b7da4a1d6e9a9728e58dbabfdea31af58c18a17e79e3dcade6d96efdb689", "021ef6717375d52d4e02c36bd8757c6c73b77c97bf3bb4d6292cec23afc3c8ec", "cfe39e0052abc482f2bef739131cdacd79582c952cf1a18f18b822bd2a3412a9"}, +{ "694000", "8d5000ca461da1bf1687fc3ee92e3a1b414a92737d82e301895d6cf41e0e4cf9", "e2e6ad6d2a58ee8538e7dd8136587a612c39ac281fc3e6bf609b1c497d9e331e", "a341bcb67f9c01c7cfc99d09e5e8e0ce74d44603c48af064d508726c0083e901"}, +{ "694500", "daf014e18bd15e7a19ac859acd668aa28bae8fac71079e0b8285c25fd28a46d4", "9a671a25ba774c600b2f967a1632561ab4ebbfc4b4016979aa9288af8be93065", "61c76269727aa28aa7e21471a6894b778e28807559713ad41f6b832aed7d9a78"}, +{ "695000", "f0d64ffc15600b2a53e5b9f09f1a0f981273e1cff39f01bb69a3c27fbe679c71", "d5adc8baacd5fc0635fe0ac739a16893fe0c4215655ba111f49e3c709f0d1faa", "46f19a5bf4e7a9a77cc966982ea6f0d54e06670471faf8bb9a3b0e272d1498d6"}, +{ "695500", "d784ac30db59c0e5e8906f2211b6405356158cf57af758b047445926e8dc140d", "7d0c9248ce3387940358e82c01b7accebe7d3445fe97f6569b0a99a1a4822b61", "fab42a73d154f8f6dd6662f9c8b72919fcca0951d582a296eb48f6b6273037f3"}, +{ "696000", "16e6034f4089c38e9eb2a11669e4d5b896b4e36e767626bb4c2cb852031099ae", "5f54a918561ebc4c21c27b793cee698c347e8dbfa49ce72f4580ad7d3e464a91", "0f024cdcaf10c1503193c4a4e6976507f46eeb34974358191087c8690574bf55"}, +{ "696500", "bde4528da57c22025db1123e7fdf3e58f020015b1b500be5d2ea13be8f4f50fd", "954600e88d55d507e82333a0b9b36f5bfd5da128e5dfe721ea486a117f196e51", "6d65c68aeb31a3b4f823b9ceb46fcd48f93e0e279cd91158124dd4e4b6fa697b"}, +{ "697000", "eea7b9418887e6bfe3a460b03f30f800672d8df94217fab7d1e7a74f437ebd50", "a210a2e4efac6617e3df43fd4219eee8e4a9dbf05e4cf103cdc9f39e162d61dd", "dc2d1c8baa899d025878d103d902be6f2ce14b2a1f46bb3bfad94f13fb2cf3e4"}, +{ "697500", "af96502823fad0e9693d94bc707b04d59d3f42fb27a12134f1aa0a863ca616cd", "8cc57e73164f446606d37223429ba5a37d92d1ab52265fef43c81d8f5d9756ff", "7c22bda98d112e24cbcc50d7e6c71892d47ec18dd658f28686f58d7765ca7bc4"}, +{ "698000", "8a0878bcd828268633df687a5405b2b86051640a122f616231d8d6146d4c2ab2", "27a9f143cdcb85bc01f31868f92a964337c451cd1a546f93c29361f245aff07c", "dacf575151c578d5b0f283296f31337bd7a1b976607fd492dfb0a88e0411b9ce"}, +{ "698500", "afbb603de0da6476915e14cf182c6c785ec6514b17d9ba7bfa74e5a228f6d8e6", "f730e6ed2ef1334071ce63f9ac851de557383c98b40a72f8bdfb29c49bb7d571", "70863c81dcc8cc482907c82781ebee38697b9c01791ee71132212a49ee4cc875"}, +{ "699000", "4e3bcab244d1ec2528890ed24340027a9add680ccac038c42e9a5b4880368a57", "1b7062e806e70df560b7dd19713440125dbf814412ff713c5bafc8776c443a60", "7caf82dc9c49db7c7baf08b8863b2577aeb18da4679d6a26ebfb620b94b32fe1"}, +{ "699500", "69c03ffa655f439caaa38a36031f45c27f6afa345fd8d380064ac4106a47b9d6", "0522b34e7ce87f078124a74b1f26e25c44cda27ab10ca9884d777a91cff19df9", "770d8310ba9272994252c5df67d39d32018ed69a29cd7cf734a9e8458412f476"}, +{ "700000", "19c87f86c5d859f1d4ba642097f626a5c6cc8420f1b438ef0ddfc52d77b5a7ce", "e7cef1ed642d40f49563c66d9428c699a66241a86d05aba5cb6fc6d6218317a6", "0c8c3f94794122eb5e615582ac97d2bec3b09ea1c5262861c7d7c4db6734d2a6"}, +{ "700500", "c22be0aa764d1e0d90432e726ecb95a769d691a7de81ea480c1bb9e74f43bd8b", "b0c38cfcda8312393e4906e1068c7a323defc33624e99c8c8f918771010a417f", "422cc5c68ef275f1f6d93266cce5c9fde6c342e1ca44a94f39c3555ed4059759"}, +{ "701000", "b2505b0ce33e22fc06044bc95bcf1bcea363d91c541451ba7ebbb07079c9b8e6", "36066185fdc8a919096d36245786b921b24ea4b9ad0949d3685c7d54fd3faeed", "b8821bed4a54d18bfa8803cbc988a6328ffe601f98282b71ae2ae265c57de22d"}, +{ "701500", "11c69ac149f239f122c309f5c7c8c08ae9ed95e563e6e5ebc0db4d49628972d2", "52282de896ddb2f1cc56c22ec74637395d1c2ff49508e903cf4ef1f5c01a1da1", "be400f9771c269879c127f664b0942276cf7768a1da841f8100d9f9c008f29e4"}, +{ "702000", "73e7769b7982c2e9be15c6d3b0156680f7705c802452205d64a5d66187de5008", "623290f47a7ec8b202b95f45d5c6408072766e49439c1aed29f023bd79a8e1d0", "658bd4418ebc07af0c511bc5f99c029d23d6786cda4c1d6f16e3f23c61fbbeb0"}, +{ "702500", "cd7f69f08cba82026873f72e8709cffc89a4bfe3c5300231a180fe4e7335e87a", "4f1bd226f6b1bc4313e7618f03e4522da41509937f596a3728da2310deecf49c", "364f12a79c19d5d7f2ce28ca42e34ad435f0f73a5c0f20eca5567f56ef0454c5"}, +{ "703000", "6253ae1e6bcfdba8257a18760dbd8f42bdfedce3257b9cff76660667e29e5e20", "05134bea7f58be79fbc3942bff929fef977a42b5bce28e787bdf2bbc1bc70764", "f51a6b93287a28af8cab3eabe6168ce93f9c2237ad556d3460874bd6a0c99dba"}, +{ "703500", "affc08445fc42e60d11152790408c66118b2a815647640a3eabc3006e0f58f8f", "34c74888ee86d1759127612373b099f56c53bdba1b0fbabb0a7ec61eb0f24ef7", "e691493935a99f1250c1d6c63be39aa71b0f92be49c7281ef5d9f95ace106ba9"}, +{ "704000", "5298b2ba05735ba586e9f6aeaad350fe88b762d00c4551d6b02f6c0b706b0f34", "9a36354d1266eb50f84338359401e91aad336d97cbfc39d574a83fbb4aa11d67", "d6ac796bb0fd95a710f0895b3373d11e0c20dbfc4c30182821df72841345b73b"}, +{ "704500", "f674bfadd8d412cffe1c8d6fedeb91e9c8914c3280414896f97e1c08e05b53b5", "6e593d4f49588dc6a68b5adbf870674cd17037cf7431f34253eb6cde06364421", "2aac262167b4696b70805dace94450148de9d8b38c1fb335a8f24074f6b24899"}, +{ "705000", "d288536328fe3b3301de1ba97c0237dcd740f225f4df07e923bb570f68716604", "b918a47fe346fbb9958ebff0e557b9febde26c435ff6320858bdeaa09ed0eb60", "0748bc47d6824e6078bca751e7e1ab4f8ee1ea090fa714dc177060f217ba1066"}, +{ "705500", "bffd8b226418632ef3a9f71f473093e5592f446776db14fec222f85de068c840", "e889bcd01a761d5208221642a51bb1d0afb1f324f74914590242204164287740", "b5d68b7d55cd34164b0a82778936cec4c44ba1734d282515b93eabd0d1870085"}, +{ "706000", "2547d907a333fdebec0140593814d90a1d806ee539598cf0672cc30a1d5c31d6", "77323ead475140b2224eb35de6da439d3832a091f1ca17e53a885d0b4d469105", "7bb1897ef463a29cd8fa71160e3548715453b2e75262cae48634a5d8ae5e7a23"}, +{ "706500", "5625e44c5204f1d9d3cb4b5b55aaa18f13be66ec9f76988159a172713f141fa2", "31a50d4821509dd711e9a541a3c54e28aad4bd6c6314526ba82e64857f52f4aa", "391dc850fbc3760fd29cfb5182c2fd2da847b2ab00fc95b890b659386878e632"}, +{ "707000", "e15531acfd422b5932479ecfe5dbec51af4e824298c73658bd43c143958a70b6", "e9af02a4dbfa950c0a45fe96162bf991f65df101072db521b4631ba7e64ad248", "122d80446848d02cb0c41f3c774e9476694ed3d6aee605a5d155957191f309b2"}, +{ "707500", "904129b3e99e06b3a75bb2b903b65b1176d82601355b13c92dfd2551edeea6e3", "4e5bdefe9ac9916fa5ba321a6056ec1bc8fa32ce3370587f13bed12c32976b71", "a89c430927f04d1935f0c5babe97cc0c5708b205a843803bc1a3fa9472d5cf5e"}, +{ "708000", "23cd48d83d0bc7e5b80c8a337389801ef9bd5584097667310342d92beafbabe7", "e916d2f42c77692bf97058ded798c541ce883f69786596ad94a22108adc17694", "e76a76c39fa7423dc5d93fbf49593bb5205d8b4d6c1e26d42d596f2ee90a451d"}, +{ "708500", "2f58264be757741e695394b348381a9ae8fd583341791a84d68d338cd811ae39", "dafed9faf74c750eedfc2e65491b75d4bae7d13b9e082e6fa91376c2d6034da9", "a01f735cccfc8003ae24b4dbfa89385a73bd68348410927d2ff7871863523868"}, +{ "709000", "e55588bd39fc8e754f2b272f80ac86b5515bad37eeeac6fc3dc0d1179fd53423", "69815269b65b334aa89cfca70ebf71dce7de046cc84b68f0f9c462da718cc469", "fb38f0c1e62aad790786497bd1cc083a3214baa52977ede6ceadab3b15e44249"}, +{ "709500", "e30d4db49a196e4ae4502c992118f37ddd6da696f296413500ce20b4b9838497", "4cdf69b6c9515176894db3bb5ead92d5ea1772d53717224656242e8007552228", "6d30ed16ebfd3de5f0e740adf51b7abc43bdf106916001bfb7e62ee5225a21d8"}, +{ "710000", "6f141473cc79d5def23f888471ff143ab546b5b1d1d5fd1fe51c996674e3018d", "5af180a3caf0ca42e0ba20e959495120693f273201de65aec15993cca37cbd2b", "b4103cd60381eaa47b921e47afa9080e02306159cf1766107b5c73e64e0c5715"}, +{ "710500", "10d11c0d1dc7316a7bc8a99b685c0b12c9e2bbec941d3c33781059c7048ab022", "541f760b8b3ed77398d5b5193220799c84f36e5cf342256921661f6d6fee0316", "2ca42896757f6e84ed6f2db42582eb9bfce4e21f5d2148b7d18a12a1f8a3265d"}, +{ "711000", "dd068ba9611f623d9e761f5e6a10b0298130c8b25317f047b6a4e79a3360909e", "920987e93062ef5eebcfeb0a98ff5b108649f1a092f76cad1c7d09b276469f80", "3be52dfa74fa750a4e97632d4a6862d859d6f72a2185626748c81290784bc4ca"}, +{ "711500", "96778f4ce3094a1c3323e3afd658b20cff90b2aa7f23d886a5f5629704f5726d", "9f4d8c3657fbcdf2375c92f6f7e700f8f108a1a5df22468685782c897b15865a", "b4be160bd18cc35c6b4a9d14008bfdca143ab1f9ef58f8a744ee7f5551687864"}, +{ "712000", "f4414c743e2b4f89177f92e0e11d61e9f3b1669d3ddd6148b3915862dd2b87b0", "df705fe65a056478cc8c914ead67c0a9b6023fcecb68dc7d9ec56a8c6ea1b865", "1d77d1875c2fff9bf63f833455e2db0a63337357ddeef49f50d9dfa9534831a6"}, +{ "712500", "fba950fc02bb67da1c4de9b6805b7bcfc0cf7e2bfff478568be99a70596267ac", "dc357d74f8f524808f3f41d6604d74a8a96c6bb87f695a15ad835abcc6669be0", "259ac2dbd6e8e2972ec7393e876b26818d1b0d8aeb44e6672c3e49cce19d1052"}, +{ "713000", "ff4dd851417240d00e594ee5fb5408372e4fd5585bb5ebf3d73a97dce1f4c41f", "b54673e8a2bd6d75e2218fecd8d20c0bff1b231b80fedc53b3f1deefc7fe4747", "f63d43982f24de8b83ab1d3837c6b7774137ce48f15915f0a7aaf6543847b258"}, +{ "713500", "92e49d6caa2cdfde8ec7d8c37ae12d995b9552c76f7c7ba0abacb77b02bdb5c8", "4c7b0f7d4f28c7c4d35a29c0a74310b38789decd628308c72a5a270a66ae55ba", "695ab5232e19bb40c61da6ac310de6020d1118c197032762b466f132e15bd1af"}, +{ "714000", "dc8dfa5b910afe73d3558be9d077fa57f1b6ac42e058227cd73b1b1cc0c70231", "9ccbffeff96630cd9248b3001d7ec7ccc83c9daa5351bafbdefd8a88c03f3224", "0031da42727b6f35ee4655ca10e454b4cbae45c43809098d870d14b6d9a8739c"}, +{ "714500", "e172274b228f5e4f49167f7d36076f71db89acf666b9e519da3a33c548515826", "14e35bb2ffc296d0d1f30be89e8a66f0bc7ade63250bd68043acf98dc625c91e", "b33ea3c9fcb3941d3783924ac3430b384a13e725e698be744396fb3e30632a7a"}, +{ "715000", "a9b83db90d65b2e1db885b5b708f1d7203019a7073ca3e5310ed4dfe19bb9d61", "1e2fea7d862a4b98f558f07e35d23b1d229dcbe2047a58f7bcec840147dae863", "44cc59497c3c6af33eedf74daba3925d8ffb15d32ab42fb97bba51511b227fd6"}, +{ "715500", "969fa24302ef22b2bea25b3f981fbb756f3de84f841d6f73ad9d6a6bbf463fc0", "31872cd93e38c92acd7b1af2ca83b7ddbc9319dd8606725fe0aa2b50026d98aa", "f6f41e6dabf4a38f8ab1df628df7d3cbbf10a40f7408bb54a74729e1c21f390f"}, +{ "716000", "e33babb3b3269852ab03a5044a595312e1828dc11169020fa2a05f4ab329ac15", "129a208db82ccf3418d94c00f39f3eb81bb7ebbe901f2a698362be4fa1f6e7cc", "4af118880519c0d6d340c1f491c3f83c8e5e35ff9dc64b6608c4e090d0aae0ac"}, +{ "716500", "9c0cd626f57ca90c771b00015658c387466c2f3d462d36d9fd3622abec903b1b", "044c3a4459440fa9078eb26f15d114c6ef9d63bc5b8640f84289a1f376b4b85c", "e8739d4d29d69754256bf748347fbd85f66714d772fbfdad9539fc14a761f11e"}, +{ "717000", "77a31d517bfcc769f64d0de88617d62d4d433c1d1a3136962eb07baa5f227a86", "e1f060643884a9ede876b52b38690ccca9c9d94140470024d2f825f4307dc918", "cb8be832b1d59378ba62a3ee348b044b60a74c8cf4a7edebff236530a589d5f0"}, +{ "717500", "546d0c517b9b0c5910d4d7337c366d76c7d99be4b875f673cf3876ca5458cddb", "814a3c25d78419214f5645a68ca361b0199b58ba3fd3109817b585cde74503d1", "1a3552275af0b42cfcf5250b893bd46b266ebf45a74aa5397f99f92c9f99b7cb"}, +{ "718000", "7e44714aea5af5ac9195904d29c9d53d03fca15e00e0f2c1a071611b6fd03011", "38d5d155e5a9992a6e9c1423f0ee621f19173c533e6954a46258e02982b89a02", "135d0b0ab3e42a885cc0ff7e579455fb52054127b4b6b46ed4fe32b871e2b4e2"}, +{ "718500", "dabb2702316c8e8043539190a1581ecb881dfdb7502a517fa183815a012eb344", "268c57e30e191d41a2793ad6b70796829bfe2726aacb3864283e82e384eea0df", "22dd681a53aa2818e3956d37d5be7589582b5d850211ea6ae5e539b003e24b22"}, +{ "719000", "9db785b29f04f274688856f0858c7c63961a6aec5788a94bc1aeaf483dcbbfa7", "8addd23f1cf6b051fc6bcd5558893366fa7a54ed89deba74d79f7a307c5224bc", "7cb536f13dc79ae18c11e9240142e7577142a4b1f474fdb45941d91a7be4a4d5"}, +{ "719500", "4615a7726a6b3b00fe5a9cc53fc916af6402871508fdc9b9f6e5799083edf0db", "3d3702be96cdabe826e24dd724ecfc426024a693c161889d0b41275cd6130d19", "087027216c909231bc86b0b4db03ceb66674212d63be60175b834599dc49a834"}, +{ "720000", "6b70419e1023a8dd272910d32c30aa0617bef67234063aa6e7447aae5356fe34", "55f7d559d3733e4d3d6b5c3c68265e088eeb6d2892671e88e9567f238268925c", "92e88488be2bc52dc5a5f775bfb82c388630a19e7a5238d47c119a8fdbe2cae4"}, +{ "720500", "473da49304fdf70d4b5adadf6fcab3f0c332ab5ffe82972dffac6b14aa20f23c", "3de3c3ceb92f8a7f45fc19ccf72f79f2fb8d3bc61654c534f81df978e905a3a5", "3610f4b330e9ba1898d98a64dbaca5d63071e971623431b2a1e873c31c733474"}, +{ "721000", "c293a009462b561ea37ba8614559acaa63cb6291673c68082a6e4691ab0eea86", "ea34bdfab3e2a7087605df85d858866b54b4ab1acd86619e99f6283a99f7ad67", "4d87009034cbef9f17d7ba20023efa90676fa62f3bd397ddc9e2a00e3b66a498"}, +{ "721500", "a15ef2603cf7a7b0ebec81fe4abbc6035183755a08fa11604e40c95477d61812", "6aeba98a3c5083b997eca56cd003e7f0285963bcb8502f73f2994dc04492c35d", "e89cf0c9fea734cb385b7dbc8af311bf26ca4564c58f338c52f8f0b5afcf130c"}, +{ "722000", "39271600011dc5e938c1308fc8f467fa44145f8bbc5335f24719d125dc92f664", "bb0387e362d72388584708287f86c92ae50f7ba4330c9857b308837d150906fa", "dfe30371d170807cd3e31ac464d3e284026235f2043a8a9d5bed5545e9595fb8"}, +{ "722500", "d7f846f9e439702e48044fe02c689990aa0a56613fced844d989816e0317be80", "f9308f9c0bb63c44b443473a8a25777e34d9a0e903edcd33598b270f0d7e9036", "2333a3407fb1d80d66bb3655b2ae3e64e04e8099ab1a0c37235b106e74792f12"}, +{ "723000", "6fafd8c865b3d0bb05f18cac70fb93007cff223789fb46958b55a205ffbbc959", "cdc9d13b0b9a5fa827d2572e9c3232f498e8b06ed8627199c61db9525469fcdf", "2bf56e3e72f5c449653b64c5568cf6dec1602888a9e77631b68b814e5268d29d"}, +{ "723500", "6ed55084a271a39809b6f3455a08d082fb7c56ad97427307ec207135c7c16ef3", "cd4a3d7e1dc9e293cecbcf14b969480c0c2f277819e9eb2286d1761df7320694", "a0ce856d8b19fa250998213ddce8e945e25238617d9632b1345fc257bbbfcf4b"}, +{ "724000", "c1b649d3101d61bfe8b949f443e1035a3d5944310f83e94785592c4cc91552c7", "452655726058f019fcf400a89e464688ba4bd0fcf267493e54748b146c7dbe1a", "c21245ea304822f3c688f672f6068b2c67de6c3f2658a9e9cf7a509cc190c489"}, +{ "724500", "21f5f4bc2fbfbfff183a3eaa110c1e3f826eae2f58d32242919026a8d1ea6206", "27b9e765e888343c7180fa9b5066ea254d8b5765b2d7e4a51ec62a8ecf02c6ea", "c681b8a5fc3f74d6349426ef2f01340c85c28bb4fc8857fb74d284e6b3bcdd75"}, +{ "725000", "5db006a94bfe731764372f332c2b23f9863f7741c0aacc4d92769f353cb4a4d3", "db57165deffffe98c3cfe7b95e119d0253a6e984d11fc2b1894ba4bb3010301b", "93b86dfe0990138a22c323a851c26bdbc1ae9d2c71b7db6468afbe0052c96799"}, +{ "725500", "f313538888a7b2cbf72adfff7c6aac1583c44b477c27810920835e1f36104ec8", "c811a4d09b2afb0e9e70bc9416e58aa2c3dfa4955ec4ecf03b3db9b65450e858", "2a5cb9561d2f20edc69cc6010ad5ca11a07d77403c5f090e404bb65a879d3e29"}, +{ "726000", "f9f289b08641492431e4ff87acb944092bb1fd4ae405569e0f3f14e433aecc79", "5c10e47957ac47afc2bd4fc6daa0c7e30f127f0ebdeb1b52149756d9f996eb76", "770901cce9162461c95f8f5506586075d2e0b19b82f94eb83bebeb8733146728"}, +{ "726500", "769de3f5c47b72bb76aabcd88f8c84595015f6f3f8d78b4d4a0df2be171faf31", "12f1f3f363f1cfe762d972b988ba7e0943520065bcafadfeda1cd73aad8c2aec", "b38726eb05623a3e08a3015a53ceb5de482da78b04c14de040f543cef35c2650"}, +{ "727000", "2d757e0b21cd7f64dc962c5ef6a7268d0e0223814f74e6fff9c81f849e496ded", "3ef2c4f48504f065f4efc06814674b635ff6d31e9b667f9b1ad864819804f446", "7f02f5fe584df7843a2d2590e3a1539fcd8c8cabfcf9b196fa686e2263e50e12"}, +{ "727500", "5b2875cc1b107110464a44d7d9a1835e8c19246cc4d646402fd3bfacd53b7201", "48695a64b57a8523e285989dc5bca5360df44847a66d926c154c6929e92608a3", "5205580f5bfcee12d6d83696744f906c044a5ef6f2e15e45840eae9bac331622"}, +{ "728000", "35fb3c9e4fb0a40ebced7b7d2e9bae928790bac78a8460c311b99e70cb109c9b", "758fc72831974d7f37e9307b34f80de04f3ceebebfc97c79eae5e1dabcf2374d", "32a4d80985277ea290d1299ccd4b5701d8b809e6b3dcb2c401cd66f75079fded"}, +{ "728500", "156a06f3bbea42cebe61c148aa7ac4cdfebf95edde5d021c03a90ddaabffd20d", "6b170063e91dfa3d05c9d6edf71577d85a9e3f0ef734b7376f757d1bd5a42705", "2d46a53620e7d1d09d96f753cda4aa6de2300f05c4d6b2f5fadc3220fefc9bec"}, +{ "729000", "e8771ec45982e5e9928539d0f4f398b3a35f02b92f44ff6937e6a6a50fdf4100", "bba9a535cc36db2ca8af73b8707635e3c12b3125b320df91257a944ea3a6af8d", "c0d1699b8d4e8fe005dcf224e460dab44bb1f6393036f0a9e7bdaf3c740d655f"}, +{ "729500", "e17e17e50ead400f5dcb3f3ffec5a1ff95da211a7f6d30f87399cb034b2fed00", "0263cf2e76899d4424125c726396ca7c8c3f1830eef290b084bc67aa3dff7ea3", "17725208b4e351c91f043dc00ce64fc4882b12bc2f84c793cddbaba08d27e845"}, +{ "730000", "06ee01124cc2d7e6ef4f764638700ae11ca26a457317564df6e5e7f0d881ba4c", "f20e5e74a5a07e05fbea7bdbc73ad393bc83a144a7e15d03a096f052d7065eff", "0ea35c2865b1b0dffc4062e9cffebf710ee85294257e6b5de53c0439e0624cb2"}, +{ "730500", "2692d795f114318940b89b8aba8a910b6360170048ac824590c5d814f8b01973", "9aad48ed4e603ebd7c79c8535c24ec7d2ddf7db6eed92b9d1e83846e9e139a1e", "9958167159bba887a61cbe4100f975ff830eb291aa1ecf35d601e81c825c54ca"}, +{ "731000", "e167080479d38ecc4cbcd16e4fae05c1f87e09d33e4947b6a9813ca63e147d5d", "ae82cde68df2aab3ef79112d4080a285b806bed3e457aa4215c6ee35a6d73e33", "701917f137a9974dcebc359e7f39ce47c4c20127e5d90b0cc6f715290d4052f0"}, +{ "731500", "d8c7e6903152f5f559f108449eead76f647a5c9991f2815eef0d0058c25b6bb0", "f786151a72adafd6930fe59a04cad481a49770c191a3f5444eb9b4d49b000779", "1fa2adda7b69711f052d101fdc698be6cf424b7c9aa12ad51151d4fb61455c8b"}, +{ "732000", "7371a17e1393bde477a0beb136f98e89dd30f49ebb28cf59a265dea0f82deb70", "67d98bd80facaa69bcac4ddff46661d1dced445c622bc90bbdbe1e7de9a8f768", "12daac68a822872d95dcc053f2986f4d792377ceb347b5803739832b840425d7"}, +{ "732500", "921701199569749e2d13f7940e6347ded7a3f1dfee26b7f7bb744d5d3db586dc", "41fd3e2f31c4d732326d13c5f31cd850e864c43f1f179d8631ec1aa69c506d88", "018fc6f520e5ffcfc1f7cc8cbee755ff914818f3813b1c4fdf66ea67a42adb82"}, +{ "733000", "d452ca29f9949b714f175c7ca45841a6519857541c44df4e52caa73b4c9b347a", "616e3b11378287c338d03dc5e2395c5500915fff6340d6fb48c0123e33f92d51", "c33b9f88d8fe1a9f7392d5244a3c81f4b5e6ac8ce5c6bf01116acd3e582fd438"}, +{ "733500", "4ecb0e1b2273ed4df5bb7db47988c3271e81cb9933d7cf50120e9730db47c82a", "6dbe9a6615825d26d58bc5a2c068e9068dc5b4a1402dda75c43ad3810cc55a80", "85633a636edc1e9e147caa51f1dd0c9f347f224ae059f80a36e905562e035a1b"}, +{ "734000", "6ef7723b332f6d1a4791f14a1cf2811870cbb08c2484ece5cededa3f69fb920e", "de8e532d9596a92249adbea9833ff2022f96bdd3f82b7c734fc3580b4b3cc946", "1a3f96832ed8a83d09635e696af0c7e9c613d1223ad319a2a3b67ad0258f05b7"}, +{ "734500", "01d19d29a83d79e38c274b76943e9d5769932a6a7812e3f297620a40a0bc922c", "ff43eec3f821cef199133f7c5282c9892c1b1546a77f6fac3e9021037481fdb0", "9483a0bb66b7919d3e4577e0d388eb55554a2a9ef1e151625739a14fb9b15499"}, +{ "735000", "544a5f6ce7a71e13db7335cd2a4e02fb7b5ff98253016f9d7f26956dec908470", "662695548e437e31e7687cd4aa3a463d2dbd1b0579df23c6f5daa7e9b3788e66", "c746d32bd2dbed6a9eda016c6bad0036ada8232ea88b85dc939b7d12e0983b2d"}, +{ "735500", "997d9b45e87e6f1f1b76c7c212527bef213f348c51d806200bf6541da07b76d1", "68e5ed2790eb489379491eeb583227ffaa09afd5b62b9073117e540505058b8d", "b39478fd31667381d09d847574aee5cf03b9477bce4f683cb3600c6aa3f1950d"}, +{ "736000", "b371ea1a60567133d86757ae1b12faa8832166726b9c2eb67a643e6878b0f64c", "f5308b0f2fe00d7b1e1bde602e6028ba5f2ce8849da22ecf2cc07edb069a540a", "0cfe3bd3e577dbfb6dc463cbd437b5658392d640cff71ed697581ec6b7f7df85"}, +{ "736500", "ce6bfc2ae42b6e0893e4abf6edeab04ee36cae259415004f71811cac250e2abf", "cf5273f67e35b1bea345758b059f5b4b05ad705469c64e85cd90f392f03db171", "ba542ef5c7f0000a6e504124dc41cb5c833a9e8b132bfc51970f3971285a8de3"}, +{ "737000", "79e359fb34759ed805e4ba17b22b3f64f4e05bff59b0929d5a996038e3e2684a", "06fd8eed2bedf16f590dbe5210c4657f8f14142fbd12b823b4972a4062c46476", "6ea03bba2478d703a2733547490033224633d92a6d9cf23255673b97115cddf2"}, +{ "737500", "3d69d33e4b40ef18a677394e025c74f1ff03807f1cc1a9924301da4af97d40b9", "8d5cdd08a8a4db368da7ab6be4a68085fc9b2a156fc5e89b69ed661267bd9d05", "e2627eda436a29aad70b7ce047f4dbe731a21fcf889c41db65fe75ee8146106a"}, +{ "738000", "de67c044daf5e82856c70c57c05e0963d2767f721c9a2a3095052d271ff77a21", "3f6cace03de90c0a7093e549aaa5862b4d0d4304d20e548c1b77a7022a39722d", "7107bf0fd8cf132d24c92e2b15640e5bd98e857a64118b0a6292a1d36b1c0782"}, +{ "738500", "9857746dacb79d61819a9a7bed47d4f3f8a8ef2f0a4241e4a26e84eecc388178", "b324b1e1ec98f23aad98bd643e12396cb0e6db5b6679f5f197b8c82a74912869", "e3cc1d3066314c3a969cd1d4758b7d20919507e4a881f8c9162390cd6fb503f5"}, +{ "739000", "e760e2ba3fbf67764d9ebb7a9b5684b71d079174bbabdf7de315b7814e6a6d74", "74cb6e148688d11254c235898692018c699071730431d7e9f7438c6859e1b140", "f5a11830bacedd7dc2938de16c36e1e64b8a15418e99c443f3297a9b702be043"}, +{ "739500", "f066444b8192b7bb857f79443308595802f67e277d85efca22432c5dd095ca02", "91fdef383bf939a8e230f32a00ad0c58452c3bb0847a257a136297dcfd476a6e", "3ac87fa0067e5fa90dde3e5fbe065ebd5b81f5cf757416b6e218e9cb4006bad3"}, +{ "740000", "8d11e7b07aad1f84d0976806645f5d508acb6aa563e1905bdbfd49f88a83f561", "d1fa7be0afdec09bdc631fb8d5a35bdf26f47b479aeee287cee3557ddcc412e2", "327633198b1b9a062e0954dab483215898c26aebdb2a37ba043f5de5bf950dd7"}, +{ "740500", "54b44786a4b53f25a1ff7dcbe85ba288f6108cafb0abaf193c6fa9fd1bbec690", "511fae7de79f3e6aed0645375673168bba00a2d39563ea2596e09e3a0e609840", "53da3ae936a368c0341d066925cd431802924042b0aa65f68d03c3a78b256def"}, +{ "741000", "6e98421219a255828fe8067f68097ce9d08c9f33886b8a29a22d2ebe6ba1f3e0", "ad33286ebbf08385412b7a732c551354dead015e466163e74e7fb5f94f6b1cda", "bed250411cd373b3b2be382d14df5c00745a98ee5b2a0fa07a6dfffbeeb3f247"}, +{ "741500", "81eb9f3b0f352e0ed1c5935647d526ac71e0b775d8715732e262f50ab6a55963", "fa8c84206d369ea634fb6668aff771d4c9d3ca7e687a6f2aabf1b2c80563b955", "d00302262d909b8aeec2869fbe84179c8363d6a099e593b536a188c66bfe80ae"}, +{ "742000", "540e29303471cd64e05ae80fbd19847c61476ca202848595583e1432e45b6a12", "01c47d0edde8e38dbef982a21b7b95e6049dfd3ecdb75763b3ade1cb8b804ac5", "6de5d07a99e47f413357b1234c46f8ec1750153692c54150808309b6f841f10a"}, +{ "742500", "6bdd578f687b5b04d2492b7bebe989d618b7d55802b977c9f1362c022d37b5e0", "abaccce8aa24b8424fe18df7490c67e36999e1f44dbcc68ad557c59717da560f", "46ce514134acc7a1f0c69feda82c4442225be9cb87077b320970e56dc8f49f77"}, +{ "743000", "1a56cced54e09d3e03f267054909c5800b30e571a81e21cb8e1960c32fb615ce", "fceaa34349bdb34a4bd0125a9d5a0d73ac8eabd0da333a665f71613075268854", "5b81d35da286085c8c5f08bee82e38a8c0f90d544947c92f8d5afe8da7617b00"}, +{ "743500", "2b102f1ce482314a2ffc09c26320f241ed197ef0ad1b0b1b05884d95e98b4832", "0d514c31a22d865f9480fb408373139aeb312d750df0441dbba91f6dd74b7c34", "39bfc62af5e07b039baccebca8f47e56677f491d1105f662e9b40543a7325391"}, +{ "744000", "9eb6d3d3bb45887dccff04f8555b7b6ee5c16af80cfc8fd132f2f5d64ef32d85", "18c336ab05bde704336b82417e0f8a33d6d70df4bcf3fd3277dbdbac7d285313", "3eff0762442919b5bcd423ac1a3c0b1405182a40670c3b72e50d7c93d7e5a085"}, +{ "744500", "2c894cc985ba39b9d41d6cdffd9225d1137285bb2a9faa355fc04e1c3a503783", "fafb7464d1745969dd5edbe08aa6400acd05dcfaaf6d09a135b206eadb2d7a5b", "93107399425dd94d165437b4c24878aa326f48d67164b4bdadc01b801790b737"}, +{ "745000", "0d3d86df05886717a850b573d540f01159dc4aeb9715260e19da107d8a5768d3", "273a426515f6fbbc4d1f505ac48c2be61e47dfddeef2e0725d1d287da3706876", "17f3b83f2ba432653925cd636891dd78d469356d1c8a18f40cd2860b9bd66a81"}, +{ "745500", "b614d96445616a551d2ef219bec80a8b104035ae75230819c08c1bb5d40d3eb3", "e8a90e0d452a4db19b7703651fd04988b45763240ec6e769e681cff12a9713c4", "94918b14a3ecdcc5c1bc43e98b4d437ca0483f34a6e375ebc6e217f004b0e731"}, +{ "746000", "32fd2569cffbaa373077a1d958628f5bb59edb4f1123ea22d827e59b58e6128d", "f0023c390d625e1286ba9aecfc80f28d96109289f7c438379a75c7b08c915f24", "381767ea931c005ac7304adcc66633a229ee3b7a73f67a385da507be65fd5a1b"}, +{ "746500", "51f9b04af9044618552cc030e88269c4c8b6f6285653003ea31fa0596b3be8ca", "21e1a38a259322e17a4fcfc9d45cbfb75c345d2475f7081373a9e8b791e3d906", "de4d31abc59236bcc16c6bd7b36a5a383000bb1e9b57d55ba02eccb49e56dd62"}, +{ "747000", "ea7dec43ccd90255b703203200c0b71d3aa7332a2bb43549c5b713bb03b77f9c", "9cf126abdc8e883dd428ae846e7fa5d694e87f40d1de07f772f916de45db3de2", "f28ddc3a0c8dd9831dc98edf8e7c80395bbc2a6f482ec626d2a43d3f6c0dfd24"}, +{ "747500", "1b651b29875be11fbb4fa8ed4c857b030122b7facdc75ec31ddaed88e3623566", "66c676aae65eae30d876db4035a19e8e00bdf9a9331361e72f57af17a3da4dcc", "52c8869f00a2fb858219119c25d1e9d135bcad2fabc2e4a12dc96063b840c04c"}, +{ "748000", "55f61b3e6a5434428b1a062ee86523b68f5459e7615c29d83f01eee310ec66bb", "4927588d5f0600d0a418298312581aab6d41144ee3bb87a6875d7b11c676704d", "92182c1111a64f08ba98870b439de9f81627d117715b3ea650bfb5fea98feaa4"}, +{ "748500", "cc910d9ef1a087c0c9aadfb77da9051aed5124b7d072b976f4d34dc74f842f14", "f1b10cb29bf15f5280b2506a480c07a610de4dd63212ac5fb1a33894c2fc0353", "d5d083bee08926e2bc17c9aeec940906bdf6b0f37ea7d6c2c23b2d4d881185be"}, +{ "749000", "70c48f09a23f35a244e22e7d43f245a20d1d171bd3958ffe261363536f92a087", "5cf7c04ef74572576b5debed4c20f3446db017a0360142b325a330909c904b09", "e24e68210d96e24cc04563ac6fee29b4991f3b13fa04d3b31f83506a03fb2a68"}, +{ "749500", "33d54681aff8149655455f3331792f7a4582c0f0a436b9d3ec0fced7a525ecb6", "95e2c8c804a409d62130abace845c696125f8a938bcebe60a45d9c76442fa6c3", "9c16bb3f870ee8e50900d7310541f629e4e087ee581467f3dac27c7601a9a881"}, +{ "750000", "8e0b562cbf9f5d9e0539f9964745265261cce019e73e22cd0db86f0dc7049110", "03a1b08260d16527973210066d867267be1f3d4692f3bc680afadd2b1653f995", "4c77b7a73824f489244a9a1ba383b413f23b932a2b7cbdfabe707ab95c66f5fa"}, +{ "750500", "a85d11029aa82c4dfcad63d3e6e32c4525f9d192fe8ed223ab9f05a3fc4a5d11", "1e1aaa3b0c05e04b991026c5a9b6a56228b007a6f936902f7a80f1b8f48eacf7", "79078573a0874c4d42ed9497435e6a5e9fb2a6ceafce103a28a3f4b0f9753dd9"}, +{ "751000", "bc48dc5090db1a9a8016b89fcef45999f9d6c87c8982dc4ed52e4b583ac2f7bf", "94ffd27371d8ad63511d87f728731b0513ca8d8b948d8b777d852ea9aab4804e", "f0b84e3b614d9701a514808bb116eee3547821b42e0d2f6d6a3d2ed2863d951a"}, +{ "751500", "c45fd98831ad0acd126e9fc658da6851a2a14a1cb037ffa596da1f2da2fc47cb", "82be3962eb66aa5c0fbbababddc65c99ac5c70b372b32aff94aa47392ce6b802", "11d04f7ee3e0ced8bd872e7bd5243f39704b3650db2372a57a37b1caf00105b8"}, +{ "752000", "373e8654d6a04c16dc7ef938fa6db6abc8672283a0f027cc34eecb1ec872ab7d", "bc163b7e20ee438640c02e74d48ecd1f65a4bd4b16d21248663a48e63eb02616", "dfa51a2b8c35ea201b2fa58dc759969dc8f41036f3ff67e5710f2a6b2a8bfbec"}, +{ "752500", "5f217d14da39d80fabcaa06ee56ddb41ee0dfef892576c2e100793f03818145d", "91a33cc31ca938ce0b222ee141bb4edc500263a0689d0aed50660f8e4581a960", "be525451b8e4d3066207a25961ed80d3fd944ab128b1250c657bbea2be7c8ca5"}, +{ "753000", "3e4aa8b1ce5cd84238df7ad4558f411a41a674ebee9fbe087bb41e880936a7c5", "7b8530bc78bb832d51460962af3cca2f534cfdc28760d7f5363534e68a72ec9b", "4775a888543db3451784cd50e2459d686dd66b08684e9f82b2aed331beed3c38"}, +{ "753500", "23a5236d81db31cd3e174f58fc2f9c1263365c35dcde4a20f315cdb01fc29d65", "042dfcbd5f30011ff7476e398e4c4b90f890a9fa4eac0da6b809410c3a9cbba2", "e7b4c5c5d5757a05bd4aeb7a84b112c965b857dd65465c2def12144d828e6319"}, +{ "754000", "5b4879ebfac928244d38117df31bb10c9d7c9e8e8d2a35c5c2f8a230b4593434", "c57c3095308f688759285e35312da7e6da208cba0f9db64180d551affaf107ab", "baaeaca199cc01903acfc8d30213c08fdbfee34e81f63bc7bbf5f0f9a97bddc9"}, +{ "754500", "96cc5bb1028f5ad1cd8a33800d9832d85700d037d5746d6cb4e58c1eadc8b119", "df2a0abff85d391ea42eda8fb0a1d7a750eefe9d5fe25efa10a9f46fb6110f8b", "f0c2a4150df181efea04ac95cdc535f8683ab435c9915de021957be8c4865bb8"}, +{ "755000", "e7129e48fecdac55aa3944a4bbd19eb16f0d8a73cfadd44a79d641aaa46dfbde", "385cb4dea3040a9b4d475877dd9d3cb61e23091f492fc5ad741a5cad2268c6a8", "9ccebf717328abbdcfc4292031c481d94e058144645784c9ea37b5a21962e264"}, +{ "755500", "93174ce679911cf73dee7fb12bc26b02889deb145dbc92d69637a85407812272", "5f000b1a76187f1c309f9495dbdabd5001f69bee3f9498316d0277383d861388", "6e5c681a580f3a0c20aa42c5cd521b5259b1220c25e47844929ef21d14de7811"}, +{ "756000", "d2cad51c4c7f604a86bd42e5fa0855488394561fd8b8e403c968676dcecf2f9a", "d24b9c50230b5c1aac5e5937e488ef65f19cc11fd4cb6b97497cea46061d7e44", "74a6420ddc2aacd8cf0c4802e46cc50edb4504924c64bdb287884b4358a45b48"}, +{ "756500", "2e24a5dff5e90a2bddd7343297d9e1cc5f1e8555a19606314e46c09962ead770", "dcd2285a17c2b37a17fa6cd27899af70be173d7a3d5c28c7f3ba6cf4d835c716", "29e38f84c118831844b79aab7038ebdf2b9a4107b7c2217512976b2536597d78"}, +{ "757000", "d11e6ed1c335b9cbb3db5e79e9ac728fe2377ec42de299a318dcf31ffc545ae5", "748036b1271dd158b39d7de65e91a95fc4e51fc0e9eb3445cf7306f15c0974e7", "14150ef035ca4576a22d8f67724062f82c3d51ce0899bebc32a1af8d0d06114b"}, +{ "757500", "0b5f20e382095632dec99c72f66fa419e1ce638a80671b8ba91b9a6d24f51e29", "d6181cc28a4fd461f6de97bb298ef188941d1765a5bf650e95d418fa8b7fbd4c", "1d5d6329ebfe3b3e4677ec3da843318ce79e3831a1c0805b10e30d718ebe1d3d"}, +{ "758000", "5a2a205c4c51fd035a4f57e79f2d92ca5e3c9af3c8c2beba21a442fb02b2c705", "e019ca24e6b67025cf564537c25fc2e6e241b44730988c316eb32aa8afbb6804", "a3e465d0821f9f2f099aa45c16db42cd1f93bd213f010ceb1b467889f30d61b3"}, +{ "758500", "e33c965b4ebb8b924a1fb73c65017199c806b762d4441854b79661f4de03b427", "313706df2d3cde7074b2f6849c1f134ede50bb46a297da3884d21a1828ce8072", "3a750153373092dcfe4dd326860d933a459acc0a9a686516a59bb70b070f0ec9"}, +{ "759000", "31928e69c1bdd6c727eda5662bce3f72e36496d538d9fc1cff1424bfcc24d0b8", "98b76d0e9682ac933b75419da77ebdf7ba10f016d35d26638915a5ba5be4db94", "77111411b7f07c74f18996a48bbb02906214463af40540656f4b263f40fbb8d5"}, +{ "759500", "2d322b637e8d92f51372101bf714ba726396d413b0a8e9ba573018ee1023b0c1", "caea6763d02b49152bce73655908d1bf489b2918b8514982a2fbfcb1099011e9", "e56b99479d6001ec1424744a425809882d6309a53452d7d9772aa4eb3c5f0fff"}, +{ "760000", "1cd9bc900f95c2e15a802f7eceb33ff51dd12a71718cb4220e466bfaa0f5ffaa", "0243b603adce50f296920262a13469d2ac1d0c42c2ecd633feaabea80a4c6100", "3783656e78d3879fedbfceee5589968967364f6af046d0f281bc8b99c6d1b321"}, +{ "760500", "4de4cae653ec7611cf7079c4deecd470afc39ac6a083a7b5ebfacd9d789c4394", "d3a390c8ac0a632c7565327db3e9a4fcc30aacc43e2ba57377a1477235124baf", "2e276fb93c0e9608afcbdcddc74fb5c5a9fe3addcdbac27871aa547ef7819b05"}, +{ "761000", "6aee8513d50a19fdaf21e0ad49ffd92cea289ed0fae844cb3afa16ad3e60b934", "045c6ba4c62d4ae995dced0633d85b8e120542be2533abd9fd1fc8c651f47563", "9107af72a3f9b005b7ba8b6c379bd51ebbdf55d3bfd7d3f9b39c6ebbf3d62546"}, +{ "761500", "b1917f5b3a3f1acd43c09e2d975abdf63f4a2c6d0b8ab429b47f467020e5b31f", "c7f69fc7d9f169a97f9ce25956c25668cb780205eb59dbee76f592718d74503c", "21a08cc13cf867235f5cc7471480d289f3e7e203116d607853a359ec4e15bd7a"}, +{ "762000", "5f11eb707b887cdd88dfd5f98203a949824d1fe960c4c85525995a377a39a79d", "6a3963332b853b978afeaf71fdf868b0d36ab203773c958a5fe5a427013ad02d", "f9b97eae9b714d0256802379dfe0c9efe2812b64cdfd04425c13f14c4df8c893"}, +{ "762500", "8c3d3c496b6ab6a1e56cd5fceb131d8a9dd8c4fdc938d15e6ed090dab25889c2", "e6eb9f858bb451d57926036c80c3c7ac4617b7897b19f67e2cb1952ecab6a24b", "4062917f26bb776572408ae3fb0789ad6376c988ed58e99558b5a5f2ad19a55a"}, +{ "763000", "6fcef4afba243507e7d54aeeeba6cc7de011b43df9d90f364794e3c59621b980", "47461602514b2ae53177fa064e5abfc46da728227988a9388120901fb2dc9a94", "b58aa437641b3c7073ad03061ac0e9f7e84a8c40cbf5c6f2e237584c94235c4f"}, +{ "763500", "41ed18026f39928e570601d40419b18758312017a7c9568d73d12d4b828a121f", "c04c199a5b9d12441ed489dcdff90453791925fa29ab6eb6c62b0c4d648e28b8", "ca6b362ff73a0d0f8f2a7a7088004a73ae76da9b9d2a22333686a0e40e881d07"}, +{ "764000", "67e928458125fe2e3c6970092328b48497a4d26c6b04b01e53cac4de70fea64b", "9270bc1fbd0aeda1572f2c2ef56dc700086652533d70be2fc6d13e5bde70f8e3", "775bedfd115319f5255de4354039a7159685f98370819905b6ac06e5202e6f22"}, +{ "764500", "015f8999e9b59d173970ac6f7b5b6b460879a56fb254c55fc64c79c2f1ceb2af", "0fb0da763fc466bcda98bdb2d28195935e5ed9c8d35fdc877160aacf553a4a3e", "7d7cb857eca8938dffa7db3374ff242e637fc934814ca2fc627b3c03f90b6d10"}, +{ "765000", "9e706cdbb0b6dd01e5fed36ab646fc0a80a850e08f2088de2136388d4db8a219", "f307dd0ce42f0f743054ed8236b6e8c44e4370634d9382ba439ef593210f14ca", "cf725e3349b816344204d20b498755e08ae270bd798b55a3081642af7c9cc320"}, +{ "765500", "76b996f89bf12e2d725e1df6b6e1f9fb71a0e4741add4657f8233fa6b1a9cc0d", "1c1d390e6e339f40129dd63bf89b9dd34574b6c0e16739449ed1936b023f73a3", "8987ba1a7fa864569fd085de2d8fb6455ecb5f19c20cc57485ff1ce2c12550a7"}, +{ "766000", "46b8674f0faf71bdc7bf0a656e0e02660d90388ec7c3df894b0b3562d8541ba3", "ed993dfee8eda538ad156e46f49e73c96e6abeb40c4e2ce1b34751bcdf4e7bbd", "90b578e9e673e5a0bd8d28b9a19d65faed380af38b35dbb755f85eb0515e345b"}, +{ "766500", "719246e48b8d681ea5869953004219e8e9ad1ae095d9f7005b39316010542a79", "7d760e07389497315c4c3b10c43d939fa4e1d43dc29fd4e898911ab78a6943c4", "303206c118e59260c94e39b6cfce312c44f1450ee1e223c4f0ea0880f8e61470"}, +{ "767000", "281b1c63ced6e6a9e548f01039e79b341b4c75980548acc70b0c52d71feb8e6d", "fc8bd623900af0aecc3fdec5de0a55fc7889c6b3005c4aa8fc3973a221702eaa", "9b9834b90ef9349513a363f3fc57dcc98976193b706a9916c18b689b4c1f01c1"}, +{ "767500", "d9a20cb9dfca54abe3534dbcf69a04b8f6b43afbe3703e7aebb2bee8cb81f73d", "899b241bdd3264be250d3f665e9930a6b2f302e1eb87ef65845be021d856c35f", "1b6a40b17f0dda2c341f653cea81e3d6e6a8ddbfc9aaaa063a145b3d735fa0e6"}, +{ "768000", "8360e09883922bda97c55167146f583896798f25e12baf10cbdb39254ab11ba8", "fa86336cef4c01ff1afee67169e0f4a3810546750ff4c38cec86e37c27444bb8", "1854519636f63903204c5e6d7375411fe7d4ca51126a9b89bd903da11ea8088f"}, +{ "768500", "ffb03996ae3de8c5bf73eeb51ca0527f6ebee4b20dd059828efad08e7e6601c2", "df22eef90381eb583a9e93e90e0722e0a6210c72da28deed40c27499c7a5ef21", "b8eae47b85e4f4a219be1ebe5901f57de53415bd7410ca1b2577aa908cbd1fa4"}, +{ "769000", "2103acd9679638073a79876db195d494213d9d6e749faaeaddd6c672cc7e177a", "cc3a63870c9ff71fe67008397b61d975a8147d03a0d8d35a3565538ed514b4c9", "0180d7731d63e1b4a4ba0bcf7d40fa9997c0520eed0f1c89959c4f705ddfcc11"}, +{ "769500", "9336bf1ee4de809e164e98a29bddd7a448333f2e25de891b4ac528d1bd7af785", "605f77b3340dd29717f7ba780e9f4ce15fd0fa43f2ed916b9e54cf23aab2863f", "77371c10af50eb346f69bbb2a16a91044a48dbe7bec4982ddd1f3e80b1da8157"}, +{ "770000", "6182eaec959caf801de20f3000efc3b9431aa1af594a05d704bf2c53d810fd83", "1ff43d1f6b27ee4063f01fd16f49110f0db50d58ee4937c28fef346f0777335b", "469227309694c2f4b2bd3e0d691164a2b5e6bf747177ffa5315b26f98ac69a7f"}, +{ "770500", "5405e7303c38724438e124b5e518c9af26a0076596be02cc57348e91a89abb6e", "a64f6256dfe425b8fb3b98b45dae59bac34213b85fd777b91d08d15a62a25623", "f5cb13454e327025100ace0344bd4af58e088555d3d7dd78e5c0ccadbb3a15c6"}, +{ "771000", "07874de328fb41f73e1aadae9e57705d7679e8e186b8b6a2ac50ed5d1455d1a0", "38084368706c2b4c84de621b821faec1466db4cd8334bbb13e4eb6960dda4b5b", "8451f8da96a32b867f9fc444493bbb25d26d18a7eace68196afa1acd048f0a5b"}, +{ "771500", "caf1cde2dfee0a11872272140e8043b92a33ab604f0b8a8c34d7a7006a11381f", "eb96afea84eba379a82e30b8366611d133f219dbbc728f99d55419e5494c5b6c", "d7cde2e02cb4e0adad717bb9540c408d7de57c290db5f9fc0327e27f1edc9249"}, +{ "772000", "3f8fb7f8de518b519eb102a29f372ffb4627dca2bbe06dc035bf7ebd4e6b733a", "b6de44e3b4a2a16494b4d6d7e5423e1ca66faf4ec0916a8ac97e4a3a656fde81", "df44c8261bc11e19e81c4d8978013bd39cd33852c3b1315967ff0f4786949dad"}, +{ "772500", "2fe560018de02c9be5e9cb02c0d2abcf8d6efd94390f10d8eb84d9dd3964d53c", "631496990ae92715067442cef87711925361593696c1ac62ed053618951f9d76", "cf131dfff5f531c19ea26b7760c86cb3ac1b8ac3f8920f9c4f15d336bcb68973"}, +{ "773000", "53c1e8e472ee4d6bad6411fdc74d9fe4fe2564d0baf1bc5107b9dc4ec6262afe", "8d48f77bfb9b49f20dfdb2168f0abb988b8ddcd8e9e62ac35ab0a2968b912986", "e2aec43709ca010a47522638f0624907813138e1e1b380f7bbe6f180e628fd60"}, +{ "773500", "2836b1c2239c528ef1ca59823417c6ae51c93040e1a5e3ca11742dd10350d3e6", "16f14274772f96d6d2072a33cafd5c8f9cf4bbe37111b3f620e04bfc42392829", "0a71b92e9860fad2bd7f294d271466c0e66a73c057d4b8ad4fb7e0da53894584"}, +{ "774000", "69a397d817d7155b644d650da51d5413ed2c133a3cbe2b54bbab7ae7e5a82914", "c50ff677b8441b9a940984cf5ddb46f4b690ffbc9703ced2b163d89b929830b4", "f8a641d436f1f789a2f605267b1acccb8e851946b22731e19a4aea620672b3c9"}, +{ "774500", "e7569a38cfb85227d2d2189a89c59518b64da01e2fdc89bca8e4759269fad47d", "b72f3010914018a60019f151631c660311b949fb400e20696b900603404cb82a", "131c227374a68de26401bd9fb82fdcd47bb947602a40990c87ad1830d5c95b10"}, +{ "775000", "d62bff072790320b532267e13d16eaa2b6124b12e9dc9704ea8b3472c33a7584", "2ccb3c701d5d6730cb7fea0a703c1228f75c58b95dd167e135689d020e686cdc", "4434ccfb2b3ee14daec33d99f0e1a4f1e48f35ac1bc270a796db881fe872258c"}, +{ "775500", "69206115fd6be6c73b95c85875329472d8550ea98bbcdad27b1fff5f13f1a383", "1044c0b51ee23082e8268ea9f57e614ead985939009b2d6595f866bfd407c543", "36c58dd2f153bb315fb5ac171b2d7ea231c405a995705a9aa5448887e72c46d7"}, +{ "776000", "acae9ada07a40fbcd1abe244a88eea4497d892f56bc6c47c9a3256960c48a674", "fa6f6390e5912cac9e116a1dc8ce23ea3acd3a45ab8c372f265c2a813a1d43c6", "766450d063de6aab1e43fa81768c6d063e83fa9f1e3109eda9cf6dba976cf44f"}, +{ "776500", "c7800bf474c58aeae4052c7de8a9a5be9ec371403659d6ce87f478083814cc61", "5801468504c422c927e64b555cbde135e90690036800af540e0a515cde84a6ec", "3e003d9d796290a1e73dae287b93363e01403205bbaf21244b6abe9d079d0614"}, +{ "777000", "60999146dcce1a4d7c57777fd14c438aa74620575ee304da40f3139145be094e", "761c802120daf7dc3d71945a83698a8ec2813efe961ad3ddd5f0e8b05d88824e", "34924d2e59d9aed7ff6e66e5e35e97aca41d40399f5aff99be4319267e8d8000"}, +{ "777500", "55464b5c24a72ca78e577947e5e31095625d4a5453d4ae8e1a628586173696cb", "7198361fa24cc1510d0eed076fab9402f8d312924dad53b2cffe4a2634450753", "2c96807bf221759fe40c6573bf7ea44299c5c292d72534b698f20df0cea9fcfa"}, +{ "778000", "a96e3ae7c78171f4839888370b8ab6a75527c35181a76170fb0c0048a340efa9", "40f745faad08e9ec7fb07610cee6fb0bfdc4b221bfe568e692928cbd556fd0d1", "31a1cf9cb956557bf6c4c96b3b6bc5d4f9fbf8c53a37649b6691ecff7d076793"}, +{ "778500", "dd54a9dab8dfd4362d396a50863007b96b150c454397a2b4cc486f8b4436acc4", "45f3cb013e25a9a12e1998baf79504649e32d0405bda1b8d6cecb7f51597dac4", "88b4035bbf033b809c2c3ad7e410a48bf17a5704e49fbc92f7792d3932a96bd1"}, +{ "779000", "04bc1cac32dcf0121905e3b0f8bf15938de5a5470e130dad3d5e9478e5c04ded", "dfbf8b41e5cb2498ab9f6c772c18ae3af36f693115fd0b7ca12fc18fe8dc9d6e", "be291b18bee752f9cef517ca4263ab5ffe3d18de70f60ba98a0e3301ed8d5851"}, +{ "779500", "acdc4b3a573253149261bf7b8483f07e26febfa36a79b0f85663d0418bf89a87", "c4e9858c10b84a43f0d48b59f2aabbb978411667e1e740d26cd90e824e60bbcc", "8fd3e1dcdf0fa802af029b750601b028e971f623f731e35a2baa82b04868c384"}, +{ "780000", "70e69b1c46b39329196e880591e35915ed2ff68cb83f2899e1c8a09885462ddd", "eddb55e0d58a9e963cc6bd8e74cdea45af4a42783f9b070eac50fd00b10933e8", "25c18241d995a1759dec8fba925b3da79c38c3ec81f19989cd0526929a3f270d"}, +{ "780500", "44f6b73dd235490b827c83c949f8116d3e794d139ff88688db18a6b45e1473b1", "011d86e2b32e548d2143b273ff895d85f132b7ad91a6ada40d29517155de88e7", "d0e6dcd1658763ad2e899fe15a7091f139bc5540ed174d9a5b774e61fe6df67f"}, +{ "781000", "afa04315bad0a73e082c417351c846b882f070fb89fbb62f94bf6627355eaba9", "83f5ee23a34675c501aaeafbd8589c2173bed116beef5a6c05da3652da34eb4a", "96aad7c45f8253066e4efad6a5fe94c21dcd772afdc291cd30ba0acb0e9b6b93"}, +{ "781500", "daab9fd8e2a04d026d3dc748d775734b92ba9d42af448b88c4e54313458f8e55", "edfa9dc118b24ca0b01976fa94551d0e78fb276ab38af92581b336d08ad979eb", "04faece12c26b07545b058a21ae9a71b478a34ba3d7a362e394bf94d9d26d83d"}, +{ "782000", "71ac38f6202666bef6bd02261cdf9590ddc79b15b1f0fd74a0991f32d7076cd6", "d02102ec38f004cd966d4e8d53db021475903f0630404bac02af92fc1ba0f055", "7abe17429f2a42b3e4a1a9b48c21cf087f9de1afde339f2e71bab9060551aad3"}, +{ "782500", "7065d66fe20e800ec4e007a0cd3301a98985fa7f755f0fd904b2a999c45f16fd", "c68d77bdcd1b1080ab776a210493e4371a1d30e3c73d7fe871e04b9345a0661a", "f483702e71f5a84316d18605c3cc41b2cd010aa444b88992a7d5d48569d18c36"}, +{ "783000", "d494fe23c434284aa32d3043e1cc6443fd7bf9b36fe12410f7d2e35f5360b5e5", "4ef3f9328e1d2d96c19ca549d1147c2063430601ec62870fc66c5b6e68aab6bc", "45489e8456e3cb771b5aa7897c56a1602f3b861d3656bd9bc504e1e80bd050f7"}, +{ "783500", "568a8df7d5669899b02e916c28755a8d1fc4a111f3af3dfd4195298ab257a847", "7f752afdb474b41347fb14da6be44561bbd5dc034ad25035718d57ba0e326165", "f21daa8b18e339ec5aa19a6ec0d285de0c17589b5e0b0ddf74dc4bba29ecae0b"}, +{ "784000", "98aa97184148b247fa71460e2ac43389d0d04b6265546ce0eba7c2be328b6bbe", "cbb9d6529647174626503265092201bc8ed564798e1244839a9a2f022c5774ad", "3ffd983e39a9c3619919a3cf95f271a5c6e909457d005756e301c54cace97df1"}, +{ "784500", "db38f59e0843aca6f105b25581ed990384b8b6fa6c340cd21be37799ac892e8c", "bdf27aceb99b7e0386f937d7c1b8a5a8cc92ceb95cb3191e5502b41245ba3465", "8901786cc7cd832d1ee4b48e75d8b747bf9c729a742e7f6e7270c3112fb7df5e"}, +{ "785000", "ddb1f819bd3e7a89588081208e3dc87ebca46dd381593d402bc80aeede0cd724", "814c34edf844fbebab1739243a0a664de608eab49ef2d91c57ef7195bbee80f6", "3d7b3b15cb2fadfa928ab49ee537cc627e7bdb8a0fba2d2f0042945b7d87289a"}, +{ "785500", "92f3c145e77f1f518c1decb6e99b826ce6d778c24634b3d6d3340897cb670c63", "6d607478b75d072ff0a14c4c23454a04b9a08d3f9c196ebc0b817fc7b9efbd30", "e59d891441d06cd8f973f6ad5c05adb3e5666bbafd72408eace7c7f4aaa517c4"}, +{ "786000", "07a5df141fe4feb999505fef56d930e19c684e5e452ca352f0fc49c2d9eea76f", "192297c49f950aee2578f0ee3249bdebdbf6955714b4a4e05edb3e8f24aae8c6", "1140d8f9f47651b9fe9974a905afbef7da25fa1f28e9815a83ecfae2d14323de"}, +{ "786500", "d9b454e9c5a5a6f9d16d22acadb61cf1ce231ca4dae12878d868598425eae775", "d47d551d3fde80fb8fc6886f235fb6164cd99133fe9dedc2bdfeaeb10bd45308", "0d7646032a898170d3491176f37f62d78aee810e11a73df03a36b2f9cb443f99"}, +{ "787000", "1d5ad94333c42f9cd396bd5a2772973ec2440f1d9f3cedade83af2e4951cbb32", "0cddc7f86a6714a3e3d2d2b004d1d3869d5226992f0bdf0f0d3bba94177b6a49", "7fee71383d6838eddad2f3ae1de0fd6cb0f2586e6265be99e5d78eb59c8e7e0f"}, +{ "787500", "b454323565de62c5e27b717877037c918e5c046dea15404d0817ed066267fa1a", "e428f7829407e31e1079ddcac80dab9b56743be59912ddbc0e0691178991b568", "fce258bddd4cb4c1e979f1db0904ac6822c520b292f36622b61dbd922f997569"}, +{ "788000", "28c337da150a017aca9d5619b15d605cfe5c41838893650f9a8108c4844dc5b8", "0d7ed84426c912c0a3d3320009e66302ea92039ebfa4eeed9bce380b2b2df8fd", "6472ea9ff1201bbdffd7b8344fa8c32f9afa5f23fa534b071b0fe78eb8072fa4"}, +{ "788500", "5f6ec263add108aa8bae692f8381bf9e71a615ff5d4dbbe3785167a10465dfdd", "3171b907ce8071d79c40b61ab802f51d8f1ecff22c4cfcf618065e8bdefa3910", "6d0bc878ac444cb0d59c77ddec27baebc74be98a0739f14037d03f7b30303382"}, +{ "789000", "1a1a8318353d2997eb996843165ce0a2879e058d6cc2498ac43fc495f3010874", "0832a6b246a8221f36b8cfc3c15c743878842545a3ef3b5ffc0f1cde8246b72b", "f309df4a8e1bb1278d50f91826b348e0f0b041db376d3a18c864d43889d05ae2"}, +{ "789500", "88387f881fec667c0a2943deb34f9e508a994383c3ac8884d24b1dfc400344e2", "866305720d60de682a074333f7b1512e45c63ab0f9090d8791f315e199222519", "a94028bb8240ee43d6c5e07090cf2b198ffea495e7051580c34760811f2d4c11"}, +{ "790000", "1659d12734baca5dc87174dd4ea3020c907031df843af6bdf22cc2ec8dea611e", "63e7e3f379c2e361085770ef24c82f250cb47056045bae37c92cd369aff4984c", "550bae5652731d97b02f51443fac5bd465c5f19ccda22e8e0e685104c5beed42"}, +{ "790500", "a01132497c3c4a8622f3c0039f319e7bee99942268a0ef323cda3fddfa11f1f8", "aebda06ea6afc6b95cd31185250686bdd815e89025a1b067f47db36dec1fb8c2", "a299c70cfca4a801fb39ace7e623d8346dbcb7ecaa9e8f58c5a556274cbbd4c0"}, +{ "791000", "9209e4bff9f2c45a6bf3d2dd4f8960b050fef2a600c1dbafd65dda57bcd909b8", "e005838fe0d4d7128702bd61e7be6be96340f3d4538aac8ec8adf6955bfefa94", "9ab13acad78de5329ba9ad59dae73b681e37893b6ee45146fbd04457df3f2de5"}, +{ "791500", "facd9b684bce4af3ed32b93fde842ee8d30775ca97b1b3a691ac0f267301b280", "df48a7e529861e94604eaff33a4ecdd7e35be502a78ce16aaebc413f4f4ba59e", "2be1c96a19a5f3631aac8cb883f8e94d85ec5099ff406ad5ea962a13d0dffdb9"}, +{ "792000", "8439d367ef216677cf50d64e35abd6a55d555260d8a4f53af86560221aa48b07", "6b7959d457444a0e8c085d2f366d54460a8e8ea5691d8d0f198275ef79b72ed4", "056d4125acd9efd6ed734709aa7b23dcacbc1404cd764ce5f2a7abfa0bfc86aa"}, +{ "792500", "2200f9ce62b2fbb1b25ba5e05a09301f576ca7606c2eebeab05a7188ff5d714c", "2b7504213f6fa99dda613f8e7bca2fc6310930eb40c405a06df793406d146b8d", "301ad8619f7c451bac9fd29d4d41c83867692cb87fa20e11ed94855c9251ee7f"}, +{ "793000", "3c520432d9a47e6e272dcdd99e656b04a1bcabdaafeca135cdb61b105b31d413", "6f6b8a462b2d883580b1e2acacb9ce051016c06a12a87219097e5327c39d84b4", "96a981e03d7f6b44821c7ef67805d6ac18bed8983ef15881e7b4ad026508eb8e"}, +{ "793500", "a9ede0aed7bc7639d97fbf8c81203349b1aed926ab534ffd055199c047c427aa", "6b6e849eb0227f85c0faf658c06e5b4b75e15431263bc587a0417b801910ed72", "9083b804013b0971b268c4ba338c8df637bc8a9bb36343d5b15a2ed43b450f41"}, +{ "794000", "8173afb6ef69b30acaed892e2cb93eb9186a55ec63a8730cf5f23909c13cfa9a", "4f340c5f5665cf08ec366e0ffe561908c19c646b9567ab3078ddc99ce216fd32", "53b24a984c2ebb796223af7d02150cd5cb56082a0ac5b6c1f047ea533c4d080b"}, +{ "794500", "debb2e81b7e22fe9f49c42c5d747837344567a5d301f900731c7ec427bc671b7", "79a735251474e25bff8fd23b469f0d79eae7b941b45b181f475d7bf8ac2fb842", "bccf02675e786af7dceb9fc7a1345362f41520089cc1e6fa0f0c3ce462db9407"}, +{ "795000", "a83507c3c3bd71dec9a8b3f471cddb67361e6401767c8c8ad348926ce4830d89", "e626138e04de566aa065b5a7106daa670c614de2ab4d326523bfe5d1a4ad4899", "6aecc8858c719d0a8cc549660b54f5c9e8a34cd9cac07c1289151a482fcd37ba"}, +{ "795500", "0558ab8c1e1ddaa709688f0fbdbc1413bd8f80362f6e053f20479e9aeeedb4a3", "13a40efafdbd6358d9ef9f1b9307a88b458e999100a93b8f4611542996eaebf4", "9d679d11a6e91fad3b2f536fe18e47c9d6590a93967be96a98866779722f199d"}, +{ "796000", "a141fbfbd754e10fd7e956c10d459834261d3571affa49b8fd90c0c804d0fed0", "00fc2ab3f76f3b577f97c348313e9256331ea81a5cfb7d8466fdf144c8e9fbcc", "252b656f49a41308c16f727b69a001dfc325826b60683aae6bec855aa0517ae5"}, +{ "796500", "7351e53a275444b95005213efb4a5a1397a7a01d58b750323bd37ac47326c704", "57ea2db92ddb3e36ad171b3bacb48f883fb7e8ef74466fb769f7d5553be66c0a", "95b1da9a766ee86ab81026c998b07fd025d6eb4133c3279994aa4a725adde067"}, +{ "797000", "80fcb6e51160ba191312939b815fab48de5a56f4121a3d2cd7b6925918a07af9", "96242babb7769751d636828f5fdc2d1a44ca57e399fbe5b0683d09fd66b83da2", "3787de63477594b2a378e31210707d4b61f18d39bd84c748f70e260380236c51"}, +{ "797500", "57bf7c33a40e1813c1947efd7412a3977b0d74ebfb6e846097aa45d03eb1fe47", "e1250b6f44746881c59360dd6144bf4d2e86f8e31e68b0b820732b2a8bd69d5b", "316dbbba75ad23f9bd8cf6cfe3f6a277b1ef742596a3025165de2bd86c4da49d"}, +{ "798000", "f3370335ede3598caea04a87041fa7c1b51e5c9e1c5e0d50bf2bb136a64cd167", "e6e1d946fc72e48f0399f980e5a4f7e544b4eb2997739223c355e3b15af48fed", "647618c6d3effcc52dafc6a6705ad58695436d48ef25aaf8d684220757bca52a"}, +{ "798500", "8f2f93e0248a8d8ded2c5106fe5034916127161f1a554e2ce307c5b6afc3e00c", "2db41c24fb6ddfebf0b3bb5d74fbc1cbff4185082e7c22ef66c336467c652180", "ecfa971d637bc6ee3e0f461ddcc77ac59a408c30dfd2ef3dae3d43e16c15e5bf"}, +{ "799000", "5c376ff3e907391741b0ce9601a65e616d6183cff6bf744bdd6597c455b306eb", "9b86110172b3879f17995b766972b505bf547f40e1113cdb52533357eecc4ef7", "52173724bc690d27ecf672136ad648668707cbe81735bd2a77202a7c765ef32b"}, +{ "799500", "bd143703c66bf324a5cbf67f9da778755b4f7a598450c328fbb011d1eba4d96c", "83480b97e6c3221fe90a83591ec104492b37896fa34943c4f71265cdeb5659ba", "07f30ede5076d4d94c9e1e8e46bc5402d1fae50effbdd0a50fe82d31e2e5bf5f"}, +{ "800000", "e951054363c21bdb8e2c65154dc8453a7ed6908ecb10ed72fab814899d3cd345", "9a0b2888559918507acbb704a78888f3293e34ec18cbc9961ac7842ca297984c", "8252634f061e18d4e82e3f91d044ded94e90d223a7de0a13b6e772c5c75eb612"}, +{ "800500", "956b9c5b3c055d3ff4ca81de618186166629076e317b2bc429faab8ed5a9bea2", "9a80628c0558276ab328fbbff05e76501ccc20593000dc13d57eb3ac4b618838", "f65f6f7cfec65d2c895982d1ecbe70336c1f8405783317db7207dccb3a5b0c66"}, +{ "801000", "3abcc1a5f4b6411fad8b518e4e0266bebf4d74ec36400e0b242e299aab5d8d43", "6e72ab4aef323f82c48dcd697cff16bb1f0ecb039a1a892a74c57abaed498d92", "21dc9821cf54c46293bd6e575907a6e5ec525713f4328952b95cb5d9792d7131"}, +{ "801500", "c49350d66b895f226052f92ec5d5f35b70596d37a64fc2f36e386c21cdc224a2", "1e1eab3a1d14c473a254babba1a8c9f342cf97b0ef0f60c2946149c72cae6423", "4385f5a51158e98057db889478b6ad2eedfbe9463b47f2998bfc8001e1ff5c89"}, +{ "802000", "f739f9b985ba0ee82823c7c03d7ef8788d23c01ffa5ab040ab23682d5e1f27f7", "45786b2936278a79a8d856f96f53f0d4b09a04056b96a10d5bf71f5ff849cb58", "25e4902b2c0f1ff83a7b4e0b7796d4981b31c1a50256b9b64b4f2a66fdfb36e6"}, +{ "802500", "1bc5ec3d7f952e5f27e9de2f21a30fe9333fb4a53b9627d78567d789cd578098", "11b12b1784bf7f779aa53e67753bb6eb9d1fadae56dffeb1b9efb5f1b1ddbebf", "db3095dee6d0a50357a953c8dadc06f2498c054a4ab1155c0ba5163d6cf928ea"}, +{ "803000", "06fe520cf2eb81478bc9548d5802a7ca815743a5e541ad64b995af5b177ed245", "f2401149fd3855cb680fdbacdb22b368edb2a34f73c59af55099c2d44e79adf4", "2d31efaf10a7dc9b590db9fec6421b19cb6dd9d9284d4e731f1e34e940f510a1"}, +{ "803500", "2bc1768fa981d73fe4eef0174018988fcc0aaf5316c8597cc1c1eae8618eb055", "b1a09ed639e05848794994217faf96d9b66a9e5ea926a08efa7bdfcef312b107", "70849af07f962ffc21625509928d9977d6650bde0edf450ba910b14928022e92"}, +{ "804000", "9d0ce3d35c935bd67f2970d8d3d5b098f99f936e880f9ec87cc5e0b1f837a0d1", "4eb8648f841497a4bf8388158844361e138eebcde30aca295e530b9d97bbed6b", "84d64f6c3969c5a92a36911c98b66cac9942cf4e8a0cc8def314b28998593cfd"}, +{ "804500", "87f582951ccb498931e71f194f2bacc2aa593bfd236519e4abd2336136333283", "9ba93a57335f44c4bfb962c33fc0698f6846755d94ab393b23a81fa9acf72603", "e65a4a25e45bafca371b86fbbf7780de48b39fbf4a5dd9d5397673c953f25ed1"}, +{ "805000", "efa84f401e0f8a68ac402f09bc3988192fd6c85f22fdf239e5b76ce100e3a2df", "a4a5b65c94cf7ce1d1cfe3c087f63037ba522ee4916dc20051d5953f6d42e067", "a788f574e086bf728658f5e9a973441e92aa1bf0bcabcb1b077d3951df73a243"}, +{ "805500", "c0aa476e7e6452f41dbf4cb5bca05893a93782716c3299f44cf31670079f3190", "349733cacd77e399f52831dd1f33884319cabf7934c3705e798fd8add0d90247", "60fca81f8f2814562456842b24e875af9df1a5bab37f44e67f3c7c74c70fbf99"}, +{ "806000", "8459d195b63e53f3495da811539f2c883361bbcdd4b0097d0ba214fdc55a8219", "9fd38c1f19472a144ec9b8cf57d8d9a85966dbc99cfb05628f5683dbe75501eb", "345d444fc91ed2f7aefa42cbfbac89707532f876a91b91c84462d8defc5ed659"}, +{ "806500", "8ca60c34843a452a19d05b38dd13aaaddf0cf602601ab66769801c5443380904", "f1a31e6d1b4cf5387c7def82294d179a656a10f438585a643e49dd6372982193", "4a88dcd7895c712cb2b4e1fd05517f68655072c04713adbfaa9c88715c4ed4ae"}, +{ "807000", "ca98242c7ff34cee593fe6dad4393698bf5875e9a980928363fb0f2bfc01e0cf", "040fc4bf74790e2218abe48b6e53fbc6103ccaded8f389a0957e9008f96c9e2d", "021b8cf0157c9b7b74d65d4a19a8409fe69f571ded09a89cf2b26df608eda94f"}, +{ "807500", "39be5b7e38795922ba3653d1310f1579b152e493ea3c8bd6630e0a561465fd7e", "a88ca5c9790cb9542ef0a64dee1b5c001d56bee7636c09105a95abc859ca5335", "63e034d22973193d76f09a5a933a188954bcf1f2d28a8a86d1a04a06a3c4c0a4"}, +{ "808000", "8e9c44d713b7bb2ad9d8cbb9ba3d9aed199b4a70ea1f7288795ca86c966e323d", "2c9dbc0b472b7ae26418b1def60df7a4869a35cf9bbf74b9a323d08035aa13aa", "95d2fac440da1af130ff838fae84ea9f9a91a2f707a91b0312f05d3ab917b744"}, +{ "808500", "dfd89eee02bd3dd16482828c743927801121f67cab61a4335d4eead749876a21", "549d7b6c5b66bd74331c6cb6f937c8cbc605dee884796067f42fa1bd04bc6a86", "21e6841e9e4a40775fa7f01cae49b438560c94b49ca8187bbdf7bbe578883269"}, +{ "809000", "676d2d9df28b1d4bcc68bbb1606033349d3e3a4c11790eef43f689d5e8d3ba7a", "18d4addc8cc3174723f9ce263cf632f3817d015245ef3fb6ecae87aed807b0bd", "a358260fefbe6b4e1438bcb06a671260cc74b269f25fe018ea858331c5b658a6"}, +{ "809500", "001261eaa38a49c58facc31b6c7245af90f5ccae8d120be1aa3b23f80e68513e", "1489cbc34c82aa22a7de85e615f2039703a23da1494aaf7b9d1c425e4839849a", "0954013be6e64e28d40eba427c1c046d767e295102bef3ceaedaf706e0e6cd52"}, +{ "810000", "051b563ee0050d2539bb0f57e3a5b5edc759af06e4dca9ecc9b651122354d828", "84359c9f7e1bd44948c4df3a1affb6a4ee05c2761f3b22a192faf696c1c8cfe2", "8afa7f4a4d945eaad25ed01a71a065c33ab3788519b108ad54074681ca8601ac"}, +{ "810500", "9ca81889bc6223d0195bb98eaae9b2b81771b202153dbcd4aedeba781063e4e0", "9ee6f32bb1bcd2ac2787662019ca595b8a2569bb90a38be9dbdc77fd30e0f541", "8d69e782ade3fece55262c1dbafc192ac62eef03e87f547dfff6a6682994b20a"}, +{ "811000", "e24027de80e7e3cc2e2fb95439a4bc88541b10316eb1b111d107119a154ce444", "373b8d3021db012bcd4b8558235d625a2d8eebec48f5c9c8784ce80be7ea459d", "3b7baa5ff205a15500e756427cfc82481b5a4cd066a8588e3316091e2c9ad1db"}, +{ "811500", "2188003a3ac1f51c3147082a9737895235c62f579500ab7207e04c3db272300e", "5d5c778748335e1c6a4d7b72e799a84b1128150bc5b782238c222d234b6e916f", "c3d6ae0a5807575eee61c9e07cef23fa13e0ebbe17686880a722c04180097efb"}, +{ "812000", "8edc7d32936aead671b293ca3c35a4f2cd8da3da8d0a911eab810aae919c671a", "67921067e57ccb2692bfb932c9fadfd695208ae63e41c58cbaa2d1ead989b572", "3e70e461d77ffad5b2360e03d535f314e7d007a5124cedc04d2a9e5142b55df6"}, +{ "812500", "f93429e089b8304c72beec28ab2589d33557ec36f12f1e5c21acf96a1eccbbca", "bceb1b621ade4000a2e9855c387f4575dc2599df96fff5fbb43a4e934612010d", "2d33f5ae00324de69262e4187ca0930a32a9168b8901d3bf33429776d2445db4"}, +{ "813000", "c50b28d6a65438104f28a3518afc71932e5acfc9cbd3dbb0870dbdf8e175e159", "b43d73d2203a216818e42d28b5108016335c606dceac6f6706641e240b065929", "cd035b84d4a9e11704600b28b2f363dba81d32c87e2c402d5ebe6f4d0eac3b62"}, +{ "813500", "9ea262207c1743a9666200b8f174328d53875437ef4238ac0f7f9f1e841d52cd", "e915810eb721a46d939812114e3017db4a2fcee9c0d3b6701f070d61260706a7", "4a7f61aab0c3b237dca327b640b730ff5587be83bc94f49eb5036d512cd033b0"}, +{ "814000", "7fc202882e511a8dc8b76ba9fd0e5d24578c5c45f51998f83d22e5c54eb72c5b", "69feb5f7c9e1eae4dcb884df1bed34f628846110480539f3ad02db9e49c87f59", "d387dd72b95bc8e7522e3525f2a1d1093358be2b3852c8298f4caabbe56cd679"}, +{ "814500", "946dd535ac1806a838ff7af300006a3b019926e3caef42f04e77cc50453fb597", "91645835f2dfa4f7bcd0818c145f349fc912335d0c28bb21f5a6c88833531ef2", "6852325a0f560b5ba965fc180e05bcce4fda06e5e3a1dc75e6ee57d127f94a1c"}, +{ "815000", "32f06e0d2112aa022953d25a663a77c34fb1f0089091be64755920e082588a50", "09503cf3aa4c5c2dcdfed49412a77bea1120ed6741f024f25384f9a2f6865f4d", "0a90b89381fbcf7f61b4340ee9a1bff11a365472d68750575b08560ae4f538c4"}, +{ "815500", "ac758032ea15073a6e7063dc49bac109b04e84245383dfe4a57d8a2d68e74c5c", "e8796fee578d7b8c3a1282cdd6106eb5be84df03f16f290b1042788e3cad77a0", "87f052cf5fdb1900a280431413ce9ec399d7709407e5e928ea757959afeeba70"}, +{ "816000", "4b0a8e17626d583d00af2d1e0d3d5aaa733b2637c0e7daecdc9ca7d32ef78b16", "5513bb0e272bc3c35af92c733ac8e3f54a4f9280dd6305eb3f521c0a798864d8", "f49d5ce010baa5a402628547ba02fc10645b15b1304cb1a975e850c18fdd5b34"}, +{ "816500", "7883f443a30cbe6777c45da4c70e650bdbdf7f2296d0eef9580b412d304dd1d0", "83b8b3ed3caa544c6827b267919896ad0df9b50b416b4092a81c4a16cac4a2e1", "ff6182b74bc884b1eaf924d2fbc00984d7a078108b8244b8bd65b2e2fbf61be1"}, +{ "817000", "d13df124f351e01764c49f28bd7bd9d94ec697abb36970435ede31462e245b78", "3668760c6bac61282ad6173be88f0ac74108aab7e6b2d5b89bb05be5f7450139", "9bac941af8695cff28fd06e3908c6cce4b0a8b83302dc1cf4a6c346523c7851d"}, +{ "817500", "cd9bec7288443f2289c3e350aa1e2f133d13377ef45051c8ef68f588f0ebfb9b", "a6dcda37fb4542b47d6358e6f4990494b3889031b7d57270d4581c3c5f5c834a", "884493c8c41b3841ea683fd22d126ea1bb45ed0d2e6fdf227938eb91d4a1885f"}, +{ "818000", "db2426a8e3f0260a1385c6514a424c1db30e077cd18f25affc301b857899672c", "1e887aa787c16fd0a14425d7699a20ce4a184468a4e8ddda982637cd60dd684e", "b02eea2ba1695f8d2d9846d2da47b93bc05df3551d9d209a2705d09bab4a26fc"}, +{ "818500", "475ceb331fef75bf43194e6ad78493ee5a3132b1366764166bea3f98214c5e02", "67e95130d865ef6b96c3c3594993525b0ed740d94de1322bdbdee1ca44c52be8", "0f8cd1408b9de9af632f1e58985e0326c300e0eed6df70ff99bb77bdb38b00e5"}, +{ "819000", "8bb061140f8217d2d20fc59542169fd7afa823a911f74040d58b3c86dd366481", "226b79c0b56a187130199fa71bb43f0c0c17986b38be4bc953aae9035b3b137f", "a2db1e16f286b3eeb7efc9e17fc7da990cd35d6d0db72b74794c89658346346f"}, +{ "819500", "9fa10df35922528bf712983310840e630f4293f91e9e81ea9a6f416107b4b385", "23400d8d0d4f2eca02b0a320b012d9c3874250e3703defd32a742ff3a14161f2", "32dd6310b486174a8f3985f5a58cff61919ceb6dc90dde2ee18a01d9435bcf2b"}, +{ "820000", "0b83d657248250c7e9d96015875066e2e5d59b7a0696af84d83b246abf9355ae", "c7575028b8e2df600f1ba0acc5a101952b47e9660a8a912940a2b548172a05f4", "d74ebff85dcacf707b41d180abce396954d0bcac13d87bdddff2611fda3c68a0"}, +{ "820500", "e0176c1631f2909dcccd2e56971085cc4a435398a3a967945666e2d7b3232d1b", "86cbb6afeb7fa1e6ac902b3d28f2aff25971d24b6cff228da7e4c8046b397ad6", "8363434e90dc1c20ee0f5f4b47fd7c0dea0400b93943a51aff7986e173ad861f"}, +{ "821000", "be0584aaa7571f33c631f75d7881d80e2a19f6eaddb91f311547687ab8b6127f", "f8edec8d65127f3eaefc274cfce29f29c4cd339739f2903ec60759367f283f67", "c755a875eb8b6449f2a210cefc2d896fd89a457894a070554e0067c239f0bacc"}, +{ "821500", "fd2e812d81cc2da106beaca8ac8e7ec4ef854416f30d7428c83dc72944e01ed4", "9bccbcaf94c587dafd152fa579fe7bc4e87734d1840e0f939f494d1d60dcd499", "f032fa6b906ab9fa959545de75e6838ab6a908e5913c8bcb5deaaedf7037e5bc"}, +{ "822000", "9054e0ed1b7621397499863a4dfee073b379cbab6d211118e0daba86ec09b239", "0f78238858465e4308062dd44ccca1a81e3b1aa830378d63ba37cf340272f04c", "e315de9a64da20253bed5b374086a7707d049f1e99fbab8e68f1b9d0cf55a648"}, +{ "822500", "c50dafdd9aa14cb0fb01b2d54da426cb862dffeb6369c1ff1f27b86bec6ea28e", "d7d020758a8d3fd93ce7a603dc710b085d16c3c232f389f2518b96b88d903a68", "c5caf8bed22e2c5211f32b833db8b51dbe0e54018c177c883d5cbb25e3ffba53"}, +{ "823000", "6631367fed6a7ca98d2ca58e0ccb8060e9e0309df1bbb5d76ea337c386f3066d", "4ef109d1b5fc3ec978f34d66b8d93cd3ba0b278d7ba9c6ddf4fc3d56039e0fec", "88fe2323f91fc57da58b494933952f12aa11b292953077ee9664b6aa32d7c3f0"}, +{ "823500", "b924862a40ef19454769b776643bafafdf407500c16dd73a70a61ff7d033519c", "dc8d2c04b3dc1785a7a76698674830e8aa8371dcb815083d849851ecb47f1805", "7232bae203573f6c6689058ddb2b4d2b06ac19ddba5caed5a07b08c3912d6ad8"}, +{ "824000", "d9ff8b7426f57da2db3d9f855572b493eba90e61b0ff3b40beec0b46578679cb", "95e502ccf5b34258f239d7a5aa86f16c643e189873979210e0cee9c5acda128d", "cd794aad8626da79dea81ee006ca4c52b94aee1f55ef2912cb2f4807c75a091d"}, +{ "824500", "b668014cbc4e38dbe8870d15c7ece604e8a698dead63136af5954cc403a13921", "d79c1357567cc361a4629f57d3bb01e99929680f5597fb20e976ed9da246d732", "b3a4d6a91d00cd7ecb1890525ca19214242805f0ddd04555b4899008c735337d"}, +{ "825000", "ab26157df7834e458aacbb394f8f6f34fd489cce3c7a1e6251289401acc59062", "73352b8b59b8fdbe1d83e82c2da9ed6282c5788802e2eaf3db7e7647e04d83c6", "219be8d78268674671c9953aff79dc2f3bfac601cd535dc6839ea7dd550b194a"}, +{ "825500", "4447fc4bfa77499510c1f033998de510174732f103eccea27ffe544577472f5b", "f15ba38703c021fa9419af02b8210ad9a9658b8866f70cfd734e282daf996169", "9d3ea35ecad6a8d38b11e387681a7b6f3ec972492c9914e5a75093bc32288bcf"}, +{ "826000", "8b30104ee7551d9d564a9142e2334aade0c93f1fe7846f2d2d21380096a5a1c0", "dafdfa617b0bb3f7980b4df7dd4d0159144b7973976db5e60a28308c0e9a2216", "ada7a2c9ec028cbe84830bbbd0e4b0d4b503bd78b0567dc69a6e74e91ce59ac4"}, +{ "826500", "0e2e09768e2c0cf1f39eaab0b5182b1616b40b9a6d931946bfae09c246bff35e", "417a26d05c6fe49e0800213efe648fc7fa29040f0f16b4e0f3814ac4087fba79", "e6ca3b27dcc0a8d4129a7d458543297a7d3ea8ac12594de75b945fa58210ab60"}, +{ "827000", "9539816f7acbfb9151d30dbd91509b104a83bc0564050ab5f3c3a180d1659bbd", "b8d3ddccffd24ee4f56c161acf6a739668f48a10fc703233bae30108e8b23f04", "46961bf809626452945dc9b458e398e7df465214a7638f9b4fcb5acd54371a3b"}, +{ "827500", "735c35ab86f85b3d7c430b126cda4a4c8e55479a414be9b344ef0749bb2381dd", "526c10694250f563eb1f7e7be275d89c14893a95118bb5caa0fa3757d2f1b08c", "63113fad7d2e86757c9a30c110290e27b0eb3a34ae94c3c19bc98c65dbc9fbf6"}, +{ "828000", "846213c0f91cc5f47286bda5e74a48dc86d91bed3d5549f2130211dff2210540", "195e0a72d1b5934d7b37d8678c6ee6da4713fcfad761e397921573f0c727dcae", "31feb7525f87c51d0efa33adc2c7846e4086f9a5fb0d8a49e90356e9b7104493"}, +{ "828500", "033da5a6c02d67fd91df3e6d357de891ba0a8352546be1e4c3c47d6d7a0b8916", "3d55e3405532f51149ebf67cc1367c225ffcbe2832a37814c37dbbb324fe8c6d", "de49ee4299d76badb800b1df4df0506a30022a79d5090130584c9d2e1d842537"}, +{ "829000", "b64d6b04a7eeb8513608c60f52b3a54a2758808beecc359cf23e5a1c9991e1eb", "ccd618e28a3217ca7d14e462c4d2df34473438c0e89e68a498b9d236507003bd", "2f667922d18d9fab532b941589fb89f5ecbe9d182edb79e09fade2d3eb4dcf9f"}, +{ "829500", "31cc80619db75aad85974e5c52755375dba0dc8ce67a17e6e6e4cb29f60dad24", "41145f9a5566c0d919937386229a00f302067d3d0dfdc369d866f164c4edce40", "4a6178bcfc9fb6e5c545de1980f1ef89dcd83c4676a4201fe92e5f797c35894b"}, +{ "830000", "ba6ae9853c6f5efc64e12f9982df9f199587f43ac41c49c56c52a217c42d31fa", "db3584bd7127b287f20a097fefea21aafe602b6d36287248e5b878d8f59a55c0", "77361e13d129c986a762f3d37e7d02b47c84fb06774199ea9bb2f2d059e537ff"}, +{ "830500", "881ba4b6afba166f55baadba4ff7b98076398db48b53f05058e4fcef5931803b", "f2d61ffdc8eb96d572eeb829ebe227489c2748aabb4e7ae8dd2d4ff04db6135a", "a727d25ce975a1c188e4e15c2a460023893f985bbd65b4a1b65e0da3840dced0"}, +{ "831000", "a49b5343b0e4fa384c6cdd8a9b79713ddefccf1cf1b9a9b8340a55ec56330684", "d5d6f8ddaa5631cc30932ced1cd5151825bedbff4f7c454fcbccc0dedd8822c4", "b401a21a7c7d52316b22552a82facaf78ad6204f97b6f53b0595ec94394b48a9"}, +{ "831500", "2325e3f54a404e7bc60ccd0acd9ea77d90a31b18f8368ba2797d9a2f7388b482", "09565fb72aad572d7b2fbbf1b0662da7687c7d98db22f55063d753d0e59a9663", "4d8438c7be30e5e62e2283d0594256eef9bc8d91fb71d44ff3f8a9e8249f4253"}, +{ "832000", "79353ddf61d1fd1c8930b19c8e2abf92382f86b7ec5d3de61a766952b465144d", "2cfcfc5a17e8042417128b3e60f6c2f4acb4f980508c3d172e0530ef1322f55e", "c10e27c97f5093fe783e94e9bcb09110d32e61701c35c010799876e5e612a79f"}, +{ "832500", "15c4c20b6d16377134e683d2eb7d561d4276a32d61f2179b1ec4f6461ec4954b", "8d2364c10cb39a2c74360fda5585ead678c0325656ee7e2803383cf5c9e94862", "6ddc31d223921892ca90b4a5eebacfd6ba6fb38d67e71fd4383846b7240fbd9a"}, +{ "833000", "771fb7f8e60a4065f3977ce3397d58a58102e11111312bb8d61399be0774809a", "bb06d1ca6e8e92d34fa9f31c9e3332ee8b3b31e0a4bc3a1deacc6a9e0a24079b", "94888abe56fe36b87c7952bd271966e42012a8cfd289bf8aee2c9ac3c7f58d60"}, +{ "833500", "b9d939f1ccd4ee8a2b769a4b014dd932f2d51d765eb4a4cb45844e726ba26f7e", "77a9c4bdc03d8413b3600eece8b0593804b58afc41204063c3ab92b4c70d2478", "623f0e27437ad34d1003504cfaa0aca7236fd53edcbd8edd8e2b9fe13d695858"}, +{ "834000", "c7bf6a274ef1f46d5faec1bb73cea0d5873fd15340b0ed103b0551213bd0b168", "89deddbe651ce60767e84fcaf8419a7146cd8128f439436cd9c5edeea0c0262b", "d183306424b5963fedd2f7ede8e4e39d68b1a092957e84f8b32341afa963f611"}, +{ "834500", "614d3beaadffc9dd3765a68108e9f2e01c33a9c440438163970be6883f71b68f", "b8cc0eca95d7f827ab45bcba1eb5640f883f803c6635d09eefae1ab30558872a", "79dcd4eecd52ba310114e3df54e355e44b7a8142d9c5e7c32322605094d98374"}, +{ "835000", "9a9f3c4367e50c24b3210a0650dbcab4ca0762018f41110fd7d45e70a0270e7e", "d827e1af0280be63e64f467a81e39404d3798234593ed89f03619354cd4dd7a5", "7f307a633d01ead46c855a3ff23037de616aec636a15a68b005db4017c33d3cf"}, +{ "835500", "cbbc70202da7cdb4cde6059eda7529609c9781e534661c44a1f61e5fab4de31f", "9640b254c6bf22f95f94b10ee1263d475d76ec7ffc8d8813c2a7f73a7ca77a28", "dc221fc429853e9b64beac869a705396dbd079a96505aaed00e8fb9737c861d3"}, +{ "836000", "63d55fcaa4b84b7278dc98564a5955756f3ecf915b231cd6f2399ec836537a34", "be4ab8603457a5c080f6d4f451702426b19f87ade3869565c41aa9aa1cdb6b16", "81751c92dfb6cdc8fcb076788e7e070e8fe3e8b1253c9adffc10591220caa988"}, +{ "836500", "a0a1ad507cecde4069df4dcd3ff6b0e44b917e732cded5fb86d50acbae0009eb", "09c9ddd16cdd8ee68faa85a59b8547b9d07b19ef08ad42fc9d98f9d85ae7f54a", "45869cc5a27d1e5a0a20e4bccfafdd547509b7006a3179083e6f4d9d4fb72137"}, +{ "837000", "4236b2466078279f38a8df0df56bbdf71da7a184f750d439aae1b7b9b6a0e217", "1b7b95d0f01cc0dda255ea389572d8d66be622054e9913e6471347d83070da7f", "393991d1568d9894d8fc66b4d9be11f0b213fd3ad618bf1b9e2ee7045aee3f0b"}, +{ "837500", "975034c8d678099a6afeff9e8e37d1ee524f64a851ce07def65676c0ee189b4b", "2dbd86bbab192ae7e44609388bd9036e20d6496962b2ced1b23eb764d4eeb3b4", "c9a9e2e0176e36cfe676ba951e29afe717f905cf2e1932f16044fcace1c580a6"}, +{ "838000", "05228288f4e87f9283efa2e6547316fb61f8a6c9a1c4b3dd1b919d02c4beff88", "8bb8421d901f05fcb5b476b8d5aa66f4c380fb7b00f65833f6b0bdd6ca93f62e", "155861e19f5454556292463548962fd95d701ff0dea9aa2506afd3658815bc16"}, +{ "838500", "f165d6b92e8b15b8a276e7aa3682e61c44e6729a39111e1883cc8bcc78cf9b30", "55e669d31736fed4be07280a142594c8f283e7a427f0630f9ee7f0b06411b948", "7508837234344d9bd77efb2a47a09a2d4bb841a2abad90d37bfef179e8ae5605"}, +{ "839000", "e7b73701d281fab70e7279cc3406b961db9c7d89643139882ccc269515bfb8ce", "44e7b9087a0f031995a963ba2c3d4d59a2856ddf3e822d0944fa472768990ddf", "991dc1f6c6e7905e56fe721e467392c0a227f108b003ade2e13875145cc5c99a"}, +{ "839500", "a0e9976acd9fc6b93cedeaac38938156409b74d9192f1eb4d614d4af4072d67d", "774aeb086be488987a9ff3d9d80fe11d7815c1061754431fe3ec2ff387a4e2bd", "a66402d20b190cf54e62c6bf3917bf66bffca9d599911d6ff6ea4ae619ddfb87"}, +{ "840000", "85f4bef924671af404c377269d655812da734608007a1e43c7e2c974ff1a7f26", "a7c27c2f0b37677d61314ca1a510aef72e2a7149c0dfb3e314c47ff151a7589f", "298d9f5856f8db53b74c14c701b7a0947ba6f92a6e3c809a9d722cc84d778c38"}, +{ "840500", "9a3f8a90c257352934919ba5678d710e02abeb3f8c9b609f00827147d2f7cf81", "c9234118875f5ff26dd4c37d0f498911d1caba96dee4d33a50c7ce378a9a0749", "4a21e3ff00fabeb73bb38c41c1e1b97d25d59aa61a1a3dc248538016a482052c"}, +{ "841000", "51b45385204a2bec9cfb32ccd8677bb9fce49c7c5fcb6a53c452e9b36cdb0bde", "07ed169f164ef448a9a828d17a6c3455f3a11dd6c2bda1eb38a5100b8817e04c", "c512255a21d35ac5102e25983c4756960a5f6afd0eb8d7672eb8ec8321f61d4f"}, +{ "841500", "92f53759b018613ada40999270e66657ae1026e4997862ed0d5e5560b917d6d2", "37b8239afbb1d59bb35fd5696404860f47dd31163981e62738867af4d1d13c85", "96805068c6193df48a0eee37b2e41bdd0a3c73c7002a2369636c46adf59acb8e"}, +{ "842000", "a1202ffaaa1bef1c9c95e11f9b2f1e1b03e69f535628130df12635ed9a3fc297", "ff3835e7e4cb8e4514adddc8fdcce0466170f3062e57d9abd9599da0fd0ae1dc", "c076ccb715442fe2b85dc94cb8ddb79fdacf597b37ddc0974fef209a475b9dca"}, +{ "842500", "fcaf836bba0923b8d887f619a0ecd298a94f04a1127f82773a531d8951326582", "7fd60c91ddf7611c5d0200f3f5adffda13a651c5bc71929b0724a3ef0c178463", "1be228c7e806ebb9f4357ee1690da16982a8853629d04962a97ffa08bbddd6fd"}, +{ "843000", "37827f08056c92edc0a941127d96f9f4f481d70cf2cb6c8c0212bbca042ea04d", "863b61ceff5d6d3314fb420c17bb16c00b220833a634f53d24f7fb6c9ec7f7eb", "3eb3471a68af99385a084fb558401e63c7a952432a6f61d2cbeba43a26c9ea2d"}, +{ "843500", "5dae3f790ecdfda5bd46aa1005cdf1170b25daa976dfe3f83f07cddd47747f86", "3d352565915c9634066580e57621f6682cc147cc92fa1e7f0112af699a2a09fe", "9d565afa1bf4f9747dffe38abc72517e189be7af526058405d9e9d6178a1143f"}, +{ "844000", "b3b067a2be410c5b04cbc3088bcff2678204f31c734440fa5ce28a43e61f6e20", "dd379efdd80ed38f855dc2fed11db6947ffecca2c6d78c3b13d9e42de618eb95", "7d01e39a64e1171e37a6affb926a6b6ba95e7f804955d81093191f7657e7e40b"}, +{ "844500", "d8ec90a7f602aa58fe31112ed0917f4597352ffbfb186524253bd4a88a283efe", "b8684b9b13ead86b6620d8c6cb1b4e3ae9891ad53c74a5ed93bb547b05d1a8df", "1deee7cde09be77c018bcd36d69dee4048b1cf551c42c7168a39e9abe55e1111"}, +{ "845000", "66ca29da4d604a893f7a56ebd96f365b3853ac2de6b38b71db898ed7226fb49c", "2a671d1a790cf390618793e3a9e2995de070c431014e9b1c88c9c587cc12708a", "134177e23c5e52aea8025b0ceefbff4b19361eb4849473c43fb843f1990814ca"}, +{ "845500", "b735fe850f31101901fe04a4207e15ccae72039895ae0f149593dee3e6cf8a47", "fde7269beb8e5c3ea60f2b30d1d43ed52319787b1d9363aa67c53e6beb187d6d", "fea541f995264a4123a2c94178a42c2804ce048e48364373b14872eb4ab89a74"}, +{ "846000", "b526a9a73f37f20c6ae046ec9b131f6354e90a4596cec60cce1414285c838df4", "fd42d265ac2d194a94732500fcdaa7f4f2e629793fb220a871459880c0cd000f", "bca8382ad9026274cc09e2f3d0e8c6fc2ee05aec78774aaed3ead6d88715a072"}, +{ "846500", "761bbfd7f554b81cd153149a73641b567685b60914402dba0ee171d8dd0237e1", "2d9ea683992b346008f860b330b15ba6ea707338daba431103b2a444542f9870", "6cf67a4ff5492aa8c4700e89f9df215d90cf9898565a5ef0de702c35bfb96595"}, +{ "847000", "375dd44f3bb80150df686ae8f3813999d60507c6e9ac4750686b5d182adcec3d", "e4ad131095150cdc0a23d0d7948bf3c870e01ed0b4a6f9950457ecfbb254b342", "bd3c6fdc759d432bad20314c703d555d9e56388c7c77277de4a8b2c40cf2f4f8"}, +{ "847500", "0539f76c06c311da93887c10f65904de31c72a00a2c0ee1bc66a46c50433c0b7", "2ce4000e6e36145f7c0711f53a8b20144a69599490a7da79726938926685c5dd", "1fa52cb8ef3c0fb707e5f3ebeeb99d8e25adedc2eeef565b82b109fa6cfe198f"}, +{ "848000", "c6e8ae1f92209bde14bb652bc8478d5592d0f6741c3d2f2f232c037494d81f70", "b7c0aedb71b645f0501319a9842e1fac4873184f50a0c5b758fd9f2cc2547a1e", "69295041487a60c8f00f631c3e56114c9b348f5dc7ee790fc819631e55fffa0d"}, +{ "848500", "d302c73e4d2ce3e318afb5cc773b089956501f00f64de08073bde92b2f3a99f3", "0a8901df9a3d00b66ed1bd0b117645237b61fd34c63fc45a0604daf2ac932bea", "4b93992d98ad1fd9b9557cdc1568803133e96fb9dd51878d5e6958a170a02867"}, +{ "849000", "0ad8844c1a45d6846464c00e9c6853719f80056b6f0fb70821536a133432ba1b", "6478dd9c136dd28bbc4a49eacb7909c179abfef94618dc6da67adb4ffe69c6dd", "bc7dcc71f8572ab902c0c42773f396d327657951178a1e3376556a12c8be2391"}, +{ "849500", "8ddd724ab7ab24e5ce2f5355c2c4bea780fe7a2b4a01fd04d6a0be5bbcf6059f", "54da6435a5de096881e00dc1907cb0b66274ab5b976fe6b67ccdb70761fdfd44", "f71d51e6094c79459ca8b568389c91d23560f0daf00a023a460315511c97b09a"}, +{ "850000", "b5e0c35c2d33ac37932b6d187a8839f1bf846817dbf5f4c58b73418e9a93941e", "e9f2c9230ca20ec14c17a35fa24d9eecf9119c5a38809c420ef099d9cd4ac61c", "58c376de138829f5c2cdc42a78ed1936686cbb0cebcaa4f0c2ae8bf8d9e6f4fc"}, +{ "850500", "7c1ea7bb106ee4a55d64930589f44b2e9fe63ab9846eb3caa545fd3b5597ac0b", "9b2b304003bc1746f27de0d9a7cadc9dca7d6c87b6cd5c88da09f45282298480", "4adb35a77d7e23f431c34032f15421dc3a75e86bb025ff7a470eeacc0feeaaa3"}, +{ "851000", "78c3131d573b6a70a648b111fa904b99707c622bc56f842297953968e50bb804", "9dcd68f3d2c985c324ae53f03582ffce484a70724e2c13602f84099737641cd8", "b7e3f52bca1ede78075f9934b0bc416ab5b99ebc2dc32ce3007f9857131a1bdc"}, +{ "851500", "e470491ea5d0631653c6200effed322f6696614bd98109f9f1c90c2cfc72f211", "5dfdf81aae36a8b8aada229a8ddfba138552fb9e101f4faa56bc76d3860e7738", "10d9d0567062f9ffa7f8d8293d719b47be1f49a174847de61f3796bd16b0fb58"}, +{ "852000", "528590bfc01e4b7f567aa786f0de29c2b7aeb8dc3042114b087f761a5e6b161c", "a96175b5107c4129f6512d54adc38ebe2f236ed6c3f362f885cd4a96c6651e0d", "83cdc7cb8e37b75127d148dc8092f8b6152102360a23721c3fe45315865e0227"}, +{ "852500", "a286a106373a8e32cbc0b3df7ac65b0720c04cae34a07cf070bbf652474d8c56", "205a7977e413da822705095027abd2edbe7c5e34c9afb7225721dd18b700454c", "822fde522643b4f3382d6fb35048125d73a72555d4275f9df3feaa09a17844a4"}, +{ "853000", "a2d7a0b916cf5aff1d6cd5150b034448c58dbd104c5f88e9b18a692d4a8e98e3", "d91fce318de2b273cbff6891c8ab29c769d7dd2f09b302937493a38488ce1446", "3ac1da42ee057e0a2d6712c7fb4aab7f35a64381133426ce3e0b7c72694171a0"}, +{ "853500", "794d93de5f3d5c39ad05ee77658de33f094880b037da8d2c124f4257f7360164", "3f94598f08e53b436df3517458172624b710f4f9c108c463a39b2b816e511a0b", "be9a507170b144c094e21997367d47daf719134fd5b6234c26dc978ce6332fcf"}, +{ "854000", "886b8b0cae2d1c914ab6748d636d5553dde505c655102ccb384a5c9a2b864516", "308dae1dc6e58335096c15c90fc276e9cfc6639289c25a9a748ebe226f37604d", "3e10bac885ae26b5dce2fd259a9fe6e9ac91cfa46c247c53274050428b72d668"}, +{ "854500", "78d0ac66bbe4ed7830eb9025fb934514035d9440e2dfa75d4046410185235755", "e2976153d1e9c4253528b84741fbf9d8bc73e85089d63a59b29d5c847e336c02", "18ef920835702377682de6772a5b57be2c8ed8ace449d334d05a30b6c1b34113"}, +{ "855000", "be6a06e20a33be8f7e0c96318ffc3ad202215dcc9124c06ec678a6a775c8f67c", "4ce675eafc85e0f8d54f8281fecef780e98677534b3dbc3b1e9e7f7a529aa3dc", "67b323bdea8d1b397006d4caab0c950deb258ba35738eea3a737eb114acebc63"}, +{ "855500", "ac409e08616a1e06ddc3e14a2b1f6bd947840932fc6e8b007246de280a6b66bc", "ebb67251598e38254f9327ff1dc2336da5269cfc209a5476260da523cdfee0ab", "712ae779bde3503952ef75ef1d4a580acc03e12af09a5250ca52322c94da1aff"}, +{ "856000", "62a624ad49bb1908d25d7190f363019b1cb5f1a1dfb849bb50226561b3c60218", "ba4fef7924ee2e26f271a49319726894894497685b1c81ea84e0bb62246c24c5", "42670350f297560ecef23e4c5bf42c3bb72378c57f46ce6a8817c065b2ebb7b7"}, +{ "856500", "f02dd187e61db50768a596177bf62878130d15910ced1f4bed2d5aaebcf4960e", "8e9e38e2a88d1a24151ea08cd82c2debc7034d5fa21e75f926d9a6c0df18d6ab", "1895c5403923890bed2d912fcf2b6b7cebf2e23ecb8cbee27a27fd918633138e"}, +{ "857000", "b2ea7f0e6a51ea74155d6964d732dcc4fc8a0b71c4e6837d1f17030d026da89c", "8ceccd983eb05888198163e6a0ea44261e44876289a9effdcf3d377ccf62ef67", "4d2efb8494121ef8f03f7fb1d43c56d67205715eb81f5424a52d07e0d6810b12"}, +{ "857500", "f99e644cfa949f806ea938b97d5232d9430ca11a51ecb0ed30ded90e6d4f120d", "fd26d9ef2f463304bb2839e8bdb3b5b0f48592e2cdfd043ad809292e22391623", "793a973ea0030005c216afb7c2b40fd42f6fc269de9ccde2f7cd578f4dd1c4df"}, +{ "858000", "9dfed199b5f19ad984111f21fdaad2d5d1779a317ba5982a93e14e37e21a2eb0", "3da6db23d0fbcdc02c440eb755828b4a5c02fe77c75b153055eb25362399216d", "8d6e1cef06e63fabe0db295579b2312868d74053e4197860ca17a57a28711de3"}, +{ "858500", "daf47ce2ce33b9db10011f6bd963bca3abe9b8b27e6101394d5516555e8e7bc2", "4fecbb4ea28d764bd3dfdcb6571a7c6400c76c1e7f21a1c1407d057fbc6feb62", "b8ef93c05f197b5e555999918188a148b5d2234b4560663895070dfddd73866a"}, +{ "859000", "f6cbc9c86ebcd2832f2d0db57e47b611d187189a37f33f7588c7c24e2f2174fe", "e85af2f0bf8bae60e417cc65de17bcdac486348b40eb55da41a51e98b5c148e9", "d8c4da4448c5bc5dee35365b15d3352e4a66820c2e676ebbaeefbb5aeb621603"}, +{ "859500", "11102fd852576a361c4c9a3050eb8d605f317f82ee78200d2a2820d8a3ff76ae", "e70ce2ca1c2e9b818d276254f46f0d6156003a8421ffa99fa8499a09a982e1dc", "a30631a2a3c6f5532794a4ef7104b9d087131eb039c83ae4eb24ffb2550f17a3"}, +{ "860000", "b0689ff799ad43c8123c38f815e8a5dfcb4fa2b2cc1d59dd08f6d6e6f260ccbe", "60815a438a372d41ec3439f8b21cd8cbea71b090758260b1920dfdba4558f235", "21801f9d92c87f0cdec4e499059b503970e4c47669d8c398ac549c4f8889ed3e"}, +{ "860500", "6298a42b99734a2702bcc358dcf100321fca31a1cc547ef0c168fa83a50eb132", "2881b992eca478a15c1d505d3b021e2f589d536832e98cbb90831b4d0daff767", "65794277c6392e331fa20b893332ac9d755d33ababcef60bf3e1b4d97654294d"}, +{ "861000", "9f8f6446a6df4ac6674a0639bc616fbf8955fbd7c5a6ae8743ae009340acc6cd", "b9c2b8a675ec2a9f1323f5391a81d5a2bcb83ff02fbfb94e1960eebb50033bfc", "fb2d4ff73be7986b8df82094c1e8ab7b52e1697d4e259bc2fac8b91c790b3272"}, +{ "861500", "c53640e61534d7de4001cc4f6547133d225ebaf607937c6ea99b3a92e0f1b445", "7befef633b3eb72ac1897e3628b20540cb0cb51bc447fd69877d178705b165b7", "44cc2aae200ec72ac2b1741928330621ece7a7a0c3b5aaf58da2830f552225ed"}, +{ "862000", "1bb40c878bbe264e2fad6a6e523345390091bef9bf689f6860bd30fbd27ccece", "66bf4703cd800c13edc3e67d0889df0c4694e2f6545c5f71bb0d43d80adaaaf3", "14612a0dd18d1a9ddb64a1d068fd9c8027fdc9f86b6870cf7c0972ebb8048e72"}, +{ "862500", "464bf61e9afcf7f9418661d069ebb015bed143a3c53449e9ca98013c624c0d01", "b858f8d0afefa1f199f3434b656587228c659429a9b29876139cbcde4a66d36a", "42e9d60328738e7dc1a7ec7eb51fcfdd37ac65c504319aef0011ed50cd8dafcf"}, +{ "863000", "0dee780a99a58bfd60c05f95db7ecf49c8ca8380b7a5b8ccb4c7c26229966441", "4555335383dd8dc416b36cfdd110d6da87faee63fd0461dbacdb6cf9dc61fd1e", "58a77e6126ee627594569bc946a69928b328440f27c717558c89f0b14d97c9d2"}, +{ "863500", "98a57cc44810adfffccb2f42f93455e1124e3297a8dd4e176b6367bcf864fa6c", "b16bc478ec16263bc8995541eeb0cfc6640074c65853989f7619f1094b48f17e", "2bb84dd8577f675c40d2f79fc20f4c854b67a3e5d7f4226dc80e5923e48ba22a"}, +{ "864000", "516c8212c055b610d7295dd1dd14e797a2b4ac025f1fd2aa7b3d26488f260a60", "e221eacebb459d180c743666d691c11997995f6f4d75dd21613b75eed2be2425", "28fca9cdbee34e8df75cbdc4f32f1a64a83042e01dcc24f547ec69fe18157184"}, +{ "864500", "2e8ffca67b4cf71272e42d524e1427b794a8e663b437c156cce8f9ad39d28b58", "7237d3868b25d2fb9801de887b7c2071cf24952719c6170a6e550773a61a2170", "fb67497e89323233970c4a98b94be927dde692d743cd0faa9d3134e551cb9047"}, +{ "865000", "995bc313381ad5d7799cccbcfbc18876582f5a82e25dc4a6bfd299facb83adba", "3ea758c944b2f0be32fa7fb541e18f683734df6197ba711285bedad4f17d1c8f", "9f8e354ed83d6c246d802b0ce027d31fa350fe285e736924058b5009f1259d53"}, +{ "865500", "dc2fb63083a52596b814426dc2577b6eca27f5e80b08b83776c93adb0b913324", "007ae746a4a5b901f91e51014eefab59c84dbec3a3e784711d1a16df0aa04ac5", "404254a5047229551d03464a1d5b86887e1c0a72de0e981d02865b83c5e9646b"}, +{ "866000", "a1a4a61f9e30b4ac585c2777dcb066e543a3ff03ddc20b67aadb9fe8842080b8", "953ff29441259817927e36e3a89db69fafe11d253509c36a2bd00805563ec4a5", "94aa4289d06e9f12e46423e7286d041a63cda7fbea30695a6d8d8624e277794c"}, +{ "866500", "44fff17033fa5e2f48afd1313484e62ecb1bfaeaa0b19b1973514abe18381d2a", "1bee0d01001a576776d0e6113954449de228bd3f69feea67a11769f2626176cb", "a53e44164326bad1e2bab2c9187473d43d8fc1fe9e44263fc19e2ec3a0066d2b"}, +{ "867000", "77d6f737b4c7b493657ef08c7f28b5dc43e3a7194b2e3193a37d1a931daca9a9", "a9f847fa150f5881ffade66584ad6b5a741f8dcf9310eb808181c9c3e4724a8b", "21232a978d4964960887fa86460c27ee153c25601fb63ee11502dd105da94c88"}, +{ "867500", "98da2413dbd1bf3e2d3d6254f849e3a971ff9579e78a4bb1ba192f61a1ca1bf7", "55a4bc913aa643d798a0d9d29b5c31bd38db0051ccedef30bf4bfb2ae6210159", "174d2ff6dbfc46694e7fc438a37fcfe18f98a2f946b9d2eaf337c77f1dd6a058"}, +{ "868000", "1e33271126faa909e8b77bfe4431587ac68d50716e3ddee70f18f4ba56509c98", "6b3ceb03adfc3ed05acb7ca6a2c9822e0b183c1359826f2714d26fedcc8b779a", "a79c5253e761b325c53e7383becf3000e36b15268ea637514b84037da39ac78f"}, +{ "868500", "b4bc5ab2d0f52588e8e154a831e92f9bb249bb30c4b6a4e379d529d9c916508f", "e1810b871f581727fa81164f7ba37242a0376aa7870f897547fa032efef248a1", "61da85844a76502eb61d1b647470c06e0a7d1a9005b95eadec03bd2d16aa4e1c"}, +{ "869000", "9db0fa91a26eb2c05272e50cfff46c7c9faa4d72938f14f03736c7084c4b2d20", "e80a050a8dfd6c5d2ecf765f43222b8aec1a85232641c32583487753ab3107ae", "d2dd26abe610889bd4d2ac990a3f97030fc4acb66f63ccb3f4733d545820f510"}, +{ "869500", "ca4ed5b1069fe42bcf42af8fb065aaa98db119b2e98c23c8ee9dc823c46a0bc1", "1f45046c69978e3a13a013d995a469a2a6583b18cabe3e48c5735a1bbe88f1f0", "6adcfb05cd935fef4d4a76a7e0b6a0eff99ae5071f610ef7ade477cefd2a48d9"}, +{ "870000", "02da00fc2fa6bfb0027e8c85a1b92e919495b84e763dd57afe758df11635956c", "8ff1ef73ea14756b421192b3f936ed06cc5a8f016c33a4bb8c3eb94a0a4afb6b", "b8a590ef2388d946e9d71c758838b56227a4abc719cedfa19edc8eed9f6571e6"}, +{ "870500", "04cc97d0004ba00a8211986f0fa13bad1cb0e7cd17e302242128ba5bc923bbeb", "d4dce041cd8b2c51cfb7a50864de5d72a627a93ea5f5cc4d837004e9fac80691", "35cc8956a844e114e3f3d133a48e322bf2f8eb5b5d7b1d2a0e0a430f46546e90"}, +{ "871000", "8c46f91d61fa06dc47ef2715dd66a510f1eb909b275c85c0f8f914e8ef0e2ce8", "a04657d974398377996f4584c23bf29a55085fd914b88fcc85bcfdee46c1f4cf", "91bc499bb802787f73201fd4b19428be38b9ee7cda22e9c3a1f2c637cc8784e0"}, +{ "871500", "285a13a25bf27fd974c9bd32ffda2796ba46e57044b4c282331cdf94ad55ce0a", "c701e8a240d4dce38b98c91b01c0b306ea6c8e72c345a2fcec704f4af6f880a9", "a58593d021c87cb3647bf70d501386a4af2b66812b8dd83c6c21cfedb42002e9"}, +{ "872000", "0f474790eec84e0216b27a41df528a1037767792657a3aa79122dc31caf1e1bb", "0774199988a33ae42d91de34cf2c1450aabd65b62e4792acdd67ee92c9d617fe", "25203763e4455c575a0871bf241d8b8d40fcb5ee4299262c68bc7bcaa36d3165"}, +{ "872500", "4192751ee0a2c7b7bebe5e6a7c60dfb98f1527eb6dab97071b5ea89fb851215c", "9e36875819fc969d8b5f971bce6d1610be7a012a520b317ce574c1e24f26c0dc", "f39c114d1ca78036f445336b7b671ec4c6dc52d4460b339bba60711c75bc3f25"}, +{ "873000", "34692e36b62fdc785dd9468d43a0a637aae66ea75c592d5c92e3b79245efe449", "e97152bec752a6cda91c4153cf191e6a04135a2d824a6ef8ce6d64f640a97fab", "0ca6b7dff238551d4fb8495eb9cc85c22be5098f65245cf2da2ddfd4d4731eff"}, +{ "873500", "af2ef369df933f912140c7a4ba01d3e33ae803b7b2f4939f8a98405fa4127b90", "3e30270cf39cf279ffcf99ad4b0cd55c85872bbf82654d03f6a9a40867ceaead", "ac2375ca321b3bf357d1bfcdb51faf0664c89660abb3bdfe5e63eef55c14202a"}, +{ "874000", "7f1cd90d997b5a1da4daac3691082770bc7bad48acca998746980f0b57ccf21c", "d7cba24bf85848378fbc0f655a1795b9baea22b97a29b3bb1b74fcbdc25baec1", "2e4b750cd6433607f340cb88227e3d9dea81ad791931f096c1f57a9ba4199adc"}, +{ "874500", "c15fe484c8c031d1327d24f1b563bae0c6ceb1f81b8c0b37c1a3a6d3ea9c12a4", "77f11329dff67de4d40f655a73c71a76e4637b274af5ecadd6f8f2ce7e265d7d", "246acefff1f0368ed146b59c7ae6e3c74ff4e2c0e99c996942fa9b109f5ca498"}, +{ "875000", "6d606825c8c4902999704cd9839f60f072743c33ef3cc8fe5b075e15ad6f521d", "0f98e7eb858a741ea9b7f9260142cd07d98f3ef2fd0f5897f0dd1196506f28af", "b1c7dd3bc7112815fd1d6f4c8762dbcab3e87cab642dda4c9447a037d7fadc53"}, +{ "875500", "8102b25248d5cc9fc5e8780fa7782a5f37113d5797ec544bcb6164d922d91ddc", "5331a1c3f2f1e95e9acc0acb83ef4cbe04785dc7a319ce069d252cccaaa748b8", "55555d9c896142ea08db6eb683d05328b1d060bbcb4dc5aec81965a740737360"}, +{ "876000", "2a6d640eb47cbc93033640e4eece162640b36cf256a1cafb406e2c22f0c10fb0", "34f34e19ede327aa5be14240436f18ead4abe6f226c1571429937380247402d4", "ff5805c276bef1199b7adfdc679d716f30cc2aa8dd02c51a9c914f28424d4e1f"}, +{ "876500", "61e5fae25c4f18e92e7adf64242dcbf6507a7ce4f1b0de6f2e614b8f1f5b33c9", "3f421f95de7e2129353ef06a9f9a206639e0f5be018937dd02e4c39907b75702", "0bfe75b21927d526919bbc82a7beb4f77b9d2fadbcb6c5cc4c7aaff6a8d185b8"}, +{ "877000", "46d077012ece5a31c29ba761425e6ef9d42501740db45016c8c5b7da1d216c7d", "d06c5c6aa3c05475f8a8649b9b6134e0c92301d47186f2c379e7b159bab2388b", "4e8df3fbe81f73207daa1c4676347683302341edce0f2f8a1b581b548b0a8183"}, +{ "877500", "610a50c20c1661286355fad8c8d067e794b5ed61c14087d04976cf0f378e37fe", "18141f4f7bed0308bddc68a7b897a035293fa9fdb074b6af3b271c2365a3d1a1", "937748d05622215c2ff5b9c77fea03222d4f84e20d3da7b207d9d592db6c76df"}, +{ "878000", "1742b73fe7c2d014484b21a1604b0a70dc7f12540d52b21ccfdc9f9ea72dc53a", "90831e43dd3912ceefc00d3d544c3f26dbf358ff3b5d24041ba1f322be13d9f2", "5e5d115c0010292669d3bf10702e7fa5942a6031319b29c886819d6edf89d56a"}, +{ "878500", "749fec5fbed9d5446533f22f0aa36c20b63b35116e6005ca519f7fe1ddc76b93", "a13ee98f76ebaece600b0723a6ae7f7ebcabbb86e6beb5c4b9e5cf3e8170dd76", "53c82882fac1f55d23a1cb58b7b975e28038ccc395fbef1c5bb2d540ab011157"}, +{ "879000", "8c578dac00d2b6db2e1972886194a4be70dddbceeb457150cf1b74ff19022532", "627f0854e663c40920d22d252b41ecb60a4bff1de055d1789727ff33eee14455", "798f54759dca2eacf858dc30221ee3dd23cd3afa0e10ddfbc85f808a50690f32"}, +{ "879500", "b31016513fc56e8df0eaa71197462492482734a9dacbb0d85838bf4253b70b30", "854e8e0aca0625eda1261e56697d87244c1e386be8d6aa78f15de8de50a76169", "9e39462f5b988c5cd96dec54db1283f98a0d46cf6c6ac25632309fc9bf32747a"}, +{ "880000", "e0764e8169753f7f532973ad4706e5f6a07e64b7ec10f64240c91f0d319f485c", "4e1ebede695c7ee95e4442814a5d98539df2ba46757b95d8ba4f0e0e437bb535", "65de64495fae8054b2af0ac5c24045fd567d2089526c93176bf4fe641884d9fb"}, +{ "880500", "b72623a454e91149046f522d60935871a1e5f098389d9cad4086119732b5e3f6", "580082c91f04822d21265dcbbf8c3d3a0866171acf5564e982c8386ae5a3a40d", "53038b71554abb4f5d16a454e1c6694f14de3166eca6ba6f61e5603c663760a8"}, +{ "881000", "b94687f79df272c2c5e85e21bff01136c5e99576571bbb8a635353aa9b331c81", "8f383eea1f9a3014c27cc3c0a6196b0764c269a1f2f3effd31f4f6b76d2a33a7", "c0efdd9fe63174d834d1c2a5a40967b61a2e38dee84ea431cf1a0fcfae782ba4"}, +{ "881500", "5ed1eceeaeebe16a0c746f796507f6b0dde6da8c53f4e3502cf5a49f4ecdff18", "901bbb467df17a499475e767cf7886763681deebd4bbb537a4bfc7f3dfb89774", "2b42e9be5adfc9057532a7ec0cadd242e49c8b225d85f41b62e0dae491d43960"}, +{ "882000", "bf12ffa015864c59f04c80d0141643c9de99f79b79c2b26ddf9bc398b9d8bf32", "2b7b77da53ad2a19f61e3aa54ab5833bef79cb88700e51189ce7b1ecf001a2bc", "4286a5d81097b7e676a6884e65333957554da50fb15d8e400aeb5c938af843af"}, +{ "882500", "c8e8deff1d81c65f2b607cde0312982b03523aa76c6562c666c1dddf223e7432", "ee0cfaf5a0a284a4e324c4725bc6ed5499cec94d170baff0b955ad6b2a2eb487", "6fd53db43f079bd26b9bfeedbb5687bad13ff05c05a38dbc1d1f8cea0d7bd37c"}, +{ "883000", "b12011d25c4c08da00b5acef266ab9e451d06c2fe9c65e4f149f7f0bc32b9c44", "9b06de94a84c8e550c49947303d058d4a93d898970d50b8be9cea965ca656575", "030c738f6a0dc2eae18976ff9c86d99d1e3ef4cdb492ad0b2183ffd8473dbece"}, +{ "883500", "77b6c306c2410ce6e03c825d016aafeeaea3daa7172111085ebcc5806dcd3bd9", "01d7719a498afa8051f872a3e8fc32cda3eba0e4151fc16722c0944d8715a6ee", "4a16d0e045c3df58b454e37a884ef89ce882c51c0ef3d3418ec42ed5350353b8"}, +{ "884000", "1fe3f4911ede2f37d7587640a80408092c044904f44900ce1bc41df2e0f887fa", "8e9b706cdcdc53e77915c281b532f0589c649a80fb563bcedfa8fea8493d4a67", "f2552453cdbd0281c8cfe49ce64155a6995f5d3421635e73f8cb82631e92af12"}, +{ "884500", "22d008aa6022144cf5b7070e91a056b437f105ee9ee3d343c2e1eb485afc55e5", "90404898817c93e64a98b4919df62ae8a21e4dcc9bff13fb563a33d544b9a09b", "fe71a783991a7aeaecfaf21841596e948752f868c6c9b8957e9bdded0229b95a"}, +{ "885000", "0d39372bb9bdadcd80ce022e52792bd5097a8235cc9a571cffa92805b0d875b5", "bdf6ea092c4bf488f836f3db4b29361eab0dd0323add526c9448b115f5e269ad", "d1adfdde0b4fa3c041dbbc9a11ffe1f2d6c3b130c6b956395b0c422de8d00bda"}, +{ "885500", "b6c7b44b85b84f3366c87bfa92a3a5d047fdf0fd265d5923726d1edbcd823a0c", "f6d9bbdc568fa107333196bed759d22eb22a2e101d3fe25cdbf88b74272b7d5c", "46e3ab90c37dcebcb162ae85a4d8333fa68f12ed87e6432a66017e149da25bb7"}, +{ "886000", "00109348c7d7187a543a4f45d72c842076614af9f5ee0fe37ffcba6510d429a9", "893946048c4c8954313bab4b7f2ebbbad527fe54993f9055243b83460cfd2fb0", "b2a6503a4c9ae11366d03878d5e8b95894c33ff03a8adf130b31030c188d9ec5"}, +{ "886500", "c50a72846bd8f0fa69fcae71eca2dae0aec9b2582896ff54dd2cc32f1c91519b", "61192422f9fe7ff5aa553363267310c447ead236e9c8798057c3b22f4e32ed8a", "847329db8444ea7159e364ca10364bb63ccf41ce6bf4362f4b7a05b51ecd5fbd"}, +{ "887000", "51902324fddad3458c70670d38df58410ce98950a70fcc4aba475fb2a4c10554", "b4c451e8d6f329db4a0d191970be6d74479b4df4615f1d576589a826cf025fda", "e83d6a0542db0eaf77408e75b749df59425e58f3a8604cf5c617e463319f247a"}, +{ "887500", "576f26ef969d63688e1ea000213b96aedbe715cf97031c64ad19c0e5a0f9332c", "c1ae2f4a3337bb92b30c745971a612af9e911d78bf9503f2d4173d32ea3e2a6f", "2952fe72cd55224af4aa3fec9384721c1014d006f324c559b12a81b51bd785fb"}, +{ "888000", "a67f9a20265eba880a4615aa5ed2e62c51dda0d707b65f45eee03b4fc44f0e1f", "87877dd3894621175bd850a8656bbb101ca98ddac12d54a86af38a08684fb31d", "f3a75bdef56bf863e6d727a4211dc6d5b58c9e4591ef246f29578cf56a236fe5"}, +{ "888500", "ffe36e4c302b226917ba2587b586115115ccb319b79626fb739ab1f4e511f048", "0a3fe9d179cd2bebaf9f4fe064c9c6addb877f12a05090709f2abdd570b36ddc", "0219907577c432170e08eeb909bdf1d39d0deed3f411840f007408549fdc09ed"}, +{ "889000", "3fae8f764be49d5fef337a07943d3419f749eab745c5349faa81aee4aea0a638", "14c98ca1a85488d6878125fa5085d35c8373a461ba7458e3b689a54a13153f84", "340fa29de6407586a958d38626af76b1cd4f00f2bf41099837fd1e8d3bd25809"}, +{ "889500", "49a7936fd2f10c0c1fe2dcd9b65a0938fd4ae50f7c4ac195c6084fa067f76919", "b971aed9ab7b39f4a9d42d50c714443e9be5172b9cdbb055245695c28266ad53", "c99cbf94433fd898d33815bd970d3b96ce1665eb4eacc9dcfd6050ce1d8bc8ec"}, +{ "890000", "761f8aad21a4501b257bc29b52ebff2e27f55b0a465fb5497587ad11212b98b6", "81e6670cbf8594d99c9d24120c2ca70574834637314f6ca75996fa13a2694810", "e0b7cd5afbc69a293c1c554f5f39c2a89f8302169553477476e6d46c2055c5fe"}, +{ "890500", "6f040c12fce7f3e45c6cf2305533ebc2e740c7ed5aa812201372447494772b19", "b79f97bf1e7764c569e5cdd10751ae56de90d41ee4324f9c4b51ee3603852364", "5a3507ecef5219bb37e23c36b581af016bdfae7d3392565f48747aca46deee37"}, +{ "891000", "945ad3b937d8e0e0c8ca33a5da647d1019b9c8e37e0ac4337b66fd3e3a3cd09e", "d02331f0631f106e84bdc9a77e5e4d4ff4f3456286b1eef2962dfcade867522c", "4f06e91bf73d2c1909e6204d14a96761e1f56b728824c7b1ef2cff95a95fdd1e"}, +{ "891500", "118403722d3ba35113e3d5406abc1daa269440550145bcbd0272a84e528da03b", "90f9f71ce4b26c8cce5558f04e9b842f539ef65f16bf55de4d7003d28b5f9c8d", "fda330db9176d659ff4e31d71a14d6feb0267dc30553e8d91b2b48d9dadcc45d"}, +{ "892000", "80769648898afb23defea7a20cf1241f584c76ee5637cfc7a49223cd53d5ad76", "ebdc74487afd6fd4c963f8120e760ee8b8f0f8534cbf85cc28ec67058c642fed", "4ee3c316f5c26a26a9ade27054c6fda8ebd758ea0909d18fee3f5073b20befbf"}, +{ "892500", "887d6de372d68314ba865a6a1bc5a431e2f8df673742bd2fb7e11b439117b0c4", "46a0ffffbd5887f14c94ac1c232f46304cdfd029f1871b1a30b704fd1378b949", "a7d421ab4cf79ddc2b33ebb0a569bca25d8cf0eaa7b390e6946ceb3a945facfa"}, +{ "893000", "8b0bacc43bfc87581959a67dabb72df9fe52ff891daeffbac58b0581403a46e5", "5c472f2d80c437716aee3cbc3439ce0b4e256363248a93b5d1adbee71d77690e", "6792f9bcae3ec53b7fed0d070ec6fadeddfb929eb4746f0b56c6eb5df9509d83"}, +{ "893500", "961d3fa31e522bbdf6cea3742ce5b8646b3fca603fd44daa57f5c10f830e4071", "49e19baf811717ab81e294b95c8eeeb5d96fdd1a4cb26fda305046aeb5041207", "0b7645e62baaf6467b665125ed34bf47a6877b6a1ea16dae2fdfe1f1e10e7003"}, +{ "894000", "cd17ae71de5a09dfa983f6dfcb13fcfa6d6f242080ecf3be722c72f6bd7d402b", "9a26285e49feb36f6ae744bf0e89cc91a3b871339cfe538b8beeaf5ebbf54fd6", "76f30d6a2811ceb8c7788e7bd3b375e86688d749c1229dd7e85e233e73534302"}, +{ "894500", "25fa66f74866b3b730f3fbb2a9f92d3c705354e71f2efb2747f8ffe1427f494e", "a37b7358d87c473235c3731bb985bc698bf95f6cff9a5d3e225e4d1ba1c668e5", "875d3c2e15ee2757c420b7d38e239c0c0a1113a7c94299cb08f4b44ce0e27ba5"}, +{ "895000", "50b47a9ba28ab1c5131ec35372be0690b9ff7c5967a81f7d6d7d5d7bab8c34e8", "c6d808c63cdcdc412b9318270655cb0d37c315957dff5039d0b018ede34113fb", "d789857674b0158469cce78c39349de4dc4ff43914a8833b690a1c326f44f72b"}, +{ "895500", "944784b12fdca39238803ecceb354bc4e8e5d91d4279ec25792820866d5c3e5d", "21129c892476213ae6df19646a942694518db3758cd2916e38b4afe436d0be2c", "9798a519310c9f896214a005d9a400e58a2c47b099428177d986440c7368b223"}, +{ "896000", "8b45a6293b573820f4b798c57a2144f7d94bd2edd02118d44cc0c59d4c92a5ab", "de0a319d296d3e88d7bcc46a4cfcf93ec469305122840f5512114776011cc03f", "92dcff354a50898f923f899fc1fd3f44ea41957679fadd7456075e25193ae39b"}, +{ "896500", "c3303636f08723508f17d63f0d376e9819e7c537d96e7ddf5bacc5cf02455287", "36654846452e690e6b833d5fc2d4b6d402c5fe81754332d35162ea65b1ead7c2", "e0798392bf6afce7c1ef3ec91cf696b570d12651d25c7c8185c5104760ae09a0"}, +{ "897000", "6cf1a830afc57e6d8549c8197e90839f477113278db181bba75a3ccb3cd0718c", "387883d5fdf2362515430c50fb20dbbb0ef24c387c3b6fd4f21be58102f4f20f", "c14e890bf64e617106ca77768787a7d29ef1d18e254b29217982d432452d569b"}, +{ "897500", "323544c069e43993ba59d272db7d92d8857855f67cecfb03afb9fc6495aaeb98", "b006d9690b7a362398d09b5d5066bd8086f36863295b5da7c2a113035852ab00", "cf5e1d997aa0c51ac80169bae457d5f49810f5d7b601599e2d1d682cc93823e9"}, +{ "898000", "e303ff088305156ddd6d2b5d0c239e459d5175585902840d3f6713a40b2490f0", "4504065e186d009dd784aee6d957fbe295c8eb1c3bca23d860a92c6be32a9e16", "0d624b8f5443456d6afa38e9d8f65b44e63bdde4857b2dd7d86a79657350ce62"}, +{ "898500", "4400aba3a75afc73ab3f6f8328a179905fbae533dc9a75a67e8533dc34da8281", "f78290551a6f5db3989f2c6f6087b5746c0419604cca77a8bcd63268455aff2a", "493c6c9538fdd84f4a7ccdec7da1656bf3397863b566af0d053cdea28ddf4429"}, +{ "899000", "30d2245ee16163dcab5b9b71fd37c6e0a1a5a3924f621dc4bf2213702878da82", "83f95bf132b64bfdc4bd75ca04fd972d5caff941d36a7792f55f478fe140972a", "828367c69dcbc2bc8db30bd6a79fed31d5b0f465c1597faa85b9fd0299a7253b"}, +{ "899500", "f35505a5677e09578cbfc9c7900bc40b1add13a8df9f70781a95b00ff972add6", "a71b0bb9f424c20a026bd94aad9922dbde345382c0751bb892ac7cc9cf0b9722", "d6831c7b98fe9fe24be7e4e5e01e511c9eaea623a3c9378acc6f424f4675ed31"}, +{ "900000", "e37b70b214a685698666a18c3de3362baf0bd158b6f972e77bd306e62e7e4bea", "7a6f099828ed54a20b3b9565c1548ce0fcfa4de8c6131ed4caaa629d96e17864", "5a5155ad28208bc00f7e8cc3e48057f389d7e52db71d4e98ed747b4a58838f81"}, +{ "900500", "a2473a95b679ead1011918bbc526ef833ee8b03a5aa3f3e11198e30d11d2efae", "9736c820b1d63362019d39a77218d604205e38ec79a117c117ad12d1dd1f0075", "eeffa6fee4c89d0b7bf4aa5816c8f2d5c4bae46c937fa58f1815c732aac2de4e"}, +{ "901000", "dda19f6a2f7a7da12753b2d7c334e3df7cfaf74a44ba8304b3c5f5e05882afc7", "bc0f02a893b0609aa80e08392cffd1ad14ee3b625837d16be6869b5e405139c2", "4c98b101813e05bc7c83bed737947884c949e7b299a03b9416e93491b2b988ca"}, +{ "901500", "5d1585d8239afd15b1028bf7deac725db26ee14e9f611aaa8f972b27c8f8dc6f", "6f02fa43604aed757759d0116918538b094641c0cb9f66d75ccf62458139c5d8", "5017c361f626993f0914476c5a4f192e258979cf96ece6e0386868c3bbc2b49d"}, +{ "902000", "433e97c928b52d4964e08193549e6ebe938a665a0fb4bbea22307bc94c5ebc73", "6cc41a90d5140aece6e637d823cca6e4bb96fc7317a4d603c72fabc7f6239cb6", "db578775bc1f54616499ac4e819baa4b40b4e657b5dc18a5b1e7ea6e1b1cf918"}, +{ "902500", "4650e5d627e8526ec617f4f8c5a31bfb8ce3c6bdb2d10cea58873bf361cad4ef", "06acce13e151648075467370e9bec6864b80189ae6efe4e0e94a395b4852fcc9", "09b574f8cf4cacd2f1fcf2ceed04417defac847baf5f2d899cc0af70cf99e44e"}, +{ "903000", "3f9bdecef49c48d9d259d75cc8d8de5a09baa6b51aed59ac4cb9661afd4ee856", "ecb871b85f6e41259176b80cdfdbbca72a0e5831c0ec4d42dd90cfa361f2ea32", "938cbf36ae75d4ec793c8de82183e3e2c531f28ccae06603932618fd3460cd01"}, +{ "903500", "38512db7f3d831faafa2e27c548d9f10e08176c8745fceeb56a59b4f1ec16179", "cfe52056c802d202a734e35fa3693c77a8ba3a8f0774b76b9b2e9d962687003e", "fef1cb9e1986f58d64b1ac150366784a970b91c84182a5a2c8abc26f11a240fb"}, +{ "904000", "56e1e664a1de1e2f3fa285ed05c87b89a1db02aad29d4aa425d4491d6b502bff", "ffce9af2a239a9b97ab7f571269255fbe6bed14ec448078aa1315b1d7d823467", "c7cc12aff57434310d7d9d93a4114775b738f01c97c2918ec204ad5283ede6ac"}, +{ "904500", "62ed0214dee8bd914f40e07f60d0b42c2838e060aaa771b39e3fad5db4aba3e6", "004bdff9bea3fb7de4ed18cb1a546bae626f03adeda035d47fc8c6c7d04fce21", "d94ddcb97d5652096975c7456f98a99f81c2d4a7924d5ddb2728576fe5317f0d"}, +{ "905000", "02c1fb3064dd2e906dea5b09a9e9515ffeaf4a8e6290d213adf0328aa310e023", "0e8364f05dc947ea27a36adb21a97604d9e2fac67508a098f1c147968b7f9341", "c6031e17677cb3cd881166acd24b301964ad7ac0c6744650e8abd7c11fdd2454"}, +{ "905500", "013be02154184cdeeaa19e1e3419d4dd5f63991ad93362a2b4fa2e49039e9beb", "a12d791cfad9e6e291441245832cc82f7887902d4112108b57ddf584ba71d122", "a88ee394bce510665579b886509ba86417e3d937285c2e4991e17f23a814194d"}, +{ "906000", "3b1787f731829c85e9888fb9bc683df92ca34b636a1aa2878106d04e4d1ff448", "bc52cd21978e040a67220c44f03933086337dfe37f69cc3ace07f5d8ab1b3474", "7026fa68a8cd65d8f0a228b08dc1f2b8305b6c45626452142ce724ac0b80603f"}, +{ "906500", "0be9d3396dc9be557baf880730a8c8c98f0d008ccad020b54ab2f4d3ac5b2bf2", "79047ea467c9ea723cf97796ad295841d72b866b1e9b925fe363f99071eb9ec7", "0c791ca86defbe69ba22fe652e8d99edc976fa89e9d816c33a2d5e6b68acce15"}, +{ "907000", "6e80e964c740b9b31d2ffb3939b60f86d019bee6af9c3714f3afb313f659e9da", "9fced4419a17762d628a0fb6efce506270556b2b041eac626ed03b923e68730f", "9620881fe0c84df16713e0e1605a1e25236c9fdbdef5789f17b67f69165e4a18"}, +{ "907500", "7f70ecb783d1d233ea3f331fc823479f0478d4ba40e0b3e25bb5149307e688e2", "06a68c9ca8e4e9803d7d91072c7b8008dd77da2df6f1a329f071ab497b16dcf7", "214ed849404ce6d70a5f2ec0160f64e2461235ae3839eec2d51e9175e09ba4f1"}, +{ "908000", "1bb873cd795e98cb9b30c692846a31531cc7f4ce5a474a50bed96e2061e65e17", "0b269ad251a90950543ba4657bd0044258f3bdcf6c50d4aac1c89d87499d1aca", "e1d891bb3a149411fa39a8075fd428e2e6dfd32ab888a949b0ab3e9405d881c1"}, +{ "908500", "c57c7855c97f82ce4645a2addcea5145c98d1cb9553d56ad8909d43a29bdf320", "b97be283db5a293ad45e219ce5d9c8287118d7daa887e25eca7914ecce5b5db4", "c38048c0bdff948f1b636c072fa4af4b83fecc54ea561ebc74d728b402f173f2"}, +{ "909000", "340e921bae13e9a770996bfdc6b30d21502a9dbd0016d2cf0a60d299e01b55c4", "50d0d76f836bf9a1f6c807cfc9512ce2621a7f8e8d3215310d78222eff1dcdcc", "af825593546ad267439a73e196ea826c12d3629235be6b1e3e0bf01a550e1a3b"}, +{ "909500", "bb00fca39de21c9b3eeaef52a0f3ed353e63f041c817977b6339f6fa1c127827", "69b6dbb417be0072ca4ceb44d11e61569bff4161834baaf439361c0b17eef028", "c7cfbe1ec7c40047bd9a460e7eef271a77c32860b97baec14cdf274d7f46682f"}, +{ "910000", "355ed393bdcd6c79964e984b96df10eac86ebbdd70652985e5652175230e3f24", "6be87fd1fb578588c43235926805d8740eaf1fa271ed3ef54e1b830a976b85ab", "52e0ad64384b4dd7be7dc9fcbf4c4c6999935f4fd6ce4f2bbe018567e5324c8a"}, +{ "910500", "cebecf803381bd5bcfe62dd27d0fc46b34ca7f14ebbc463ec770e6998a1b629e", "6dca0680947bdb1ba9f6f2ebffd1475d18874ccc79ec26b75134ece99dee8c04", "a441f43ce75437af4af9d797d3ea8f3262ee86c42eb2f9b6d35b8512aa6ac652"}, +{ "911000", "0fce8ead8161e060242c6f7a6003c4de749dbc1194d8efa84dd22daea8cceab6", "649a3e01e83b89631a710906ed025cc0f67e8ea52f11e0b51ab3f8422a14de46", "9edca6d164ac003f15ad325e06f42763d213bd339161d67cc7fa053d0eaf3903"}, +{ "911500", "6e60193890cf91c0dafce4c0756a47c2d57b70b84723bed083cd3af287d82435", "b12f27c0626739460618af055b57710d241bf473d10c209edf8b10300d64a119", "49014d1f75815a2ead4ad7dcf46f86fa7b9434c22425b7d7ca99aa970f273328"}, +{ "912000", "c612c0ef542a4a95bc1f45d8b5992c5bbd499a0204d057fc5c3b8c6052b0bb48", "ef4f90f0e2c4a627416f8c7b590c79a4d030ce3b6ef7040fa8dfe20d9b1341cc", "5d9b94ec08ef46ab128a48ed2e40030a7fdf49722226c0274def2c0bc1f63334"}, +{ "912500", "4e8c07cc191bdca3f15f8e5e8fa2a0ccba376f23dc9618991f9fccaad35b1694", "6d2cf50ef5fb9c21ed59b5669566dc625e1a023ad3aefb75351c4e96a2df4222", "6af009dd536d8612079da2da7b7971c1faf48f858b860d1a90f3925b8daf033c"}, +{ "913000", "fc9fafc9d5208d6507d92462be6ffc8b3acebc7d3acba2bdb5f5b1afae779ab8", "bc2b997013ceeba576521c5a2dbaaf429b9d6eea2501947de4c696c2fc8083fb", "72a6ca802a448ab77bad7c28b3cea2ce9b8363fc7c978e2fad61345a686ad16e"}, +{ "913500", "928d12b4332252e7216fbb36d4384eba4ffd8bb79a50667b3fc15878c7deec76", "49d8085c3c7a8477fcdb80af39c1abdb69f5a0366e0dac79bfd30439b2f293e7", "805ee656d505d42bce2998fa67246169c9ec1f16e745490f1db09c54b1c281e3"}, +{ "914000", "7bf600d26589f7dc4cf0c68a9fd820b4709e95c864c379b4e5175b23d518091e", "6e60fe7892f34d0eb38229ada52332a8d1f0d120de231e404ef18f319adf5715", "ff1d407a33016b5ab38fabbb6ba22879805377114ec6adb19613274459e156b4"}, +{ "914500", "8e5cf10113f76678cb5265e293bd0365012f0ae661e58e6998005c96f1ac9869", "5df5fd9760d67bdf9708867bd15b11fe60230e125abf2db4500fd7db945fa6bd", "a933bfe1c6fdbc8d339369b5277743e85487d751d3dcea4c2add3e7cd1c78d08"}, +{ "915000", "33ddfa347fc55f5b299363d8b6bff03dc1d98ec1041236e66babf4023d3d52e7", "8a85853ae490805462a8aa3700c84a276cac17603b3dd0002c54490842cebee3", "cc0b6ba00675ca7088c7c4299286af7e1cb4ef0a98622e8109fc55cfc7bd2dc7"}, +{ "915500", "afba8520a990af275a8d1f82de844c793547432b5c6941e1b30859513098758f", "06ceaf9f70d81c901054cd961ddb15b5399fc0f19235c048649ff24bf916f552", "2f7ef80ddb64ee43f85492f1760fe53fa72ae703a1561e4d06aa1fbb3e36953f"}, +{ "916000", "fa8e0f7e4c73fa9914b795af620ee52434bf37fdaffba88d318af058830dd361", "41ec81c005795442c4705e943715065eb89cb4b32a2f38a311cf643b06880d79", "6d4b4d0f5a8c1a70bdac3261724846e02fb94bc538276f7f17bbd9bbd0914ee4"}, +{ "916500", "2b20f9d73d4c0af59212b3bf8383f845c95baabc51df6db044ba80fd5051eda1", "324489489a55e3767836aac9d5b620f5be775806ada19f27a61671a94098f269", "b87648e56fe39ca53538ec9c51d0ae98bdd38dea3049b54f0919568ebc5426e9"}, +{ "917000", "b7b20466d119311d1c85ebe1ef60dca612ee14b87e88d633fecc679d00b959a2", "96843566d7519919c12ee3cde2b4793e7043a066f63f3dfd690638d3b3d2bf5f", "128994409844e5ed3e8d4c53cf3f2a0f7ba386a88cbd21bcd2798642da105d2f"}, +{ "917500", "624ee2db152989d3e86cd4bdd32e84cde6f8d0fbc556561bc690c8d64d95319a", "d043c5740ca03cf42a53e4f8abcc96dea665a16acb738dacf29cccd3721a9081", "b53cf73a34e412370b6c793e3acdbb2ad92cd6ce6d6cf91d66a5e569b095b677"}, +{ "918000", "eab30c35d483b6b8d4ac7db12c139b294c9b9aec8d4c0db627f57586b3d1f6a8", "121c7b5a220fbcba9735c6ce0425ec14d9d80f75bb498a986684c446ce8ea2c6", "ec65f599ff6d9665845871374ec58197d0e6c0d7fb2afea19d7eb81c4bcb2651"}, +{ "918500", "e9bfefe8932f66486d1d3a740d14b1fbab1fbf80b5abc9abb4af1333efada148", "3909b21ceddd287e2b1d8cf16accff743dbfe6c2c0a0080a33592036cae626ca", "17df39dc7da315f869c7c7a1a6cf1a4abc14dc56b4200c3029e977ec7f1759df"}, +{ "919000", "4111e02c00666bb2701731d59808917da660228f50fad0d338d31324219fcd2c", "faa3d00c409b5cd2cac4bff556bc5d07fe901df0b3e6f1e1059e661f59dca640", "f098984bbe4e46aaa2fb1830f5d28fb920997095d0de60b0c44f839f60d035c4"}, +{ "919500", "fe8ceefd0657909d523c68ab34109db47c31a56d96190f25eec23ccac28356ac", "dff9eadfdd7da200e3f9ee425b46e6f1869c2947d77eb068d3de8e281ccc9f33", "90889e7baa5d936dff61a5953c5576e2877455f1f0d92bdf5d17084260d122a5"}, +{ "920000", "94c0c84e0720cf98585709161f8e0d52106a76810c36e8eceaa50c5937423e31", "985aeea9e4d2fa5b24727c5bab4979f7c181d52e1939f5c1e9b9fd9d8d21ffa5", "619a77f293cf5bcfe5b8e55422c347b1fe595d6a8b9380ecf51ffbcbc776f899"}, +{ "920500", "7942c1928c1c7fdce2a7f9948db255a58ac28c650d44f2cbb568b14b7e77a869", "3fac2092a646a391bcf3f5a3703341b9667c9dd1800148346bf3d0ac8eb0b8f8", "4274a21857221b986a03ab73c4106111e6c28de8d871ef01d78de3b3f2c8bd4d"}, +{ "921000", "3ad13dc5aa84d6f0c89d4c1d4424928e1c3f17def687432e3dc5bc0d1f748e4d", "fc66d327154d4f892c6fc8a1a766917e137dd5ac1de66a8e93a1e3206318133f", "4568c9acce0621cf48b4c9257deba3b99e91d3a271645605c2a35e654b73d3ee"}, +{ "921500", "fe4b447119ad825c1f495dbb58a1aa394eeb40e6fa1de1ddf72886ea69042eee", "aae2951a99bc6f730c70d78dbb6486d95d432b7fb154696f0e866b5e661baca6", "d546355aab871ec43391d1028847b386e92e2f80de62cd9140b01643738c74bc"}, +{ "922000", "7d1d205b9c72f860b446b8b254d1c22a8e5a5049227ceff04424ff01761cc29a", "9fca8ce08cf17dda9b4a2695096a50f5cbd54c8c11f7c048bad4e27c01a7dc9a", "511a897002b03614f4138dd5c05605da5e8d82a1da39d01b1d58433eb69421d0"}, +{ "922500", "c16ad392838d47ba7fcef91e9a0be7cfa1dd11d22c9ccc0b6f631aa48abc73f8", "01ccf18791d85e7a78fdc9e751948c42a6d58d9c4fefc118cf882c0a5bef2ac5", "a28930ef1b65db143de30c76efb40ac8dba61cbe0030eab5370d3e417263f61a"}, +{ "923000", "438bd2d6867e38f68f61f9dc64952993f7492e39771516520eedd7d5d9d4054f", "40b95ef95e78ae4c9e99865bd4e7a4f7d106c8d2aba90f54aed550f14aa9ce17", "ca62e3ac3b194977d03c66b015c7975457db5f6c849f7b999dca95161d06064e"}, +{ "923500", "6c205a2902c4c350df7de4e96c6815eda103645b9181fd9e8bbd6e53b5ed843f", "9d8c87504c9db8490188c7d8fb0e6aa1950a03a80cd2bd0f8baf0297a73ceb27", "c3cdf41378c92bd85ca01c42ff115906b51ace69f122d3b1b6b4a5f922d92098"}, +{ "924000", "821de00a7dd17becc9dc0ff750b9e74237ec391e9e2effbabb71d33fe96e574b", "c87cec5b256635170e6428e3040000d705decb654b84a7ac9d1566211e18dd36", "81890bcab453994fcd82bbe934219d642b127460aff6fd52a37c957bae1f0ca4"}, +{ "924500", "fc66fbb75f4f01611cc4bc86249e329e5f217ec40e0f64f332ef508f4d524fa4", "13e45c01e9098567eead7d1e2840a44cde36926ba83c270e6bb854ff079fe864", "af0db78afb9fd983d191c7482aef99fd8fc3f83ddc7bf969250a88db0cfe3e8b"}, +{ "925000", "b290fffcf3f8eb763704f79a4a6e5fd76a853a3cd013efe2e41fafb9177d223a", "3d9b89cc34b988fb0d1df0135f59df3495da0221277ed3abefed3558408ee132", "ba6e53516126dd7d723c11edf28c7f60eea4c250f4d9183b09cdcb74df0496d5"}, +{ "925500", "3a1fb804b8f62e4c394b4fb34b250986d195b4a066238eec560443219bb06a25", "3024ae8c2825c85dfe675f2b66b4576a6ebb934166dda6a12016fa8f79f12a63", "4d687963ecedcad164e63649974289bbf8f463acd84b790b1aa611ce7fbfe681"}, +{ "926000", "819094082ab3ba4c3a715880ca1de8c9b7036d68224202838a077d1c48a0fa33", "afb6ae704efec0cb30127cdc4c608245d88b3bd39e3f09b30273420046051679", "471b7d7e14436515e046998af8ac65f3e9ed8339f31e292c2c1f793eee400ae3"}, +{ "926500", "eb74c0dd62c2e8fc7e9c45545e190d959a6ca29515bc7775cf20f2bce27349f1", "13849b250174a3db106e2184f7621ea88b2e6b6fa4d36ebb2353cd7fcd0d4a12", "1303beca265306318f19a0a0aecbfd784a5304ff9a7537051d14f78c1be44815"}, +{ "927000", "6397314f6bdd9ef003cc2ba39a4539c1e2267b13272c78b886127419a1edcd28", "3455accc7f9a3e2324080e7691ba7134f8a6a3d6b0f59ac8ab1f8de3b1db976c", "4875a59e95790da4881487d2e8f881cfb6370ea23609e157a3d3b67ec84ae8da"}, +{ "927500", "5f1f6df5959482ae36d755bb88a5b2788a0f6e8ce6e2d62811da77c02324703f", "044a874fd1df9bc0e384a192c669fcacc6946d2ed148bd5b3cae0eea0ecaf625", "2fa5e7eb72e545b0de5970ea40f9a13a9df27a3442d71da9a75aec0d47c10160"}, +{ "928000", "3ee8e52f1ecd00dfa60cf89435c08ffbbfbd1e0f9596541cbcbef38c520cd71e", "af25521212acea8f5c894fb0e2c0f38a4abee868b66ed124a77980e5ae7fd840", "a839361ff828bc1035236d946e156b9f683598a5d432024ffcc81b4e53939df9"}, +{ "928500", "c3f4c0ddbf8dc7a91e5e27e3bd4d8f817d18ce724d9756354449d7894f96cb7f", "d7cd61faaf6d8e0b362aaef72304bf0d1d8d751b1fdb6e8c11482fa5b14c2045", "5e37546783cc6392c5658a293acb1e30132ab4c77ea58d328c00a9cd663381b1"}, +{ "929000", "73c7f82ac5c353490479945a8e5a3528e85ba4276e3c7b5b359ed66f34006d68", "9def4754e80ad70729276465a92e65e9d70a3fec02ce46d76a6b748bbf19180f", "5aac3534692f0996f5383d9cb8de32dcf0226b872a9b1005b855f7eb86693b81"}, +{ "929500", "90838c6bda7f6f4a9964c3b99caff44d656fde4928d526d7b761aade9f6c5a4d", "43be3d47189799a47edbe664a2e9452e57e7ecf8f5df272a5090552cce912ac5", "51a31579edf889149fd632d32a9e8f155fc2a73aed2d375f0069e9f131f42afa"}, +{ "930000", "993167ee131ed2e0875b7a764cb7e8651a01b44b85b4b40c16cf8b69f0754029", "5183e99bf7bc05a09fd514bcd646aa16fd040d8313d5c2083291d350988e99e7", "c53da68fc001a0f18d5850b88a9884e899cc09745a8fd5001610458b553ff45c"}, +{ "930500", "53525fdf3fee3ea4bd860ca7185365312b74dd8cc1e3f6397f3a467f2fd659f5", "b08fdc19e65d7ba7a01ae37de9db8065c344f602cd6811a6b0fa7efc22cc9ef5", "8478d3baf29d721b940b68501c85e0d81d566f89e56dc19188e44be9d3765f04"}, +{ "931000", "310257cecaa31778dc0ad056b4d0ba181b0339630bd9a54f1d2c01241546b648", "e84fb5af344ef95707e5060d1675d11e8b7373524227fbcdfd3a7790530b9eba", "adb90dc53ff35e4efcc94cf3e4872059e549ee9e0062ab9d12a7fb3fd3b04b4c"}, +{ "931500", "8f92f22fd3d4d35cd69456574605c6463abf15a58bafd4fb2144e58b2ae60bbc", "a05d6abd0dde92b9e65dfc93c149ca2f6ace7416efb996cbe4a1eb31d4add968", "b04d9131cc6c34eb0c55d962434e2a32c9352d4767f4305f5a4ee212b7682a3b"}, +{ "932000", "975a067e94d2f89f81945c70161dad251c93387934c9869007bf17f9f8175f66", "38b53fea2e9bf87fa3f0478da19edae0de9444e35605e064e864f441c6531ec1", "d4906ec70a0e2883a1c10ba3dd6d14b9b01bc52df11620685df1c7e2f7b1f515"}, +{ "932500", "438ce459632f23fc45667091be8a8a4247f6f83500e46805a7a63c72fd674b22", "aa7fc841988e91577fef8ed0b8b134e9261d1f8afadd12aac3fe7a39129cc393", "1cb0e73b74af2b1db898afe065e49022ccaaa178609aeec1251189133fd48ab1"}, +{ "933000", "07ece8e5df3457f385595c03d9abbf7b42654e15548ee72fa01b7c98d87fd654", "de3e7b6128fe92260b645119d9aef6a57361cc46ae6328c4752cf0feffa7e93a", "d6d5794e9583f01149951f860cf2fcdb80a563e78162acac5282a17b1af23095"}, +{ "933500", "bdbeb91240264a917bf44b878b92c09c6a15005a39d51bd7cc4d6d401e1e4319", "ae3181503323e70a8fd2a11ebc82decaaebe409793fdf43f8fce394b17dad188", "f8c6efd1358c3135e3d409b5801c521bb0d198ad7b2b3845bf703668fa08c2e9"}, +{ "934000", "f3bd01e5acae46dbfb3365f3432ec1c81a2cfdff7cc6affae91c109ef698615e", "74af995d48d047894f0d544423ba75d2018f04d928c6e7e468115bc9d447317b", "0a25e2580c6d19575df1b34a8a9d053a69cbd3ca7e47ee9dd5344cfafba900a7"}, +{ "934500", "d1518129840b5977d13fd42440c257445bb31944c177691c8204c6babbd58f46", "c270324df573701c0b3e41267557932eb7fd68e46d96f84e1e302b6e336207f2", "be679e077ec214a331e206447b59d5401fdc422e20362aaa83cd23ef1cdadb6c"}, +{ "935000", "00f16b56da0b5e21f74c506d5d2a1d7a10f4403e6feda3b75b269b93a7b8751a", "85b16fbf368e56074baa64cfe454fcd4d387dd2a3e4e8dfee7de5d65ea7a423c", "5b3050f09ad3ca761f65bd80fabee09db49f2f20a99c8f22d3b5c95dd7462296"}, +{ "935500", "bca2a40ec3e783714d2dea107f8a35cd01ac37f845d78181e79e88d3770b9192", "99a2c6c0e33f5dc75a98b39100a26426408944d396bdfa5302fa0aa8df340f2f", "ea65eaa05964c10969456e95d66d54e70f51904671eef31309dcf1659173a7b7"}, +{ "936000", "03e8bf996ca3565405d01cfacc215f59481b90ed44d2b8329379fce0967290c5", "7c6c2acfeb309f1fc6132fe8a812310aef3840b6af2cc1928394be16105e253a", "0e80f01c0ef1549e7ea13ad275af2cb0353e5415e44a5085d72c9a3e171b3319"}, +{ "936500", "36b9b71a5a9d854eb5456a8df936d8995f40520173c81befa852db9773a1d26b", "53733cbe7fd5a371c8508291f8d2ed3720b87838f3f15d3db8c16656f722b5d1", "8465a44a4efe2c42bb8efbae4cbe46d5819094f9096cc3bef9727e9a9056438f"}, +{ "937000", "665e5bb5ece8d808b906d0476716f2fffff168696bfeca1b5483c7345f029a7c", "801b0c3ff2814d875ba2f1be4f26abb060fea42ca9190a45275d13523103d015", "4eec03fc9f6315c94faf8e81ccbe7e9b840e42d991cd9ce72d1f880c5216a095"}, +{ "937500", "89c15cc1d22a312379aad5255d2c965ce9d466a9a308052fdace9d955878b03f", "e1b6c64abf2b80105d8c292532489650af97b6de6b6362ca8d5a090e3fb6e930", "b729dcdaa9799ad26958f0407c569a6ce6b6272b1c14bbc808b4a90e2250aa70"}, +{ "938000", "69263892b7a2117af68e35c3e6f5ac6de567bb84d10d86ef9492eb31cdb78e36", "1db7af4a0cf53f0686e7ad7dcc15076154d06e9fd8ca256fef101fd82a76adda", "1b744b3a013f3f3af72b65eddb918a11cc791b26fd4304e2c35b1696c7d70660"}, +{ "938500", "031638da90c052d869dc3da33fc044507e0831219ae121e416c10cd8ff5c25fe", "2e94ef6c5ac4720c93b9389a66cf999f22145751f58cf13bdaace6d5b1735344", "62380acade3dcb89b6cc458982cb9c760fc3be1455f7f8f1c5b8281067488968"}, +{ "939000", "342f820c0656c6e11de2032ca29247575c0121d8414c63e703c486a5662fcc00", "e23bfa4425b2d940da54a62f26883b429558dbae605a1a762be33a5aa18b63fd", "17f7d790a20ae0a292ed62f76f2ac831088effc15ee2047156658e51b779bf58"}, +{ "939500", "250cd72bd19b23ca51479cea2a7a9f4bfec67e343e250cd67b6727baee2d8520", "b2514af432838f255641352ff93268b990c0346997e2c11e93987dbffbf50344", "d59f0df3ee98c60d54360adf42c98dff754cfafd18d21b93ab45b120edd8a914"}, +{ "940000", "1fe1cf60f5e02ab75067eae08e3f8c71e4cff03d232bf2f2c6f789ef49dd134c", "c4b2e8af2ad3c324a01c586f22be66a30dce34d76e05c9c8296b6391cc143e44", "5c5379961483368837d22746583f5dcf50022019c71fa3f948429da2a4892f7f"}, +{ "940500", "37fd0de5d9900234dafcd91f2800fedc4bdd5f5f77c6091c5007ea3f5091e834", "257db0f9e944de6816c015102334c79e531decc0e89396c49ab043143d557ae7", "b752eabdea95cc3534b2f6140ede29ae47192a7003c09537329346847ca434ac"}, +{ "941000", "6751331b479dab2a45ccab32a8df6c5667df8717d99bce3eda9099d5a93976c3", "8d3c34ea9311963d4aa20cf0c35c17d5556c926589354d474ae4f89fc7610ce3", "9e17d95145857f43e5cbaa9dba6394406a1315a9823688bc1a3f75398962b600"}, +{ "941500", "e20ebc38059a946e50e5779e069d3598de8677e2974efac3aae5189904ec9b2c", "7d08a1657f10154b398f06cfba601c5b8cf68d0a70afb8b1905ea8b9e449ae43", "f808b65efeb9d8b9cf630fedebb42bab2965bd29f45772423d1dfc405e29f7ec"}, +{ "942000", "08b423776e24127b4db2d00a86ef3d23defa5a94ee9e8a8d04723a0061c80d09", "94e541a46a6d4c989c209f262c0c563bec8a6cafa3bf7a61e1bf73008a3ccf90", "49d866b9bf0ea648408347f88a07486802c1dfdbcb7c4b35165fb57de6f422c8"}, +{ "942500", "e99b00e621c453bc93e1238a8de8af078b2cb639f185a7061fe7b1d97c66b6b4", "0fcee30b06113c4d3b1f019e57cc19c5f448efa689f5a95f041a715c115deea1", "53a1e6bbf4b763b3730c7fc78a48efe5c79f6756157b2bedd17ab55324c1284f"}, +{ "943000", "dabc19a6f8952c1f8c2b4a6ee8540d91c59b54a953ab93071f026150cca356fb", "66da69070bf359d355715c3f66470c0711470eadaf3ceb1ac80648beb4265b5e", "f0d29101757acc0dd73a2270f7ef6068f011d25407d85da1d25034aed0fdd069"}, +{ "943500", "efa86ec88589aa9853bbf58b7a66708f52d72b32a43901253b48ef89fdc68195", "da99ff838ba09c7843aa05dd869311fc058e9a266ab3cb560e4c4ebad30bd6b7", "df2324edb9840ff91b45d2cd4769a4b57f5e4a9a1fcdda6f5a603d94f325bafc"}, +{ "944000", "2f594ae136ca24d6d073e29d4a7278134ae0fdb782e823c2fe6efa9ba8c053dc", "d285a29599828a65ddaad8acd888a3030133f8583f5618af616c3637c3778861", "3080c758a77224e44ba67c0667b77fa366310542f5b851c04b994c391634ab68"}, +{ "944500", "c3ba87169f55a8669f3f2c7e94df26be0afb0e810104dfb2fcabfe40847eb644", "e028eac5db8fb1a565277f5587d8ff105a3f4523946a20a3cbdb16e7eebaf586", "87c283fdcb34a2cbee915f730f72e3368b4cb47f6abe44ebc6fec8caaab96d74"}, +{ "945000", "5aabdf7dbbf96f3b9136f7891335b4b4d2ded4a4ef4b15aae24400ce7eede6d5", "a791d33db0c6c72fe407c3141d954c7b6166964cadecc7fc7d9d70a05c64f5d1", "b532999fd01a92636e0004fb99621a13161d561a7a3525c6b24919008b50d00d"}, +{ "945500", "160513624bd360141f9f2aa0b77e15f2f78adffde5408688a3f5cf2748f5a33e", "1978fbf063588d8d5c669261b70e569bb5242c67ea4b896e4fd273cd5fc919e9", "e1b29ffb015db13c6f12925809d5c607b39249f5f5051b90d78f925e43a890ed"}, +{ "946000", "baef0350d326a00c5724bbb63a3a7d12a8463d59407afe8cb775f3282dabe66f", "3a08925e17e7c91fa44526b13304a55ac9344cf0139d6b2573fb362efbf6e2e1", "12953db0d841e911244a3e10f9f971c035e714d9a7535d1057ce96b2b25a0200"}, +{ "946500", "3ba6204f144b41e18b5f571aaddd7591cc8a2461790e23117eb263def13a409b", "c72dd099c929527f4916ed7dc0cf34d3c4b98a4ea8f488be7b92980af42ba4d3", "9a967079f01e44081c5349fa42ccbe3436afab5acd9474ffe97a0e9b62c29c75"}, +{ "947000", "1bdd194c738e7fdf54249f73177a6c78104e06133d0fd97d2e732e86752d53ce", "45f323adec9c4eee2e3ca82bbb2a165a0a94db22d3d700dd34688fb2575343bb", "71ab8b24e330266c7745fffd95eaa3842ccbcfc89ee71d944cb4f394ddfd7f00"}, +{ "947500", "b99a2375ff79648c98fa232d1b0fe37759deb5826866853913e7ef1fe2eb65c2", "17dd7cc2b9689b1b4ac97ec835fdcf9ce80cd5728d2d5d2a14883e382e182f51", "b6e255002349e934651aa29ba88b523359aefe2c587b12b9ae5f315654e2ad06"}, +{ "948000", "de7bbfc82a59fa0c6691020204c4916b9b102f66536e061a3585824472bbf2ac", "2de0049ec5f874e752ed146e2c7edf63f6095e53a8a349ed06c052a341d87e1c", "e9f976098892480b5662a211469875d3957bc09297ca5445ec32118373d80d62"}, +{ "948500", "ac2e0e3c131538ed118a3123795a2fe51803a11c3b4b08a7e47981884b2f62cf", "f870ed2d50bf25f95cee956ed54551f4b3e92d54abeecc3f0aa5cc15c5b10a80", "9dc10ba06c9e3657acda84f512e71e2623e92153f355fc85f292efbd7fd27293"}, +{ "949000", "e1e69e1b1b21e4f0a18b04ac9cfd9f8285db96ff6f4e9ba2ea5a454d7b4a51cf", "f08f455608a96421e2c42c6fb44348331ded8f44536def80ddc2aaea53f811be", "e9fc9f8f87793b08608e8537c9e2ff487a6a0371c40f601076866cafe3819747"}, +{ "949500", "5be555320df6b2e99d8f77952bb45df07ca3f9f1bffe4a4800a156af93d0c629", "5801c09b3c3ddd4fecdc69bafd4b6ed5599f5b4c3d480b6cf9e319be1aebcad1", "77b78279551add5e0960ac20f6beca37c1a18a3f4d8bb4afa3ee783d5e05d95a"}, +{ "950000", "e227fbd4fabcb18eb1e600e30654fe09de863f77f81c7634c2815bdf909992a2", "5c5fdf4e2450ff02361822c4702cbecdd0cef3c818ec819a8ada6c7791516396", "2900534be4fa7b504bf8f6a1047adeced6250f63dd441cef1e1d684511f104ac"}, +{ "950500", "9c0dd1fb0034c4a92f5b77bcc7e5818dcccee55af147ec6edccd499465ed8502", "94d3663c2526c1645a1e7430614a665a7f35183275b7167c5893d6b1fac7b530", "8ffc20f33c23109237f1f1fbafaa719c87402f09f90ad22c73cdf18ce0fa5cd1"}, +{ "951000", "2e932c87fedb78048a70c47b4f33425ac91e5edf91ee12421a4dc6675c50b084", "2b9e81d117f74eb48f91f5ef0c75c345f0d1f8685b2caccdd0e739f8a4d54d04", "aaec22e07e78f82d3fd5336adfb33c5cf83ddc95df01a0ffe6624bc222724d80"}, +{ "951500", "3d14b8f5c18082a279d433595fed521d134c844ada0f144595bd1c6c271b02bb", "9b6803d021c36acac84246ff8e5ecf486a40de03cf3f256b91dbc1020c62f772", "09f5043a2a9f466d8ee91d7cb61acf9ad6d16758a27f72adea3eb453a968dac5"}, +{ "952000", "f1d7b3035d1b4a3ca9bb76325f8e09ff28baf0c0bc02d6d02f2f12e09cb25bf5", "336abcd43c7b1c697e751756f24bc499eb5450d9d6adbe83b01233a73587b72e", "c7aa3eb4463829a604d2d46823be735ff9f47ea78be069a25ea75dacf86c2a28"}, +{ "952500", "09ddfeb92d32ba800b9f715b8c2148d283e4fd0bfbd1d0fb1a32c2249dd919c9", "a22209348a5e34a49ff2a9dad503299d59877783d47d5ca6e770a29a07396adf", "69ec74309f004f52806a5b3158f98aed9b4b5b5dea08339023515c54d50e991d"}, +{ "953000", "613e697f705fac48776f20e3f1ead078e683ba3b5ad72ad9867e14be2d28cecd", "5d74a3b0feadd5f3edbafc529ee8a086eb81cfd9f8588e12ec8631eacb955600", "fece4fea60c77b3c982fbddca9895e9e3c24e6bbd5290287ea15cd2c3cb9cf20"}, +{ "953500", "f9ab20889ab4c8d6f7dd46411b80f89f3551920684d8e4b1d3de88a5dfcfdd6f", "3b4c8c9739de63889bdbae40394a5e0bb12b982a5159e01c32d005e31ba7b4cd", "9f322ff3e4fcb73f3849b552fcb961aac906ad7e7c368917935b302f75f0e99d"}, +{ "954000", "01471d646b617bc8199e95555f46f2893e97502bf541dc6dde371e0ceca8ddf1", "b805b91fa492fea176eb197c88526fe225f18a52196cfc3da37b8850eb36e4be", "a011d1c7c4af6cf1c6ef8eff91a62a1cd8e7908d4e880fa1c69509626e42f0d5"}, +{ "954500", "c26bbf96a0ff7d8d6ef2d2ca911b2c8f649be385be4f526753cd5776686f9683", "e22b003c8414dd5d24dcbd5882705846e7391883fee7252d2f0019d0f066193f", "bb2c86475f9f60c4d5904eac230f89dc03ce58eddb0c7f82a79b28d455ba4a92"}, +{ "955000", "2812f54afa9234f02d0f89ce067730047af24ee14b3c380024da7a6567787b3c", "3a796a63e0dfc3baaa249d05553a993a4bae85c3ed54b183adfbaaed1a1398a2", "4ece14cb9ad276c6eb4bbf4566657fc4eeaba0b5519b6111db5553520c024d36"}, +{ "955500", "9c05768aa95ace543246ebb963ce1548cd9e5ddee7a6f5e45cce1db5c47bb2a7", "c824fcfa5ae174f199cd91ecf2ed8049716e6d7dcedc0cb4be2a3bae035aa6ec", "e13affedf873d26bfc24d47b9d4d4fe5a3da26c28f84b4115c97a40287c89920"}, +{ "956000", "769586a0e2d78803ddc48d46a6477505359896a7b8070cb55076d142d9360ec3", "69a7018a58df10204ad1f874a7d652185e74bbd75d6e6b29dfe6bce759dfe945", "4f7f343a437f4a9af6f8cc6e5c2e355d62a66df820489155e67877303cfd688f"}, +{ "956500", "ee555f15c4a433b4ad77468b6dad7560838ceabb56fe1e67076ee0e23a2e5aee", "727ffc7586197dd0e3929e7641f10fe84c5b7c1255a4075496afa76cf8a4a473", "1bad79baeca77e98f4a0a127d38228b7760aad45e61d26ee8782c3d58a6e7a9e"}, +{ "957000", "1df30e4f986c04325e299cfb1350dffc76591f9ad53b40ab249769b38a1488cd", "3e689b1cb999a8528c0fb90fbe51adbd0b90f6237a80169b49991a25caa86fea", "6d7cd9894e43299c76779bab920d5956d7cb69037bcd2daaec94f40cf6413a4f"}, +{ "957500", "0be5166150c2dadabff827efe2a7e1760807aea08f7c0c5855a47e9cea4149c8", "b8c9f5d0a6b7baa4947e6bb898ef1ca502c6c77fb6e1abcb58bad5451bfaa94d", "1c35f4e7046e10f2c100559833e6f7daca3a51e8c81a1766445607d0a58f5652"}, +{ "958000", "05d2d2d75328dad0ecf43961e0b52b227ef311a18576b2a2c58f9a1fd4844aec", "ab2e7a9c7bac8c39a3bc96f989afe46468975542d8186cef457c9ad8adbb876b", "a70069a6c9f4f0ede4c3342ef63b636fab7adb0bc56a3be09c75d1e37d329e28"}, +{ "958500", "a06d333eb4fda03d0e2cbd27d8d415e84d5da63d7e5db371e0d5b2744c32e625", "7b093292ab44a6f779b5ed00cca79a1bae4eb79de2cb150b9ed38a43e7deb57a", "aab451b16be52aa2546d2bc54e78980c3aa64532fad80db5a13b4c8114faedf5"}, +{ "959000", "ce381f9253633f9d2b48b71987f9827e5b8d68d09bc55248badbbeb85ccd33dc", "ef5fa33efab771f5175bdeb4ad9f5a0e6b122f02d47fc5dfcf950d467778a23e", "ce46c78c4e93e8213f768527501def929bcb568fb266d4c331d09d7e1f264ed2"}, +{ "959500", "c6e95e1ea44b4e47cece003fb1e8da01479c0b41de18ed008e1f6746f208b75b", "9b6c1ecd301c7dce7d5c3f0da8c4e1e7523570aa387c8f3c5006a55117fc5420", "9b915bd62d44bb84dd76c96adc9468024b757018674fae0cb26a576b357c4637"}, +{ "960000", "bdb90de7a26c79d8559d48f9cf9acfd272a2ebefe86c78e11759a9614e5f2400", "5defaf36aad68670ae534577435596269927ebb28ff6daf25e7992863e048ac4", "1fc928c303d4f7a40e4b9ff2698575fd8978fdff1003850762a91f103a8ea0f6"}, +{ "960500", "c8394c48d68806fade6e2d1b27fb16f1db969be718c19151625ed723c4d782c4", "9074493aa1e6b8327a8c725279fc67b90dee31ebe94e9e2431ac9388f8d6b7c3", "2895f1f0145a7df71c22849ff4266ded050bf8fe5adabde369b398212acb577f"}, +{ "961000", "9177a28ac1eaf2190c6d3e96bbcfe1ace9cec8687d91c5d1ef6a51d3133a6251", "13d00e3d155f0535894a8a170925f592f63112f285d5859b05119a90d6ef06b9", "95ca6d7417b662f691b371faf949de77867de09164d2989e32e82b64f557b399"}, +{ "961500", "7fc9e7b2460070aa7de93a059e74f220dfed6ca9d60784f305737f4924067658", "d688c89a2e08e78cf11cf0b62ef92e4969f934a53ab7650a09b3178693f9f4f1", "841b8871077a869cf1eff185f6290f379832001cd6f36fb545ab9faf6fcb1517"}, +{ "962000", "92b750fd920737b637e87ec6ba242570e05c24805a4c06ca6adfe72de1cf3cca", "79ceeaf812c0d470eede3c04b06ae94cd14e3569958bd0e7ae4ab4583f1652a9", "717002615460b13db543f643e27ec120808571bfdcc82199e0e33599cfbddd97"}, +{ "962500", "4723dabab6846111db863946410887489b0917f28b6941661d38150e80045834", "2b5b5f09f42e8441a73d1d69ec1248b881401b23610153724bf4721158a8cdf9", "647da4cd89fd11d38c19847d198e921f3e538f5adb7d283ddb9338dc1ad0f5b8"}, +{ "963000", "e7718854b1a117c939c705a60d706adbab7bc1eb29e18b3fa86f6f7052a4ff5e", "aeff06b67b31c015553db2a96db0360e61d61e3ba03b81622a2f6535540bd431", "66781cf92c355b1c2b0a8d17868c0c880ae5dbff1d6b29142cafbfd689f6f50f"}, +{ "963500", "64755a7e2fe737d5c50c0294b03ce6f11cb5ec07f55e42955c5e0363f371c5ae", "3d5d8c6aac6ecff5aa8be9a984838046bd6a8c591e0e179ef9e171b1cb04869d", "ddb7bdff3758560760df753779577f8aca0f4fd391687cbcfc4d35661f4da2ee"}, +{ "964000", "59bd046c3893cc35c97f871dfcb03988af640790f5b81bcd37720fd13a4eafff", "c0dcc142ef875e0a37f250ebc98a96a50671a4f3e36868d2b6e3782be04c275f", "0e2accd5b8254d57a052f5b8de81d05393e019939bb667317ecdd42f47d185d3"}, +{ "964500", "6f0dce76e2a057372de537c19e9cf8e89261cc24a56b30bd3cef7d9458efae79", "186d6eb95874086c7dbede1decbe52e2ef4f9bd7389ff5897d40e5d63e4fbb97", "5bea9aa83277393356b825cab01690cde995625091b2af3d6634777fdf6896b2"}, +{ "965000", "6e7d4ade21bc5b59d50ba629a0bac97eba1ea1c22b909d55c62115d83c48b0a6", "9ceae7a7c366ce13b5903ef59ee5a940c2f50eeb7ed88e1b5d3fe41f3d5cc8e1", "b00ba8d4828b108349a7326d13a4699d02013b8c683f4de0e1d5ccd9e4e78cdd"}, +{ "965500", "07073df1aab61b4e7d6ac4e3a47cb41266476326136ae32a17e63da2df0eea3b", "8bba0ae4edf8a31f1d3f2eb3e2bc8cf89913e3588470c4c26002cab2533120de", "05d2bfdcb4dd59c20b9c54a59af159a75bf0a3ce3d3b8fc18690e5d4053a0493"}, +{ "966000", "46de91c0817c0802081c0382a111d4eb0383e64cc412e20e14925ca8256da92f", "4da17f7bced7a0672c7932fffcc076da613c82178e51618ba0d051897294a49c", "aa5c04b7225ed68ebebe52fcf6120524166bebe68416e7265f3e0a56e4321111"}, +{ "966500", "5d31a7188d2e344852c1cda1fca474397652e623eb5160cac91f0765317e1157", "4dd7385532824e90376cd8b918f5877e7d65e7826a55cc5eaec718f9959ced59", "19e82f194381e36df76799e88d4e71f32094dd8f109cb4157d3209bb821924e3"}, +{ "967000", "ab1b701b49ea5a3d698a37dd97453251fd53b70ff008b8fb6b34d90c30298e07", "f4d5279f7270a1277967be4076aee31ea3553c8baa7229456ec833a974713408", "c600620b995fe71b11254415ab8d8496e7b09f0abea4f05c6df7cc3b74ad29c1"}, +{ "967500", "fcec3fe1ca40415a65df82b0587f4ccee3f121fe82592d724de22700399e38a7", "c7fdcac6633aeb83f348ab7e86341906e3f30c84422c33b1352e96b858dcd2bb", "4b3ca0d6ccdcc52d365dd33834e115ba8ad32a53d5f184db6880d00d433f0830"}, +{ "968000", "9b8ded270161eeb47e94caf849655c0930476f6b73ca1afc050f35af10103e47", "3fd0c2e552084120e2fcc8b943e734d4bc1a60ff598ce4365fa8a1beec829381", "3908294f574a60fb2de3e642dce1e1a8bd5854dfa7f71ab1c2f32cc261eae392"}, +{ "968500", "0845de27097e020706a6f139763ff199f0d665d00567812507bbdb4c4739a7c4", "75003bbc6f63a32615d906f51b0e325f78a3281c706162f24d3468ef42d0b2f6", "8658ed5f9bf63a9429749978488323a72c94e6d703b44777bffc09bf1d588bba"}, +{ "969000", "f92cd5a018e68cbe9a7f4da90a101409966d441e596d102bcac073828c13cc11", "caffbbd1f4a08e8b23273a4ab7bcb53ad5c1b80f73925a18268d2f17f930d1f2", "4289e02fccd85fb8a0d9e981f24667346bf77eb7d49ce56b0580e4d363d27f98"}, +{ "969500", "b08c175b0d02a58d410f0d9bb296059e5478c58ceb35259b225ce26c58ec2ab6", "003d4e578d4e99ecd8d1b569535e33d57e5287248eeeefaa97ad0487f8836f15", "5906b9e9c0b48fb8b5349474d72c9726cda06d062f19e1cea40d2008c25824c3"}, +{ "970000", "391747367a3e4346b56c97953d6fb4fa89473d95429e93a75cd5844ffe846812", "9af7f2fb1b4e414d796c5cf0d2324150025e5366e8db18cfa5ad7804956e4e27", "029d6e6ae51f7d222928fc51ee95d099da8309ab66ec0abe1158c7c046c473f2"}, +{ "970500", "caa262b1741e47d85bf772b131badec7e12319a3ab8a617d9f57d6584360c2ad", "293f56976cad2572a3c4b77266dc83d0810a915c1b9f4c4dad5e1cccdd715101", "91ed5f7c7abf693f2d85551e5936354bd9c726c4698bf369036f122adb03f957"}, +{ "971000", "ac906e072ba4a6d698d5581a7ec46bf277c76691314d3390188e86b68089190c", "718aa15407bea582e47710421ec160dd724f9905a088d83c7d240097501ca2b5", "edf900aa75dc112b7f2cdd5d3f272303a1c6fd0b7e2d89a2cfce1d01cf410206"}, +{ "971500", "dd461c00d3aa9922d31abdaa8679ae8bbd75b8aade9a7f9e0bdd0174bb81318e", "6d4cf414e86245695ca9ecb3a4bc3fb9b5896f3348f4e9ba916daac9133d7916", "8297847fc9f28f3b713a386ee24bf660095dc195e891cc29ed91f68adc89b081"}, +{ "972000", "099e80a3f22cb61144d56175c2e423681e9d5fbcf8c82743af51019d0123b21a", "2ec23f05afd3c6f60376c4544414f84617c48f368b3c1a1b7b90b060fbd27018", "cb3805ca2213c239b20d2672cddcaa7c436c2b0926928a2ea3cdd482387168df"}, +{ "972500", "eb380990470813b19e97939e36bc7ec145ed5bb84a5c15a18f53d8c6c399f626", "b7f9eafe3239574d3c22e39a2d2a62b471b8a7ea59c8570b206fd2d67b23207d", "cb9fb936cf97d42acb845a2358b526a9692279b55591f876c22393094f1cf143"}, +{ "973000", "55ddd462f4830ae58cef001b80805828381fa6f01763551fe3bf41c47bd06e33", "48e54fb3fa548f31b6b8012129886ad14d438d0e6af6a05a82230ef00d80905d", "5f353708dea02d4fe10525399c823d4a027a07834457e02f86b31404ce12bc09"}, +{ "973500", "0a3ae4c2d5937527041e62d202f1f3eeb575062e464a3566f6e3d4e9811236ba", "5fdd512a86c7668309807bdb7146dcaefa13813bfe05f812935dbba0c7c04d62", "1c086557709d579b3773cfa821406e79327a0140967713b73241bff2a2a28d08"}, +{ "974000", "55e80cbd096b8eb1df3fc9fdc1a4db0685f135deef48c22236a3be1df8d075af", "69b5c8b41f2e5b28a329e3cb10293ba29312c252fd97e2a6e9257b2cc225354d", "dda002ddf0995fd3a122f864c5c55971d5590d465f019685337502e34540dabb"}, +{ "974500", "57983b1af96d8dca16423e30c6feb4451abb992c59eb7daac3aec47f0c10404d", "fab5f619f442fac58344026a8e3bffca1b547084e5aea670cd678ccf1e4f7be8", "a3859c46496083689d30027b40cac019d0daaf008145d6f168139dc7fc696bdd"}, +{ "975000", "789decbf3352b728ca2513866842487ccc080040c301c20e219a6169af17f8ad", "8cd8670e216d098ef817bc6f4ac83b0de623fabe5b0bdba2bd588c28b40b7b04", "bbb05c69cd49f0bcf5a87329c75f69efb90a91b5dc0ed931fa22d9b41992d3c0"}, +{ "975500", "e4955374301cd615e606fa045946f8e1b09dd05be8d4cb90ea334e1f0bb9b0bc", "73bfca0d4522e57aad1864c6659e0906da259865cac1fadc2d4c8aed47f23a12", "ae8b93c18324c8f49fa73de8bb19e75ea2c04eab0e8cbd71d591ededc819b2da"}, +{ "976000", "911ee9db7be3ef0f0932647a9ce131e21d7eef9ac7c3a40fb9da8f3d328a3313", "a2d82537257e03c3256edd144045b2767b844046c07dcb75122d4100830f7800", "b118c6acb7d2f8a04d82083a9f25d3f87e468a7d1d363a374bf652a3db866520"}, +{ "976500", "82038a79a9cb494206fba58cc2903270b915d0396a2b3d2dcfc00c5bffcdccec", "147ca1336392af0bc36504c629248081cc5abad35dda21a7c10be10d2850df55", "d68b8150120a191dd977d13674e572c072bcbb5f3d5a97b637247f3ab72dfcb0"}, +{ "977000", "92456a662c9047c73f7083d2cb6a9bbd7f484ec5eca845c3a23362dfc9387796", "9700bed9001c1f54a9193337b07715abc03c91d0da1da02bfba14cd22cf7bd6d", "9b33fc4f478d2671e7ce83519eb04b8d808abcd4121b0d58e9a4f06dbbff03ad"}, +{ "977500", "bf8914d9c6c6b33e67c47ff6100b7f026dc80f11cc6bbcdd91489f68887a68c1", "8093398e5a2f391a3ef245664e6222069167cdf90491f84e9899eec391e01f8e", "ecb680d03236b5ea5bcc4c8d5903285869d1d8ea7785169cf27af41e05c5b50e"}, +{ "978000", "b1d888e91bc2d0788175d1167c270dab6bb1257ba68bd0f8d1d57e19788a71ae", "cfb5b13f8abc2bfd9cbea92a9feccda90f4bdb96861e29d6824d6abf40088dee", "03321ac394dea33fc18f97735ab2498c0ec6cdbafbb174701a9a07f7dd48cfe5"}, +{ "978500", "6e5e3a0db764ba19342ffacc3343df6000afc4fd7ee8aef59ff7b6e933017eca", "6d5b50718e56fe6f6cfd3bc8a1c058b7c9cfbc7b6cb4701f1d2049e9401f5c7f", "d00f4ec5daaa22e9b41fb58b56c3fba59090027a0ebd111381266420fa4c3944"}, +{ "979000", "8ab1104fca85862d1df0ab6edb7d4a001962e612b427f7814b83a3e63a56ab39", "e8b74e9b60ace577954c8eb0504dbf1b8e5c0dc057d438554c156878d6924a11", "fc03ba57eba33fe7d66029fe72b9a52498a693ff39505a6eef822184e3b0bf55"}, +{ "979500", "4b5c03ed2fa33e96b1dd3be6646c65adb5bd35a3e70dcef17dc6eaef44f7512e", "1c899654861cf5a3f58d764f8cea03248806c5de89594eafd2a42d084c546be6", "cbb6af9ec044fdca6ecc012ae75ff33362a36cf379cf1de9faaf1c2843492fe5"}, +{ "980000", "d6dced594593bd65bdafe4f455f97c83aaaf195a195c327275d358517276cdc0", "cb73280ea478de4ba35c27fc544edca9f7ff6bb3a0c1a0b44c17452fc61f8a11", "c84997ccf6e5747a0bb3790f7cb8511294ac9d0194ef7e92882e604c5be0a4d1"}, +{ "980500", "a9b5fee48434bf6d6062d4c3f62403fe8882716af75891ee9de40c010ff4984a", "50c67a1f249e74da33887c715d827f8dadcae23627c3c01cc3c86e2cc332d3d9", "3f1cb64e6dc021b39e7faf2cd5cbcdffb17ca62fb55f27f513f09f80ae10cd4a"}, +{ "981000", "e49a842bf035c8ba0d6eeff766f7674df57bafba5bc8574c7ffd55a1918f4e07", "3352d7d0d6554aefd57951186ffd4a20906c4c9a562c1d85a911f8541e1f5833", "c33807c5bab23c467dafc31f61378ce37b29bd31ca9ca3f75eaf884de1be4bdb"}, +{ "981500", "f7563d6939461d13b3d2886ea0eeae55bfd5b70a2124fb1f99e3128b1aa57c41", "ede14ce9d15b6d7dd03bf87dd1d6f4358eef1de87edde1b4189b5a7006242895", "e2fe553357ac092e527000a26b54bcdbb8b9f5d97fa9760ca53a97d6a84fc35e"}, +{ "982000", "4bce72fa79b9a6cc3a049ee07f2b153aa5de690bdd9177c60b9129d0a3ec65ea", "790c73a90c7513fb9c6a2b0293739d8305807d61d8dd5d4ff607f8bfd385e96a", "39396dc395f66ca2ff0628a1898b7cde9f618ed8a62f78a853240563ebdc2ab7"}, +{ "982500", "77132e20fdc5fab30cf9b662a7f7f0e7cf54d1cb4d81367de088f28a594e8670", "2ee079db6a79f9348a2f6484b787092b71ed1bb4c1267d5a18eff8d4c321c14e", "b971f6a69e0bf347ee37171a52c622aea4594b876f55e0a5feef1d7339efddf5"}, +{ "983000", "fa83e50346e0ddfb583789e0e053b74ca5765a4240f99f02c80753b0664a2851", "9987f99ab0e62c8c49f5b8465f24689b780cc9c016f0c7094a489dd6724ba646", "158238bf3536cbb4d80dfccb792e65753254c2a912d4369e7c3c561a2508d447"}, +{ "983500", "4c65a2ebacb363949d2a461a6a7c0a2ef50e4318675f4f5c9e417fdccba4c8c6", "62e4e5b983d0546fed593a3012c6b7cfa0ff96ef28ccc455142618ac4c7fb0d0", "83bddf9dee3f3a2fad3355a2e96fa29cf44b3923633796e7679bf9fc0fea712c"}, +{ "984000", "15b16b66f736e2f12a9324bb45854c9f6b49dfc6b367f346e772eaf8ea49f14f", "46695fd3d752266cd9f1e6d529472996f8ba494f161a7194bbf05b1130e3a4ce", "ff43f975ce071a1ed4f4ddd5f0cd6903fd7ef1bc52910d12346d92aed2df010c"}, +{ "984500", "bd9c47bb23b50fd7e77822c377f78d7aea793eeb694484291b8901322642c7dc", "b8d50e9fb564090ff86cfb90867834e86bb23d4a1b9f03ba65b3729e78a85aa2", "8f48c1bb77cddba1c79fbffeae6b285cb02beec4a83dc652dd96e899f6f53aeb"}, +{ "985000", "215551bd7b382b243fba86059c241a3315ced3cb6eebcec5d64c731a9aa07d95", "f7bf9600e24bcacd6716ac7e79942f9f62f16b644aaa5bbfc2cf87b84a418494", "11a27d57a9f743be233736970ec505fe97d6b54689b9e7ec9d67f83494bf2e11"}, +{ "985500", "aed846fcf07535b706e65ae53577ac77f106d4d196aa5adcd04d81ee2159f6c2", "0c10ecc979a353ee4b5d050ec570f95c8199401598d09ff9009d0d7e03a7326a", "c44f23336baf563cc5d6fe96982e9b1ff10ea88cc5553682873b45a403d8db92"}, +{ "986000", "f273f50890e0f8125bd23c8ccbe22be64a280b6f293cbab62dd9e9482096a58f", "289913c0b5c8c8c34c66bbbc27b602060a274ce12463a0d94928b37cded39687", "4eea986addde925faac38e16e38b753ed03072b51649744f1e231faee489ba4e"}, +{ "986500", "bb2726763523d72fa76ae25415b8e5251d234caf180c1cbc46684d30ec96c1fe", "a6322ac39bd1cbb2d2a6cff84e25e3e310e4e51c7f78aca2c1828c443cfa42f7", "aaa5b0b41e877095f8ed5520b48b18ec2eabb6ddcaccac765e93d1cd19a409b8"}, +{ "987000", "eb16d2f4fd89294f684687a1fda4cef1d5d494324818c0c16b9e2b9669211c60", "a922d18fd438b0b631a45cc52f1b35192e101b890e35787f60676d5ee100a0f7", "62223de4e95a2037cc7789c5a78244a5e19f808b4e51c606ed93c2ca13416d25"}, +{ "987500", "d50c6155658a1707ecad02738b6557432513bf5ea78bf3a2e1cde78a3b672f91", "95b19f76982eda85133625b6b2d8ed6ec049533d9a8f015a7d8eeea85ebda3ce", "311c8d2774d702663337aef37b93c1d0872a6b97f0396d617dbdcde3fc31676a"}, +{ "988000", "8fae67f15c83e3f5ce559fa3be81c49b47ea2923be52f8fca6ea76432973a87f", "db354947189daf8324430538ebacff70a48b80bb9fbc80e640efe5a0032aed71", "d98ee08d71f3619599de36326036ef6871b0a8682a16cb8e3442d5672c371ff5"}, +{ "988500", "7c7b9d686c788f19718bc1bb0aa3add6d5071118fbf2a914d4447ec2867de02a", "f8360801e9268cc2ed86aa0ec2facf7d228bd891e0cb54a5ad7d4761797409a5", "ad90ede93f5f3b0d1dbfa2999e5fc38387a13fbec9639924488e06e28588cf0a"}, +{ "989000", "464836cbe95821ce2f4bf0ae1eb094b086d894130057e25703f109fd1f6932ab", "3e3682d443a12d532d27364e2f7b6a5edd53eb7236159d859c5fb4b60315af05", "6657ba0258dccdf0a18e0f1a9c00d8ee9ab04a245f489245739f953bff55ece1"}, +{ "989500", "29766a224c17b8de90c83325930b52e2b52ea23242192f7a3795120d43c6ceae", "6d1e2b7a6c886b98a131cecee608276d80903d9f230f2486a7eeb4b094bf13fe", "914a22d9a9c75e3a58d84e647b92254ea0e20316ecfae9a9fc008f4b9acc0a56"}, +{ "990000", "7a0d6f86cc9693e0a0ee0febca3b3f8116a2c1ca3e3f5478dc713b9c03f1286f", "77ac7bb4b87ce136b1e951aefa132fa8e70566b1aa83e2b41c7e51b50f7ce994", "d6092b1688cc0eae8bc30321e515588909de8bdbbf660ad9d88640936ef48419"}, +{ "990500", "2c605fb768a51433d5ff066d9e6736e991a806d3b387c873efe12b5edb30a967", "19bbe2a5c3b3d2416b9219cf5570841f143d71a0fc20e29382eb6cb07901707b", "4eed06211d950ffb7ee961e659fcdfa432c27255a08b03f0318b482205800285"}, +{ "991000", "13a48c504165faf127f177f7d4fe19e150c94f27e55747dffdeb035a9cd26c1e", "eb2aaa0eca1b723d685a29f82d8a802e81e53009b8f53d57f0c2d80aa5dd2c71", "4a2be43058338bab0472df815550ddcc91fe47215fd487d8eed8c0fa54da1c4d"}, +{ "991500", "d28753c20fc3c35531286a7c815604103662a182986e5f1e5f84e2437b49abcf", "7f0ad9f3223bd8989cac9836665da3878a14b6ab705495b626bab79a73ae3e92", "50b869e5f6dff40cd01214a3007802346924ca2d77871b76785f1c5687d7f5b9"}, +{ "992000", "86d7ea18c4c4d8ad086d71a384f12bf1cfac15ab847838aa2dd3dc2bec258f16", "b94aef8147f94f009f2ceefb00902ef16cb7bcd31acd16633162dbad61bdb282", "c9a821a330342d8ff2be0e177b2c903131359d0af900a81982674daf2f545869"}, +{ "992500", "e1b3cb464a21d2243d3577a87ffa8a5cf4f886ceda5c3b70e5142097b425fd46", "4c934f704aab283fa3ae0b18dff434bedcd7c549816fa1e1a4639b6252ffdf4d", "c7fb0a4e7acbfa3f98f20a143cd49469577cda8968a06d094fa41010faf5e1b3"}, +{ "993000", "88a8e95ccbef1cf83a82690b89c170722120394b01ea641001a35379ca8bbae6", "fca6247b8ee3dcb01af1aa29846486eca0092ca90bc14274d16d29c823abc081", "155947c3a9d25af71c26e52dc2b3a599d12f029aaa990335a5a5dd6e5788dc1d"}, +{ "993500", "c34e2bcb4c7ead30c306385655a8202de556ef19ced40c59aa14c0efac91e2ba", "796047ec552f3417fbda0bb7e8b47476652a831590572051ef810adce0b28f9e", "98cf236f8d3a23d8c6c1111eb2eb20ff080452bf3b9fe9689b3b9363ec39a770"}, +{ "994000", "d5298162e2923b179e6cbdd230cdcc57dbd74ee47f24b94467f61039eb9ea1f5", "4b23ad485cf4edb61c5db401a01488b7546d5c9ee52f2bd3d9152ecc35212b8e", "1d3efbcff1e39633e6b214f9c98c02185e3104bfcc32bd8a21e318994498a375"}, +{ "994500", "b0664adfbec0e115415ded1b9645a536b50ca6abbf6d4064fa0004b70fde8e6a", "e7c1d777900ebe2a77996f06d21877252817e02a565346e4d014b06c1a29767a", "f4a31f3384a9b9c47bab2e43b667e104c6b00ac9c108e7c523bdd75ae51958f7"}, +{ "995000", "e508ee8874d2bbe69aefc606873f503678aedf80f7d94f41d2f2c5dd03875cf4", "86d2b0cd16d25e2bffc226f79d7212271480febb960efbd50258fcc13096e179", "22e8674a9e44bd8e8903e6b3ce8aaf7e047d02b1a30bb87383d6833b2bb32d1a"}, +{ "995500", "a707c4371079cf705cd28106444573df7512088f6ddf94529d3ad23a7300293c", "d45f3c7e465894cbf6ade11bec71ce70dbaa476e9883264398651c58aadad749", "0cc797a364857eefb9d8c277b2d8797be8db1c7fa62a5cd53245b611f6d048ed"}, +{ "996000", "f7b87eb786f79e735e906e314053d44ca9e390f3e95ace03d9210540bf481ee9", "b97629b917bf0cf5d8fea9f1fc2e70c68b7dd5e26e7d9d46e39ab007e0d1da1b", "ac28bfa8f6b7579a819de912938d16a18c6a14559efaeb7dc1ef83d52e620444"}, +{ "996500", "b558b1cf6b6c8433c5800f23ae615142084f8f3d928a40e409f874aabbaca98e", "cced61b2eef93c36342b81a9d83762f622a6bd502c0cc7dd1c0682a4724742eb", "bce90a34adae9a39878fd3cfc9e5435730384e0b2fa9819bc9a2633fcb647eac"}, +{ "997000", "caaeb7a33c8889c80539ae6c7630467e1f9a63c7ad7e785b981a407da287a641", "670fffa544fc0473595daef1fabde40074c4f7044d4dc30693940beaeccfc389", "e6074a488e39ea5fe55b094d2d81d69df4f8345ab659c773b0e0ed6b2f2da9b1"}, +{ "997500", "8e34f4d6d0a279a37c8ba482b77251ad9f7fc96501553dab0680fcb22e6ede26", "302b33d0ad1a64fef2ef8930018ada4c3c5a78c1c73cb8000c0d7761e47ee10c", "335d19d5356567c6c95843110f969194ef4232b690d543e802a8f25d3e03e729"}, +{ "998000", "4d92ce92ad50fc20856ea205479db25276de24f146f131b15a84554d0aa6f9af", "3a0b07fc0edc28355ff8d43ea3394e609fef61e0452c1a6dea2ddf15c0ded10d", "8bca7a9c18f2762ceb021f3f53f6490e33468e27a31cf4533e5b5f3cea802bb3"}, +{ "998500", "9fa48484cb1aac18acaf940acefb7e016a01f2758bea1ebce66a20ce4f035bf9", "d46c0a9835b479ae3f11573929492f282a89d3cd81de832bfbf621c1f447f4df", "221d1d90f07fda3aa7c8e95da56284796600476a866316905991083187df30cf"}, +{ "999000", "ffc5bce237b717abe7ce11f385387313ecc2aa4696c69619a5b4086a53ee3271", "ff9b6e5ab60a595494e3acef825047568620b1c43e8e6113142603e7b0350082", "116c978b4824176655fc3128846b3b28df9290434a2920370a4fde4ea5166813"}, +{ "999500", "6fcd2218fbb6bb99a7ab3ee9907cb2d91332f8050a43f540dd1b927ea7406d06", "125f37d51d86d8fd684971d3ddf14658459571bd6d21d87a2b8a29aa79946ae9", "87e1efa60065b9e9656bc24787b28043c1070748c997f283a9f04f9209047f33"}, +{ "1000000", "0eab5112b99ed6e8cf660a001c42d98c8080cb6366c7097eea2ff77dc1609f37", "acb74f062691fcec64ec6ed73d0a383fa41a034d58367c8622fec495427df074", "bbd3c4e736e39dcec4064fc9f486826379d79ed954c19359e18add4351492c91"}, +{ "1000500", "d1def6c86921155cf5563b6f8c4ce542cdd4fdf9754d4000dbacadf94048ae82", "6f7bd3d0026433254bb0ec777cc7ada57e9f10918a0a422dacb183d2c35ef820", "ed39141222abf2e2c4760fa9aa1918da3433f32f5a234d7d5bb2e8f7c2f39cc7"}, +{ "1001000", "895076795aca0adde7b87924fa062ba68e78c47288b2bb85f00e7e4d49db4b26", "688a346250fe2ba536b9825274d23fe3ab45f80bdd79adb081f2e94982a5e4ab", "0ec7a8295aa452c6ad63eb016f1a1574e29f733a03cc0150bff3f7d7508f3ade"}, +{ "1001500", "5c22477fdd5bd95bd2d21c677164d7f5f0af91b4e57c40d3a4455a84bec21e57", "5ad71bdbeee74ce1a181a3ae5e6369ee464104bc12fd976ceb5f17c118829070", "aefd21dba77767131d6f6915420636d796b0ac24f6fdb8762c2cf24572d25924"}, +{ "1002000", "19c686c9af79a78c7cc99f40e01c1b6ef8e1a2fb2fa71be9534627a4d4f9a025", "658279857f203a5c1e707bf87d65c3395b687f8dd865831d892ecb7cdc8779b1", "5c2450dcb64d2b8a125db556cceb9b5ed77a1ca3a30b2c20664f09406cd8b4fe"}, +{ "1002500", "6d44ea79ca8224f60c6e406dfe9c7b459b253173288fb27fd53f2459be869fe1", "4d4cf2b50e60efd3830b0e19de7109bfcca8ef40807d483e32260b1a85a2ef9d", "5b13f594e0b2a6ca92994eed708582f53d9ada9f61e9198bed811e435e68fc2c"}, +{ "1003000", "e5b417ad3beff6e4f8864ea986901adc70cb998335784643accb38300ba26f33", "f947088aa2b8ce56cc93358c4049c034128ca2f3e67330d0881ebf49e0748f11", "5802e8c75cdd661f92146dbd83df5409cc9d537f584c8c75d2f5bd1d14e49435"}, +{ "1003500", "da0ed4a993783299c429b78e8702b1dc731cb587a331106925a410112ee6a241", "0f0c1c4ceffb15f8a875034287aabb36c185962d010699ad1161ec4a82f98367", "0595982bf5c066b4b3702ef403a8528a86b0b4780f4b9e8384eeffcf84cfd5c7"}, +{ "1004000", "764ac91a87f912be6230e1b59065b818bed0579c6ecb1f96a17e7303de702b39", "2ab1ef7f085464ccc0245b130d84641be08b8fc885c1f15960ab72e486834cb5", "ec4e13722178845b613ff902bab5806d92ec355f5c05e195716b87d5970e5fa1"}, +{ "1004500", "bdb68fc38ebf22d68dc2a984407588ed9c452a7aee062317ed760140148b0db1", "49563018d17110ead9266c3efd001ac2c0965f31cb08ea8c69b9309a00e08822", "cad664604a8bdb4e86beddc02608ffe42a254744b1d4b5dabca93fabded857c3"}, +{ "1005000", "98dd7428557fcb55e93aacc5ce52d4685a9ff114e27777124371bfbb82856a18", "a429996bc47364fab997ca87316cc079a62290f061b8495b93a14fe24087c49d", "7f17f657146ce62fad541c45f668f193b94276025e6a04e6be7d866870ce14b0"}, +{ "1005500", "0a94bafc026c86b317b33f8cd2661d6494b8f9b01a6931d771505ebd80ef3314", "37566fb68bc84fa11fa17c73f90cbafa0ab29336a0ff0f98eefa590c7426869c", "1b237de8296a75ece190c887768b4f54a926792e26a7c89fce387804a3827f18"}, +{ "1006000", "db286315d07b3d4cc4de96bf6b344be65c9406c6186318e32d10fd8d66d5e3ee", "2f1984d31cf7ab600246083e52855afac8a6ff5bdf62badd04f6ec8c532dc5c8", "546af916a106c2231a05259f3327e1ab74dea2878c19292b1f9d3b26218a063f"}, +{ "1006500", "7ed79e53672acebe07b0a25853c34af6822ef69078c94de86137f16ef35a39e2", "1d503606be0bf1c476e7154c2d632489d9b0ee7f13138a1face4d411a0e6f9a9", "e65fc30f976eb4cb8025dccfea9aabc31294856e2c4d9abf26cee7dafb49d413"}, +{ "1007000", "98056fa1e52b11ee70eb294a962ef9288df96ea4ad8fc4a5166a58ffa67cf650", "a802403c8ffeedfb9de8a5fc863730e39a06c142b04b3b88b791f12b3340741c", "c3e8ab95102df395fc770a236e77676c0f6fc6fe34ea93c55cefb561a13d21cc"}, +{ "1007500", "037eea45d7e266fe26cf97846726facb73968441f3c3b0b8f384371335ca8b54", "f919c88493be76b460431acafe67adf6c2cf18ad72549b93f51934791b628c22", "de3565e0b9070742b491b3d3a67ebdc0952f730b6489fc63063e462b43032d97"}, +{ "1008000", "0ac8cae34eadd6a2b2b4f8c19dbe7b81b3bd432c7fa84a4635ed19c8109df8d1", "7859a5b85c491881a7bf6f3d0d5dd0c0dfe381e2d76295608ae4a2e12ad52f40", "85299c1a9cef6426c6d1644bedaba75c49db2fd764620ad1aae8c10f173ac37d"}, +{ "1008500", "903511e59fc4c13cef0ba01903a85ad56a60406abcc5804fe0021d1f364f35f4", "be8421e49bd2f3e64db5309ba30e8954d1cf68eb8ead03f5f820fa88bce8cb51", "06f71da713bb2705ce46479537db6a8761be15f49425a5013f475ce941ed8440"}, +{ "1009000", "0c4432de0745d517d1bd48fb5bccd988985d77628c45f9bff545834b63986ac8", "577c73b6278b78665f4315543688743a5c49ebe86f63f985e9e7989829030386", "c12a778e6262fbfd3a4fc18821371bede78924cc02bf047ac561c3e26ed6f3b2"}, +{ "1009500", "e8ad9cb3b8e542229367fc34627ec8e1f6e4847a37552ebe2bcbc36eb0c0d955", "5bab28311ec5b559f423c3e7980a1d55e5c0971682ea84ff9d6740ff9ad43195", "28339cac8ce5f3c0a9d7942aec12339e6d2b0859b8ab75da7c61be7b5281955c"}, +{ "1010000", "8c8b963aa26439dcf83d0a67799551fc5fa3b1fce2261db4374a913e50745184", "d3c41f512eb318d2fb9c76dd883dde048ea1bae997bafb4013950b582d79f780", "20267ef9a3ef52b03185ead600467e4da83c9f38e12b1a4506c171b00f02e0da"}, +{ "1010500", "f3bb272a4c6145fd3a142e85744d9838c7e1ea33388c5501b76f2bf3fb6f2021", "015a4e570fa61d5b9cb0d8404f237d56571600de80f4e9291fd69b5f981a52d5", "877442676c9f93153345c6e7f48af95effe054947b0ab611d053e252f7d4a046"}, +{ "1011000", "e99b3e7d03403da96fa17a760491b2e627324e6e40c99c6291ee2477325506d2", "59894713ba320d48c79325fedf70951bb8112781aa32679b55c49f6739d4549f", "b967907ae6fca462af16a9cbd31411e867699dba311409bb93dbb6aadc4d7df1"}, +{ "1011500", "624b57fa2f3c1be8a6df1d8d07162b6dcbfe4d5b5bab6ae76dab199518c997b5", "b9b72cce7e651a9beeb7a0af57e82dd1a11ff0fe4df6c7935bd67d10978b7b91", "bd0ff6fbdb52c282d8b3c3e0737fc6c51883d3ea77d630648b8d7b90ed54e995"}, +{ "1012000", "1b26bceffc486dad37b7b8ec5822a388cc5b24d884fc6463963f1bb432440981", "308612e9d27755371409af57a2e7bbb53d9432ff575aa742854b074c8ee6f237", "afb1196dcf4ca82ae70800e68f6f822c73be51068e7a650b23efc56273ab48a5"}, +{ "1012500", "1fe71ca40d446eef37d4c00d208ecf6f503e180e6f55c68dbb5fcb9e3d2eb746", "bb77811625dd920f9ca60331a354187ec62026d596a06f49bf6aae63ed72da2e", "e6ab2be9399acffd7fa0c63699ac1625d5a8c2be7a08cc67af77ee51ee54c642"}, +{ "1013000", "332859dc2b9962c6f20ba5af9d3093ee01d1e034e8c1b2defbd65e81154a7f6e", "de3d066931f8e54297a44e6e2d44fed5829456960c2f5aab427c460522dba461", "b166f455541bb19e0fb02c42c1d4932da389b8ca6177f690fe63e14329e61c4d"}, +{ "1013500", "0e4af0f0df0ec61fa3a5af0aec7c4b4987d876be19be280f8a3046c36bb39a5b", "c198a22e2903158000099fdac41933c8ab9e0690a84988691aeeb0e1d1b53904", "1db107ead91e75c67e0db283c3e88144d100ff191a64f6fc06b4e2338eb09c59"}, +{ "1014000", "1355b040605fa16e26640135a12f9ca9643a6ae6020b951f0150898d16b9afb2", "c3c21ef46afe97464537f553d7dbff58e4da1057936c6f19709e0aeccae2867c", "e015f4147b8eee74bbd26cdb18d17cf99fd65a6b2ff74d9fcdd29f28b73b4fd8"}, +{ "1014500", "d4600ab85513dc5bedd837d88720fc5b336b72f89fd571eda9004ad474d50630", "86f43b00faca5b4a65a815f9ac690263cc81af330cb0905aa9f50f4730c1bd64", "4e2f0a33340982fa9a725ec71a9b0ab676b0f765b22f80f0538c4d9c1e7737e9"}, +{ "1015000", "0a4789562092c0fe5fc900254fa79fcae07c862aaafae8b1f0506d3b7f7b5b7e", "976a0948697a861f02ff643aa4fd2ac3852b0f694ce3ea18e764e18abd8ceac6", "11fadd2f1d937abc4ea283d854c7a42e1ff717efe9b93f11c7d3a86bb92c79b3"}, +{ "1015500", "9288fd9c568b760f0038e65bd5d5bbf43bd1a5cef8b4e60dffb190c60a9bcdb8", "4c5e0a487721cd7bb588bb15ca20f610071dd4a96c0f9445fe37deb3af4b50f5", "31969127d7349880ed8012923c8511be4881e5843882fd49095364d577b13151"}, +{ "1016000", "a2c07ee8e03f8f4915f90146a752a637be7a64afdc7dca46a2213a0aad16efcb", "90df13acf7e85c2a43369b020626cc6a16d3909bce6c42116a584dd65d119c78", "1afb05112bc4e0006fc82dc1b04393b27f52dc57e85ce15d277b0abbc31561c1"}, +{ "1016500", "c6d0413da86d3ca6e27ec349e8ae3cc63b38c2dbd1b1efb4621852fc55264fb5", "7621412436df2d39de48cb0de98fde07ea39e7a191055f90f18cdb05c73db51f", "e4ffb5c5bc611832cae9ff659b49223f591c0431e73a0d9775b0bc3b740fc399"}, +{ "1017000", "dedb9981b4c85b114905c98692a951e73a0620094fc1ec65b584c8cedd18f0eb", "7fad3d8a58d19856c7a8928a8a7408a4174022b3fd6627be6c784c822c72e790", "cc519b1480c913cfc3c2e7708bdecc134af59db0a4e20fd2a431bb86df483f47"}, +{ "1017500", "34c9ed49379330dc3d1ca58f018ccafe3c706093b428a115a18661040767e145", "03e7ea37256d09c6b89b4790257a156030032361d9f850eb6c0976623330e5ea", "615c957d7d2ac1c25ba6735aa7856774b36e206f867f9fc81c09594e00103f4a"}, +{ "1018000", "994e4293d08d8da39b62facd7f3fb82ef95605a27acd3ea15e0da47a0bab0f60", "3648a62fbb596b4ad5a0c655baf9d30e5580e9fc76d5dcc9475e18bb374df4e9", "6ec66f7d4020d0ce5f17f6a65d9b450654300f17b9a8eb86cba9729c0251f348"}, +{ "1018500", "1dd630cd6391c44c85c78a99e80cbdd55e6f493d2d82181e103d839bac021a70", "a39f7fa1791b102d8927b847d9bbd2d04e10b6eee5881f55760fe2730a8c4807", "ed7a0150a145a9608fb11c3deb7ee88fa8a30a1423139e6f3e280cb1ef6a5089"}, +{ "1019000", "f7d9073afa8d925eb6f8123fb74a00f380f937b0bcf0ff7d95f1f5a42d12b7e5", "98467a98281be59593e2f92370868d35b36f2d59e46e8c82935c0f2f3b7a41cf", "07f67fe39f4150037f98e6c4bd29afed07313df161d151dd4a6a3bc90de4cab6"}, +{ "1019500", "67c86a37a72ecc42e218914342df752279a75c6116c931d6c6d36e458b423596", "cac3f08697af498999fca9c3669c5133f5f152fc71f76ff2f0849bd260772dc9", "f9ed9419820af0ec217a418b3ee8892e9841c41c20b074630407375f3d2f4286"}, +{ "1020000", "78531e7178c89f87b6b37624e82a60a0e6d6a81c7829de6bf0d96ced1d506487", "f32a845743c254db6b95911b171cc56e7a1e569a5b859c605083d8f3c5725779", "1b6b483b54f05f78269615e62bf42a833b2b746424a42e7a0ec7168ed6e10a31"}, +{ "1020500", "e97e743b51d2ca155fb58e64a9e5a9fd8b306d844275e6915e2a961bec41edf6", "96fba4d16e4722a99b3958d864b032fc55972bc5d2f781ccab23eb17be8bd9b2", "9ea7b6a72f8360983662e1cd6385b9e04666613e00f02e582755453375fb0709"}, +{ "1021000", "1c8dc672143d2b0665aaac012d8473eeffbc03593f2bff19e5cd300dc1e3c0d0", "ebde0b66d6d8203bff12f9c3d523b58be1375a8779a37f0026ed109770264e16", "08e426d787e7e8e00b3d401c3d2cdddcfaac80a24912d51c952113e8d34c37db"}, +{ "1021500", "19f4073201921beed8c8dcfea23064a5279d458be19dadc71f95d1e6860d2cf2", "11f8a235b0a37a24a410be6649c1d99593a14835c1e769fedd6d93fba376e0af", "b30df098ecd266f92db73267ef08eb8adca49eaad8902fb15b3004e91f6e9413"}, +{ "1022000", "55346f3b9ad9b8c5b6eaf87ad3e665911ef7e6e2087bc2cac9cf18bb5b47ecc7", "148ce0270dccc99dec7fbcd56e740dac0d2fdd9ecb28336d8f10f3f93e72e621", "d56058a67216694f08e09837bf205abdfb714a90a1b33f84c891d556b69eae71"}, +{ "1022500", "13b87f0b3bccd3df87720f8d1305fea62c7f99eac08518d6ca4ec73f884b48ed", "6a6820ecb56e7f823c3ad44889eef94e701c6ef730ef5bb1972630b1e0ff21c1", "926d457cb5f5038e3dcda645a4da52d2869ef4c89c010cb4ea923893869fa540"}, +{ "1023000", "424224c1ededff18483f53c1801022f74fac2fed58474f8199a1dbcdfcf0b826", "d359f2cbfd8363a46d3d603d1785b33e417d2077e48a3f36d7f6804b2c7f88f1", "2097837835e58ca3295ba57d8ae5363a123a56fda2647fc0c638fc509c28dfb1"}, +{ "1023500", "6125ef9aa4514113036ab2f8ff15916d14e2207d47d5e2370cb5b7cc474156b5", "548476c915898d2e9830d05f0ec53b514f7227f2e3028d6cc538d5c33e80dd98", "a85852b5acdc540209b4b7170ff509413e353a482e7284a2d63abf307a7f5bfc"}, +{ "1024000", "fd357daf81ed6c277315e15d1874b547cd65cc13bf826993edd19a54fb7aeeb1", "301c910cb3993c6803243b6222d23775662bdda07502844133e1723994324594", "16a4d5e08f85e9bba2f4e98a2437a9ba49f9bb5dfb5f63c0282f1b5f9bb815f3"}, +{ "1024500", "ae271907a6c47c94f7f7f2588e04428829cb37ad332d3239c71af1457f261628", "d970f8e09a2c7fd2ba1cad97bf3fb51faebb596245c5f55e1b851849e66e5bb9", "7abb1dec17399ebe7152d385679394bfaf8b98dd693196f1a0bd2ca19fb83eff"}, +{ "1025000", "bf22939da65542b923c5291432d07ea2bd2a00ff167cb9d41f85ac51fff85587", "5c8eb42b81967d7277a29176911d8199152c695f87711ce6400f2b8318b69c57", "649849663e1fa75f7106948758af23244bac416d35b4ced3fd2e7dd5690140bf"}, +{ "1025500", "21b3d481f19ec99cf0c341cd66b5cccbc1a7ed425ee7280ba90af9386d4e91f0", "41362f4ee0b965287c917e198e7e95c69f07270f1340fe18d01b6154623d97d8", "e178502e8afc4f21ee51c0da6f21827802c461eea56448d25f1404cbf42b82bd"}, +{ "1026000", "f23c5c093cc19bc5dea0ceddff5107c7ff15713677374411429abb78cac42a91", "0dac57c3e96e57a826ea4aacd642fec6948a6723ba07a58e276fb651bdcf352b", "bbb40616f0391f15647483fde7e59ee29e8626662f0aa9dc379506cec12703fa"}, +{ "1026500", "345cf11b4d563109b2015319b036395b2b12801125cf254e6f5b68c0a6cd70c2", "f0bc274a028bb81ebe15a9b71e864b875feba257ce6853841819303ced071e0a", "bccecec79419ab1fd7390b404836198ccb48a39dc207a77fd900617a757d7ec3"}, +{ "1027000", "acd07fc45909b03b24cd255627da907c89a851e3e381b717739d1263982401b7", "17dad78ba692050cb485aec760af2b2d9daad8d9f1486e32a382fb03c7fe855a", "c4b57139cc21eaa56ef7fb2f6f3642ee7890b34918661a28b617b2096fe9d6d6"}, +{ "1027500", "207bd5e690189f2bbf82846ba98c1a0b00e495245823c6159c102019c004a82c", "66af363746bdfa0318d1e2c47dbda7cd9d054924011a4fbdf9412fb010e1d4d6", "c16264a03c120a8b681a8f06f933d5f6aaf7c33895e83d0bdc082d1ef7e3a39c"}, +{ "1028000", "ed8104c58a22e33933a48881f4691046e2f27fa2968cae6b158fdc60f766c2cb", "b19ed2ab60fc83e97a2f41974620e63f86a702fec2bfa3ae616a07f3c8a66cd4", "0a7c3cd130fdf9c86b42778d121586c1692d31ba6f20b0b04dbb95801797d862"}, +{ "1028500", "a8ec00772093f07ccaced49ee9c6d884d6a9a99494f134e504124c013bfb1667", "4c460320c0683413394f0048a404ac14c85b08522c9f7e7c95ddc36be0737e93", "f506033026705682c94d8e44aebed0d207e050944d83f658fefa1df41bf14714"}, +{ "1029000", "072dc699a6b2732f3b5eede2e4609bf33421b562e69a06a68dec7410f8dc17dc", "e140cf4044f9775fb650fb52609438faff24023310a3c0ffc8b3a7e1aa5ef07a", "0549a9ab65210cffbc191bfa966b68410862049fa8414b5e87b00f85a6cc97b2"}, +{ "1029500", "1b91daa7a0be56efcd6ef7fc9abeeb20ec7e9e91b292e3841f8fd5904d9bb55a", "816a5d038097153d2c0b78130d93e905f9fa1aab0431ba050b3c2d0983c278d7", "7a3a0ed54f0f8df4ad2f4864b08ce812001bd9fbff6fd7bded5b1d582d13f2bc"}, +{ "1030000", "60c0681496f782c6d175671a609d285350517adcf1351b13c5993690101b211c", "98d79fedf73559704a2bc76c089dac5604ca5de734220992148b7419f8cf48b6", "d97446ac79f5b498bc81d03d6563b6696b0f5a4db11b3f8bf4d53e625ef228b5"}, +{ "1030500", "c7290f8c90153a075f2957e7479522dc8b16b70427da55f51e6aeba41c86dbc6", "82ac3d69040e6be1098fb05b4a50f88979b2518135024c0a129eeaa33e2a3024", "8c8ecf230f23fe7364f9dbfea6dceb042a65d4d2b000e1f5ab6f84fdc01a2553"}, +{ "1031000", "10d5f1e3d7ebe4c1e0ac25c126939110ac48a9b03d8d48a299fa356f802cf5c2", "2e2aebc460ba1bd99198559c4e3ad33b126b0e19a4dfb42c5eb35b6ecaa63737", "6245b05af1438876861c8e1775f8e135a021ae14adc7ee5d3c4ec8b30cebfd29"}, +{ "1031500", "36faab3bdc61f3100234c00b4b537295768c2d23815813d169ae2df6b4c0c769", "2f70b464e2c6a88cc966d392c0324e4dbfc50ed6a85f02f09cf14c2485f2f84e", "b189fb3e4cb7e86cd172866294cfbc4cb759bb8f350b8835a53ed7ebd419e6f6"}, +{ "1032000", "017ec62875e8d55eef392f0ef3b1807a184c872643ac98bd38ee650618b77b25", "0a3b5e3fccb43dba43fb467f8d0d07f8921629fb0976b929ca4da686983a2deb", "ab1e4677a28c6dd28026ec874949eb480dac7ae6bd6d9174974cb125d430a669"}, +{ "1032500", "99ff5e99a1b61800e956c385dc96e653e42d4a04a4793ad7ac502b518d5213ef", "e3eebf3aeb13c3f16888f9203037f931efcc0441dbc8ad833d275461417e0b5f", "e8356d391e5214499afeee845cc93f2b797280a8c0f398fea831edf5c4055149"}, +{ "1033000", "a92f1f7987e1e91d78a8c107fdf9ee32a1e5d6c05c95ec946c3e80c645e9c3ee", "528ca55f0fed1a23181382a79cd0018929612f84cbe0aa4954d28466c548f655", "7b58191d1e838bb06560bbf57f883a5dbbb0a82da83c2d80a2f77cfd30cea5a0"}, +{ "1033500", "030e3cd7b93b70312a5ec6cbaac9f567358078422f5b53c197cc86d2519ab70b", "cdcbf7bd8b051a4eab6b41f351cd6f9573b8a9ae7408b1ab633457ad9491826a", "b752605382827e7074e446aa45510fb7432771a1caf9b6122717fa7fe004d9d7"}, +{ "1034000", "d15e32207ebde3b7911ebb3db34ca537b2f1e15cb1657544b30d13829390a3ba", "efc04e7c16e0ed1fd15e5d8c9068b77361e03feab82ebe7d73e0240877bfae72", "8e618f8996635c8a7f62e323a584b9e33761d1025c887ff02e72119dedc270e8"}, +{ "1034500", "b9d7ff12e0b634c98dd84165b76639fc92b5c86cbf793d313f0fde5d203eb8a3", "57c20ce8035f48f0e305fc7e239f86f33d6382b558d68a65e1a72eaaee1e3087", "9c0eb7689751f5d0419e6735d941ea1c63d785c1fdc07e9b343df87344d86c95"}, +{ "1035000", "124827740a242e34f993652a37a666b497e2bef00ad5aa5f639458b50fd1c381", "65da591da847364ffed7cb9b7953149fbde437a06d60d5e694adbbfd146b5e23", "cc64df2f0d0cf33f8d087caf4b1ea8d0ee543e73acc36207b7dd62463d2f0f83"}, +{ "1035500", "a90b40499493a906b68e4741c5a551d45a74b6b88d77b74825dd7e86197eec87", "a6684dffc164991b841c09901bd468b1b6cb38796c71cc32358c2d7ed0c06609", "94966b59a95417fe1202430140605edf7647e6e35a911f5c821b1a420b897c04"}, +{ "1036000", "961b6558ea0c6f4a96f5020bd937b024e2315937044e94d7e99a833f15a9c0fb", "2d5a5c1effbd7f67d84478e7be64718beee3ef6a95f4e34b0c239cffcaebd36d", "b3b00b3c22c35d8edb15d7f19d9e6df6bbae05706d923ade6bb4b9f8d85f86e4"}, +{ "1036500", "ac05f9f0469f980206088273193f50cf74792c57a4a9bc3ce526b840080fcda7", "e93603305a5386d63734dc73f8df0c3a1e56da9d1fcdfca2960760f3d553d38a", "3b5965457c65f4fa96b141b2383c3e8ea95650ce5d20bb0ed60db681c909d9c6"}, +{ "1037000", "e8d461c77555c99a60f1a92922f6b3b702ead412bf65baea1085339d9286b53d", "1aaece9384d54cbc7640948f3fac7f5377cef6d87be8f523f5e45c8f9f10a5fb", "cefd2bc447ce665a2e2df4d5343ceb2ca3e95e2206efae2e871f8145c4cd76ef"}, +{ "1037500", "394e689b23cdeab65a232d4789befc80e13b946f2cb7513b6f4401c21f2cf34f", "b869eb6a9da7a0d2ea4f039a8cac963aac4157ac76c0bd1b6db0a2db19dc3a4c", "3f8ec545a75b6850d99530cf6fdefcb8bf6ab95d1eaa183b10ad58ce14293bae"}, +{ "1038000", "d4914856b50ec1c683af57b7ad17dedb0d6d496b1c3fd9e8ac44254f5097da80", "da3578419c83ca27aea9e5aded3f037ea1796130d12a7031b589ca9ffe5a5fb0", "982d02d1adfbafaaeef3ead73a8b760ef8cc4c18913aa2990df5578627e0c63f"}, +{ "1038500", "4ef9de168a9cdf6e4074492cd69b15621990a9b1a731154a27c1df6c6eaa2f93", "da919b8ccf4214f215cbfdf08bb7e568cc9329097d2275628cf7e870d8c1e9d3", "93617d68bab22ad289cde335ed90604618792bd53cb844254c861f8a0f1e38e2"}, +{ "1039000", "aabc1d300ccb7c5e20f99c58679d5801a86dfc53f489649a78d61d2780c1ed52", "740ebeb1c46972cff11c9c488dcedb4b03b1b26af5bf11fd2f455cd50be8453f", "886512ffb3b7ce603349d7ddca6f133e9de3b328f097b2a9b54933be8547e4b5"}, +{ "1039500", "1983a2e59f7e6248803264d5a3d5d5d215ae8532edfd5d532c3a87d5dff90aa6", "28ee7a4caf5585b7ecba4bce8b0a067927189f91264b6f61d40ed0ac070c4fea", "d36c42008a876af88c8756e4e1b81bbbd2967f15cfc97a9caf7e70f7b1c480b7"}, +{ "1040000", "f3e2a0b028e42ae82e49bb92ea4695af9e8086a42b0fdf4703674709442af77c", "766f9a2ab585a28d9fcc8a5b1a5ac73cce4a34a8c35ee49017ee1d005a2d5506", "415a4eef34189b66dd62945c61ecdddbc6617979b767027be748f1045c45929b"}, +{ "1040500", "5232a4ede825823ba1165ab340ef035a7283332854465224f7f46aec64bd1ead", "dd2390fd9549367fcef416b69e21b513cf2ea238588cd4e493b698ac0b588306", "c419f9db6f156969425a0e1a9a4412f7d3a1763f9e045a9e0a628ddf9cbb6852"}, +{ "1041000", "c35789e22c2cfa11323d5db2a608eae5f48439961d510bc279d1e6c2222e015a", "1a30dda49c5a3b1e8fc9c1b7e8c40e75ef527f13e83a398a41cbd3bed39c3a21", "652e2ffc28f71b7bf7d1fdeaa36a973cb7afa0e8ee3964a68df5bdca88444394"}, +{ "1041500", "fba66082cac0bd85aa39fe56c7e3f25b58098dcdf71ad064bc1293c6a5be326f", "9365e5fd1c055bf56fc73a599ccb8ad2d71c6c889da5d53a15ce287c9907efff", "130f197d253f4486061c8b344933d4e6b9888af946ebfe5bdfa0d66be7afaa75"}, +{ "1042000", "f960f144c580e372fbb20aebc7c7693e1647dde35631165f03ceca0402fd5394", "f309ff65eddf5e85b4ea098a6d47a0cbcfcd553aca7e5092af04df2660216ecb", "d7fcea9da8cc94742d3a5e0b39100433fe0ace25f448153aa6fbe9af7aab2f21"}, +{ "1042500", "bc1c318eb954e6ffd656b40aa2034aaa57510a47c70a26d4a64798b4242a96c3", "f49366d3c65adf67d855e79a8b5f321bd43e969beaf8da624aaa444153e34804", "1e1cab22f6b5519ae4265e0283f1079b2f209ce8c5288e9d2a247084e46a41ae"}, +{ "1043000", "8e675a672f934f13443b463b09308f9857256bc5535c144411f5af2df9cc7ed1", "320a8ccb3a1d44f07f16bf989a3348b980b2502e9dadbc1f7467779384e49ddc", "e2fb1c4a95ba177748c3732b0420eab1881b51fe2874b73e589cc7a08d565065"}, +{ "1043500", "cc6046ba969972c5af0389612e75d8b289c113b4900681a7b26a19ec120f95e8", "635b5848a1345f1cfe64bdd7d463d9cd09f9d075bfb2d04cfa805ece973dcdd3", "172d5cfd06424e6ecc06b0eaa4b441d4257c20ac8826f65b6cf20a2c57377b11"}, +{ "1044000", "df415157f07298c695d76b1ef2bd2ba6c6459dda30b6aac026a8492240163319", "1430ac6d0d2753b35eed3cbc8885cebe65214a9179480748ae5c3857bcaa72fe", "2d4b8f1a666c3f94f22ba93d18eca27b596ca5e66cdc3e7385c68fa151feffd5"}, +{ "1044500", "dcd1e4bf92385427fb83f6430ada423739f5e79b50d9d54d2da7682349099d4d", "a565daeed39c5a0623391382793c6436a274f39b859797088521d7ae5df1b7ce", "513aae8157476d212e99a19ca1c8e88008358b43434156e37053e69100e127bb"}, +{ "1045000", "579743f2d5aa7780e4db1b3015190a235ba6d5f4e5ebae8d00142032a3db5ce3", "310cd0259443ed2aad00773a3fe718fe05e30fa6a79be5d48600bd0dff0ea09f", "b7ecada86be2ad137b8e1f896dc2673f40b1e834e09351d6d40de96f32494ebb"}, +{ "1045500", "8a9aa0f90288d2ef021cd7bc0ff79e851b3027305f2ef6c90bcb67be1d2ca664", "01bc88af745ea0e33c5cf5d22cf1d6ca2cfba216e43b16fe090d7806b67da16d", "340015f88c93cf427fe0ecac9385c31f6be182d4f06007091144e44ac05624ae"}, +{ "1046000", "c72ccab7669a1c77adb96eac880c3b8b5505f76f54875c9ce63e5ec0a4466e52", "c5f2bf64430c0a2cf5b0ebee135d44a84b63dc5161e5b6e3bf22994c6a2448bd", "1f87c9f3afa87d527a897813ed828532601560b0b67e75e1fd040af0df8c7b18"}, +{ "1046500", "3573934e82012b7ba458286dc61fc094ebaea2e6a44b6f75c628c223610200e3", "0d902f09a9ca3b972e3820f74d83df311ba5b35e8c6fa1229ff8da974aec6e63", "f360249b4cdd69f59573d023c5faf8b0fc1e6a0f5f9967b96ac34659ee72ffef"}, +{ "1047000", "9380a4a18403d26d8ed097c1ee3c8d9deb40423a40c75ab5990088c7e5c6be5c", "175b7c5aa160a7cc32bb88a1623cf5c740cd1963c2d52c2e108005e2c895a4b8", "dfe7420133a6092210dfecaa74b30f29f0c980f74fd6205c0ad325b69d5cfe94"}, +{ "1047500", "b3eb44a8d8c32ff51230776ef692ae2df253ea590e3ce094021965a48b923a9c", "770af1fc30b4a95ac9afc82aef5959f9425d91fc27dea24aedc5f1d1bbbaae6d", "6f6dac8855fac467d526bf3b7fae68e33a594acffb42301e8cfbc7fe6838163d"}, +{ "1048000", "47a84fcee4a633f734f7197155fab73b0d6066752fee07ba18a3f1b2d2aff2bf", "ad93d2d3692df1b72ab9a4a0a306962127780d114e8ba39a8e102568906b61df", "adaf5605fc79d9153a915d37541d51b61fb849c9f0bbcba5164bcc1e930c9aa6"}, +{ "1048500", "d80b9eef45c8bcdcfe112f4f398aa4141888fb4bf69794b419757256f7b9bfb0", "c252f3198f625fe91d91dc5e3032446956d8de987b00d5d3ba008c3e092f6763", "8518048f6083c29fb1e001fbe778ed185b87a988dcbe0c61cfa868365939b562"}, +{ "1049000", "be562935777742d22230f2b13f1d885fcd3f3966af8baaf182673075aede0a9a", "7a8940e33f897394ee39c5f9edf0b04d71f28a3e07a65011496024b64a91a70b", "a90c364c7302fafc86ce15d51b08167f9232c44e2a7744a7a674508a146bf7e2"}, +{ "1049500", "450bc6a5f1b7d502c9a86ecb08ed3bf26c87149f6b6242deebf998ec1190dacb", "e496811cc6cab5c2b821d21ba29b71ca4256b228889e352e779a82aeea96df63", "64fd7f1d78833ec1260e9b39249e9957207845d99bab950ef921a3a5fafdda46"}, +{ "1050000", "a835e80973ca0240c06703a30433a139d200453a7296c24a22b62792d17ff2a1", "44c9a74b2ad97727ae4f419a77804a88f9a3cb31bb3ae65e2b372040c1eb273e", "95c578d836ef48bd93f58757d6c3b093acaa373f9654410f85dae1aefdd5d3fc"}, +{ "1050500", "631b74a56a6719158926aca09aa8ab8cd89b61e563a5b6386ec6de5e782e926a", "1e1c4fc04badc617cc382d6aadde8ae735277694e233a225634e2be077c97a2a", "fd4f6efdea193b035f4b5947404483b6930997bf8089d1661d9b9ef48c9887aa"}, +{ "1051000", "1ec8fcfb9b6d6c602e2775686f04f1d39a768064ee6aeb65930bfee5b1a94e19", "4f2f38f9f74bfd1ea8daf0ac5ffa8afb485436d5e4b35fd0742c454439b21488", "f6311a3834e71c30635c01e0c45aacfcb2241780e3aa13f2c834a84f5afda969"}, +{ "1051500", "73133e5c1408263f8053ed9a93ae7164dffc2381d3a7fa24cc78c29665b3bf39", "a47a6e2a98fef063017953ee09b4471622b986b7fe8dc6d52adda451db9c852e", "fb14519af510b672ace64d3d250549fad14d1ed623dd0544bc541b7e3710e38b"}, +{ "1052000", "20e08cce79f51cc9e5b0dd212f6cc3a0ad742244e58ce252600d286fe2415cc3", "edcb3b3a1aff133bac74770612727bf2f15cfafab7c63dfbfe6f2378debda004", "d47a434a2ba0524ee99b5664f66792b81fc9134f5ceb00e69efdf9a46f8142f4"}, +{ "1052500", "37e19650eba3eb3e2967c2585147cc37714d24ac681a8b78d11f946ceca3c083", "069c1246cc4290b4748b26b30446f3a7aae4ca9bd847d0f1be6a8dd07e89d52e", "dd01920c16ffd5ab35e7d670ff88cfc9bf348f0c85238643b8f04a2919978c7a"}, +{ "1053000", "8a22777c8f3ee2b71fc33926cde2363be651b56f4886962d9aebf6e111ef4af5", "2789aab47bf324a74e8ba9fe94951e5b3e8caa995f93f1c01a9e6f4e95783bc8", "0b4d50b5fc9dd327976276cce10c407e52b7fb70cf03d233ed3e88dcd1d8d4c1"}, +{ "1053500", "693b78182f2e9dfbf138a54fe519285ca8b5665dd630b9651d63010208cf1250", "efd0a291bdd8f0928a31f4083021b5daf1fc5de4f7b1ccdf70b2c7f62c80c5c9", "9800ab253ae43ff7d243ba35495517747e70d7da20a4a0d4691808ed669a95ca"}, +{ "1054000", "7d052ca1210218d7316d2d9b82c15e8e57d59ac3d444fdd45dbf5e577f9b4c69", "bee8ff913f9b231c0b34a55bf2381184d18389d43b1f6719227fd4d5c80d8b60", "fcd0429b0f95329e6c482907dad4a9e4733c8860c129ba977299d6dfbbe45cbe"}, +{ "1054500", "1b00ae5589d8eae631a21b715150b89a3786a33166cf0fb11e79f1c12b493e5b", "f8d95559f470788377237801e29369ebdd9b682ac289e43fc18ccb751ecbe29a", "1d1b84b14c6aead094be828f14e8d90bb451216f84ce7c325641b3277276ba7d"}, +{ "1055000", "6c92f01ed8c5f4247722230e045ae10ba6973c3f8d8ad66684852efdfd801234", "59fb8eb1e18d1ed445f7378eacd8b02e92698d99c1ac4d1544e35d127134424e", "527e64783b51c20f17908f8d4a5222f837061f839e5a35effaee8625110d96b7"}, +{ "1055500", "655d624dd686c5c3f95a7e48687d3cc7f7e3623b02c1f8db8727e54186e16cef", "508f0be15eadc58ee080897002ad681fc2fd2f4bd4e175a319807626603ed601", "2a01b2336eb82c2d66c72dfa96f1bb4778d0a28b7c169c431a8030ffcb18056b"}, +{ "1056000", "af11656c7cb4f7ff056efc8255205feb3ea12f96da9ac416e33b034e93241e42", "a9d081e5eb78f1018e0a86b8c2c333989d375adb3f217df5ce8fe0dbcf84c5d4", "6e3b76382e6e42804f19c5552c36c46ea24829dc035c16b0a138254a2c192aab"}, +{ "1056500", "4f7ce26131a4923137977f716334a07a99d1fede466564c89aac75415eea0eb3", "6723f6345fe576dcac1c5ccb5390321e317408c7dc34c4ddca7a6ac83c577ca1", "1649fcd866bf63938016938d91a53248bf9a50db3fe7af3711beec8fc3ac573f"}, +{ "1057000", "1fbe16214e11324f46064f3754e3189dc4e57e9aafe221ea7fa45627f0db2f2d", "123d5e7d330c6dc7cf7a4b9efc6375736de9b6acd14e75205e72513a19e938de", "c7dc8a859791fb06bc5de694f4586affa038b1b065ceb3abec61ef4e27dd3c3f"}, +{ "1057500", "2c742e483d8a978656e28a4b574fcac3264f040a569e8e141fb3b5f0de9585c7", "301d401df39b752d5e5a7c3d11b8dc6f985b7f836a4f8e4a318631c45d6d4f6f", "eb5eea8f78367516258e9e79be1c491b84899dbd73b9469c862b115088f44e89"}, +}; diff --git a/iguana/confs/BTCD_hdrs.txt b/iguana/confs/BTCD_hdrs.txt index f455c5c1b..973411d29 100644 --- a/iguana/confs/BTCD_hdrs.txt +++ b/iguana/confs/BTCD_hdrs.txt @@ -1,1772 +1,2080 @@ -885001 -0 0000044966f40703b516c5af180582d53f783bfd319bb045e2dc3e05ea695d46 a5d211145f8e6ba0920b2893d307c5d7c207ae0800a80955299678d1706ea8ac -500 000000000680a9a697eb71155b18a5827e0889fca28afb81fcbb46469ed7877e 79f80a8f54c6762d6408347c6dd7dfd2f8b8c191077c1d7881dfc5b7ec6a408e -1000 0000000000000cf908c887020f8970b7fe952f8b81164d83a87621dfdb581d08 3356ec4296ff2f04281492b0dedbaed80edeb6dd9170b87230ff79f6b0daade7 -1500 00000000000010e39eaa987e695caed67aa0f3c33576fd2621422c7c09152ca2 e9d31ec9f5dd4dc2688791edd4cd1abc964a7f843c59b948903c3492940e459a -2000 000000000000029e318c44be8a5e1d5bc8f7823907bad160aa63fd6121dd0ba0 15e2439021c4563c7eab5b91c916a0c9c24c3fb374b49ea24a4e2aec241ab099 -2500 0000000000000b813b136f623f85155cad3069031cde918b4079e907e1a9fd58 76ef339392ae45dbfeb2c6263e4e88b4cf888264d7ce8d0361258a81061fadb6 -3000 00000000000000e5ac27d3bb729f5c8a4312f69b28c9cefbb18b8fb55ee42c87 dee1d4ef373897e52847416837485706f5c0fe29245eccb0819ea5d32f594051 -3500 000000000000123b4e50db3f3706974f7e3593c2897bb545177d5c8a5a11fd35 75c65538d4fd33e5a77d5b9e5d756587f45a7cdf55646f1cd72f2da2b7ae5772 -4000 000000000000013e3c1513a7ffd71ba89d7440fcacef6bb39a76527815a71043 6ca70d4bd86a4dabdf5312a88a99aeb874d851df717879049d8d91b464109adc -4500 00000000000006e6d70e292394dd1f4aaf1ba3ea7313ae981a0b2f38ec4b0503 e97f1c03d9e0445a00c160c648d2f4920845502e788f5c3f2a5a392544e18d0f -5000 0000000000000278ac01346559ded91fc585defc88bbaa9d7f111b199e516779 45f12a1790418c3e9000bca11394719138f398232fd62ed3c801b5eb1e9199c5 -5500 0000000000000284e3d2455f09d9613ff71c49144823f882b003ed3177c1abab 149ab9c582053c69b64d9b3c3041f04527bcd47c572d600947d0f737d675f953 -6000 0000000000000bd43190ec79e54ba203c9387abcc8c1c03c52452a44466f24b9 ab0f1f81aaf4000295bec7b21ad5c272aecf7dee60c451bcbfafb0beddabd2be -6500 000000000000029e27c331ad9865fee87dd19e5ed0e526f9974510649616cc1b 9ee7b5e21984f8e3ceaa88aba5ab2d88dda10cf28c57b826e3bc8401d0bac0cd -7000 000000000000034bfd6bd049678a41563af84a9581d1ccaeb4952c954e327918 e09213923b66de743cf8edc0389ab1b6c07c0c79a175b3e93364ed73c2efeb69 -7500 00000000000003c5a246cab977e3f339041bc95aec5cddcc3d459d3d2cd546a7 4f26360f00347667d1c2f108ad3e2b2f599a599cb77b1ba9936988664ac53d4d -8000 34d2ddf9aa94d6e02224588d3d6585028a22f05f53529a19a202f41ceb36cefc 8bc3244b74f884ae355598fe0200a7f09bfab53de1b3e122020c4e2daf08fb63 -8500 87ddea52f5073e5283ecaf0efc637da3a47986396ad30b3adec8ea2ba5f6a09b 65ae81f7094626494fe8b984141c265f689f4d6abd33a3a74eb491c31c5d02eb -9000 000000000000016845387841c3d5a584d82763471d4b84af3921ee2832715e4e 11b2851886bc2208cd41c8381ff7bd6350379f6c0224f9608450fb0da56a59d0 -9500 e64e3a10f2daca17836d2bb5868e76290da1fd3e0574da496b06182033fc70ac 5d6ac130a3a5cbbf28cf389cda08aabe9cd5bd9a4da2d0ecd19c27d9ab2320fa -10000 00000000000001634bb95749a866092348aef266f9169c3ddbcf226d4807ba09 986b59e97d259c74881bec99d68adad8e219a0fcaaff6af3fa31b0b5a89e1b33 -10500 9a98c541a5e55bcfc8eb6d887d83dc6049a33381fe0aa3f4766006c1fb066905 3dc29b2469167c07aab94fcd87c03e0bad1a99d47c3594d80b700b05190eb526 -11000 54bafbe72c3547248f553615eacb2254fefe5a4d4cdcc66a2efde3e1ad9f3354 7113b80a2fd13692c85f39cf494ba0d30285981b4829caaa92b4b748df134346 -11500 9d6f0308699be5bed63c54a2518b7a69aa2e7f5076202ec077d3d53159b291e2 32f1b2236a56fbbfac8b1a72e3e3cfe24531bdb2c38c2619828d11c1474df677 -12000 00000000000000734778db2ce455744e1a50745ff4d10ad3d787e49c9c2913ba 712f312d18d3c817c33e522dc5b7b50b9a16c0dbac13e56ce817e8b6d7f75ccd -12500 00000000000001209c8fe742d1a45c5fa9689f8622217ace049fa3864ae24321 0c4bf64e0024dde945ddad558a13bb180d931ed8d6ca79c13112a154db415794 -13000 0000000000000064fade9e75fa24d1d1974f5ca69e84e8688ef0a58b9dd2dad2 b3411ebcf6385fb575beaac292c70d4e79686d832d6138ff3b68cac8fb8e96c4 -13500 000000000000012cdd1996be2f29e14c0654b11476e254e4ba4c6829c6887ac6 054f36fdd7e83ed836fa5c6ca63ee54929fe3549b45da07a1efd1cbfca73188f -14000 00000000000000b930521b5956b17943d5dcf001b4d319ba7157bd7fee6a6fa1 80ed5287e00bf627a20e525cacd1b6ebc2077a3e2c71a400bec64eb7b80046f5 -14500 225abc3eacd079cc0949cd8d0eb8978b5bb00720da7178ef5652e70754914d88 c87e7237cadf805554ab3f259bc89eecda51149fdff0ffb29925712a218f76f8 -15000 000000000000001f08d59b246a225efd70b813c3df8e468bc9d99d7d686fedc6 2ec038bb14816230448f041cae3a9ab64f4e237a53cdb0416dff8a2e062586b5 -15500 1181e59d86d7026c523659c152db3732c69e56a04ead32a0617be36ad3f2f0ad a2511b8ee2e0158dc668e0de527e71455b7245c01f41ad66e296118715aa33a5 -16000 0000000000000015155b08a0f074b1ae3c960bb90e96549a16d0b3eb20a4353a 05409419f76edb4ecdaba62aa65195063865344c93cfa1e35bd41931201830dd -16500 91d0e76a759d19aed57d2657cea4dbe861e849b57602a4c5c69028d24f795fb5 767a41f042292ccf2acdb0b91163b18dd6b59aae25ba60a8557a01f02a5db8d9 -17000 000000000000009f949c3d1a6eb1d50cbe5a3638acc49987902526df0d4c3eee dc090785300641d04d64f572fa7d645faa11c4677d74ff356bd8d51f50c0517a -17500 00000000000000376f6a1ca86680e16d0127507a1182507e502c6cb85cb6719d 89dd74d7a8b4f5ee127e7b4aebe54f4cb2c91c79fbc3045a59e5f94227ac6b12 -18000 a02b59af01d4fc762d8a5708b22be769b7ef651afa88ecada21eec58dfd53cdd 42abadc5ef27ee4c954518ed1a1e865a3b2bff3683baad8fb35589f8953ac5e4 -18500 00000000000000dc2e6182da1a35d916b98a4778fc35c50de27a770b9f63daeb 7a44c2603b3d31b23a607a40cd63f9ce9486a7a3de507bb26f6ad7c1e0e75466 -19000 00000000000000017207a368616b26632bf68e16984c098be64d2fb064d3a2dc 190ef6e670cda631380598333765702648c55bbc0c92d68d3c2bb5f76bc546d6 -19500 00000000000000ab3d7e8810b7ca9f8b61f630ec6e596ee105cbeffe80c41d4e 5bb4af1b5c912873e90a93c0d2c998b367768f05fa8650246bce8dd4e8b5f0a8 -20000 000000000000003adb97f0d6976b906982f3272ae0d656e1c593406b05bae17c fdf85ac01a396b796ee5dfdf3c7869dd3f7eac36a61bc7a30a5c7e8a9c5dea1e -20500 dabee81d7aeb87b59d94c497ebe1552b3f5a5ee1e366ce64143e9fa426a6462b 017e99080b6064d5f8852f6cda7563f8bf299dd15370a64ac74f89f22bb42220 -21000 7b549feae0c08f58c44ece421b89b0626d15547fd1199ff172704a51476e17a3 50e176972bbd1528d333c01501e05baf97876b8a51030cc3dced40c1bfd852fe -21500 4d7df2acdfee2592ee66f6498c2b0de972ca6e0c8e2ab38eb641dfbbce8aca04 e10aafa5c02a56181cc6ed4b48ddf1a52370d95c99678bcf5fc6a106df343bd2 -22000 1f2cd2094e85ba89286a183da2b9135d94b2be2c5b3f31bafe89ab3f631c5791 b97f1ff53a6a11d6ad3b0ff270ed2bcf70500069ab5651b8466110d472a1651b -22500 e797c4b4ed2720b494a3501a32a247f7acc38f526245ff89c8f148babbbf0cdf a5b1353f344534e8a9ef6365be58040355391297cde74c723c6a5465e39f727d -23000 50b9f76effc822c9f1051b1c0ce25bba6112a31d32a055520d84ca0f1fc39b8c e12e33c6b273416adbf598ccec93ce0dd6a3fc817c6f8e4753064e9ef78e89a2 -23500 fcf644a9930ec30bb933cc37061a17d0edc29bb16a04ea4bbf8b27444d442415 d5a23580de1505a7df77130fda147aa774abfa1f16468a55b542f69bb6199019 -24000 144f4d11b3a867d17560ef3ef04362efc715c89c30082882df0692a214cdbd75 add23a1feaf6ae651d6d322142bed5998f2d3345fc767082817ca86139d2de71 -24500 8d8fa5a290cae00be37053ee99cf2ae70b37b4806b41575a09b7a948545215eb ce758bf937c83d93671078985a70493b6bc1ab33e680143c6e93c2c5aa3674b6 -25000 b5c67f326ffd5481bdd18f140c03ac34a9d467bee8116c7a559a8777c688ee18 2e618ba056f201573ae6222928d56fc3321a3b16c32681dcba8c07587ce581b5 -25500 80d41cb90ce050cb9db84205aad00db5761a465b000b8b3a74bdf57e7bc272c4 fa5e727492c4a83fe816724e80c54ef2add090d60c3fdd788c44721b67331726 -26000 de58126ac82bebb58f841f75602b4307ceafa0d9aad7271567ec69d734b3422e 3931c58b417157cbfa4e990ceb75e8f2aaef945922962b671c17fc9076be9c7c -26500 857f050c1a4a323b2f9d808bf2da8e11a9d691517cb0189ed2f7f103794bcad1 a7ea3d0c368fe526c8a1a79c9ce3b5cba52634c324271b3982c70e2ec1698800 -27000 43b14fcd1424ed78b3cf03615ba16c8fdb53c414e894a6fe555b5a0221053ca9 6719c5530a1c6579dc00a6d6bc26c59900d5437d4bef8d03fc47cc018937a52e -27500 503b22cd2997d3ff79a7857530f975798fe48a3b46bad0a38a3f83653beb8d1a e013d7f398f337d83d758e6af4eec6ecce14d080ab95f037e8c4354b1e4265b3 -28000 85e03383bd64b7cde88467bfd7973ad219d635708a69f925316e958d524c1b2a 112902560ea7fe15351297834affe49c0a8e768b587d1a8e6574ae89903d8143 -28500 57c1ce655a20e5d4639e934776edbbc5ad099c383b62c7bfc623368a2c3368a0 c3e03e5754ed76153656787b565a0143d538298277c55ac0ca79e99b0ea134ff -29000 d9963c1d22e68c2492bef7a33f34bb7bda7b326b4256104ac1ef7d6421862c5b 91dce271c5fcec2b60e9e9a7d1670f191be7f8e76d3d13e75eecbad77dce8173 -29500 43f543efd477664f84ee78bac095d5413449e552ef90204f79bb8463ecbd5e89 4e93e04161f98d745707c6c7a85bd4b223f124c6dad64aa7080dc612526329f3 -30000 23da6267be7a1511a4f9892875bd61bc1ae5d1b35063d78a7a448379db07c40d 760c525285ec0731ff71deed949476248fde392c8bb15f100af786b7d7e60642 -30500 199d170a784a96d70fd6421057653141b423cb730e577bbe490c4d9d5b31621c f836756815de2b187d68e2729bc667522ac6f00379759c5a7815c728d52fdd6b -31000 a2f6774be3decd68c4fc0d55249a61d73333358b03a5d7f48f19ff53c6eca193 a72c7c5328570231dfa7e3b7fb68ed42e4b4f9f4e05505ea4526779d279b6045 -31500 ead2b784815b474f24a12e57068086c7cd2b59051e4570eb4eff43c00079120a cdfb920e73fa2ab6278a84292a23123bc921782c7b9648c137ea3b5d936838a8 -32000 51690f90531b33b61489e34c805c7d1235708691163d0b25a9afe161b5bde918 44ba77a723c883778528e872d4cc6779c6485e4274ceb2ee7c1f219274c74297 -32500 b8f881e8f20864ef1db26eccd81bc46ce2b5dff8359ab86cc0b915bd6d1437e9 f390ac467135ddb1d88617c29db574c34ee51a4a79cf041bf7444c522229f8f5 -33000 8c8c61289e79ec3e22d294ab824743c29194740fca09ab44d460291599a33186 24bf35eb0ef662470b75fe38c332729ec8cdfa122a52be3d81a97bb9cad009d5 -33500 958755e9cf4e957d0471cfbeec0913140759fb3219aa74096c26cba2536579ae e88ae01956031b06310eb260b95a76e2e4e9b66d40df56300ecf108cb4579c4f -34000 d4effcfa7746bab24f9c3d12bf94680770ecc8405b5b0a17bfd0b33c2f4f475c 9e5f3f87097c229ec5011c8ce05cc12a81dfd166741ad2762a0f156a8d3b3928 -34500 7f971e1a0d2e94dd8cd0ccabc451fef38429ddbf2400bd45278fe000210d5f87 8b08d83e6bebcb12ae7b2b9fc1de91a0566ed33f2c40125d7810e2a97566a28a -35000 90e4d16dd67369b4b5795571fe0cfe63be8c1796ecf5870cad20798a752d92f2 619428a018aadf7a144b3981ecf018bfffa7975819a58cfc0e16f9ef0ba274e9 -35500 03aad5e354d5019e2cecb5a44c4ab79c7120543370cce9830b1d41590a59706b d94a9fa2f0ef62b409348c56bc376733e50fcab89ecd7fe711845f66c03a8409 -36000 5659c47e9c1b006ddb991b7b0163777977d04d70b4b52f4e3b87bc3aae6fba2c b1cb79822ef346bdfbcaacb59b7a289bd07b5cc02c8c6f9c9b1c5d27111c892b -36500 166c22d2278b5d4960af665a6dcb8c4718ca3c489fb12f6744a60337a6ea4a97 b55d2820c96584bb049d4f57766a2fb7b21ac2998038d1dad3c39dd553309a5d -37000 0c73b35172fd5a08dad4570ade1ae552008a801be8f2df85e52ae71957cc8bf1 66fceda7365584ca4e28a192d4716cd0bc61da166e5c6036bd2dad1ba0f034f2 -37500 e25729880903dd4f6562deb2c3e076c00d29e08e9c531518b2920b3e747ba6ce 886750b60b53c72b8d9bd1cf744d74fd3947ea62b878fd186618a46f1ae114af -38000 fd1aa8f0791fca7ab540a37b8fe5a6a23a84d0bf372ee35d6b12fe540b53f746 3bb81e40ce808ad93fd0057fe4c8c111478857f8ee143a27383a4d64f7c9cce7 -38500 73dc7035d76f11e288a04b87036996efbce8dc6233d00a1238f40ccd95a4ddc2 b8f0d99842fa481e5b0e6011ddd8abed25c9073b259e37ee7bf2f451d4ad2c92 -39000 f0e3715e1a7b82521f8d39fb490f261c5b8684008f5b52fbca7e5f7b204ddecb 2851428725cdcc924d42f907200a50ec708342cc1025ad035dbd7f84c0818340 -39500 16693e3a20a6c2d2d823b7c3020af1a20d555401ab098f94ea8a83b7a2a9af4c 400ac0ebe9428f526123f90c8bccf69a6835ad322affdfcfda314ea795e1a1b1 -40000 fbe5242823fe378d36335366cf45b3309e8fad0df3f9dd542e10eab3b7a296fb f73a533f1c917595a88ca8058bcf54b2d8e3c8cf8c46a165c84ef124fb07d15f -40500 448e82eebd5d00a7ed11123f43f8ee955790cab17cfad0fb4f1ba154b20cd1d4 f6c092a7945bdf4ce8bbb08645a349b208b054925376821f469309fcf46cb4de -41000 42e29e0fc3e8fb2c517bf4b7d24175f7467980d793bb18d4b1903fec0292d0a0 b8d88a3f3968b88b98e51232a0304506821c7c83f405515d2acf89a6a39a7048 -41500 fce90b09826a8120907462a95aef4b8dd9487efa4b0b2cb7e90a4d6d3d40e4a8 2a4319200375bf38a272bba432cb62054c4863db024e4a30c5bd20bdd569b939 -42000 f0815d389fe88bfbf5c361762efc5bd1264dd9256bf895b8dc6f39128e130154 b26d951f8be8ab9091f1e6c56a539d1d7a01b50c265ae1c025b698f3edde5b6c -42500 97171a32bd838c19f12586fb03992387b4b4c8d1342a0ddf3397e44b7c9b432a 04737e3fefb938c73100a32ccea93455aa0a564e41e608a1772ffdd2e0d10033 -43000 a1ae4df09a7e3f060a6693d9bd75af599a658f501b0a5583442aed2bd0393dff b6290ff23b70623802b15c12dfe3e19111ce081bedd2f24a0c6b4ead9d8989ba -43500 85e2d7b7fda1433ec964d4ea6cb4fa7af661d38f761877bb9b0aa0acead5e437 8dcd8aa4dd692a271a4e6efe7b8314f2fc5adc4b96bdd932e2ffe76b496f1347 -44000 7526450969b0254a66686dd28d61c10d0bffafd0bbb623d0ac71f6c45048b195 7c626106e228c853ba6d6c9d63f934e51661ebd7ecaa02d66608bc2f1da0877e -44500 313c4a7250c92bf888dbbbe977f119854876d877cd7ebad97da3e793e4167084 e1da8d161f08c6e7cbff74ccfcb80644b571747988ada991c4982625e59d1a0b -45000 9fde3334234a707dee9c6a2e3ef6069a30c0bb4293555f59ac70ec398c818e94 987db78e383fd57efd0a1b0b0b8fe38c50dbcd648da9a1eaf5d5f59d0c15235d -45500 30f5524584e0e3016ea738b1984cc7fdbac63956d6a154ac474ff28c873eaf02 2a6909db1ed2d684bae8cacedac0453a13e37ef1485760b0ef6329228a71bccd -46000 b79943e9ccbd2513710f58b3a5ac822bdcd6f390afc8258ce7fa1ea6822daf2c 1db10c590ef1fb219c3b98c707fa294e263bf95a4ad26c2c214ebb19d4236297 -46500 9680afcbae2cdf4712605c9d592ddaeb87f9e8c522c6b5f0beb219e71de389b8 75ab5e40232ac575b25c0b892af025d5405aafe1f808551e7bd33abdca9a86cc -47000 1deba95895fa7fa09760b2b6f12395e6a40dc7ed3b14e629b7d85875e6913eda e735fd2aefe57540d02327e774c7069d08a3ec5b35e6ba939b1609d98a29a245 -47500 400b71a80cf5c7a408363c4a88a6f17b9fee56830f9639bf682cca7f6a1b9ef4 179f44d13af45605ea60c9fa6e0030b5de6c274104649283e5929abda3cabd0b -48000 b62fdb21ede8c1760346b4325be6d08852ea3944fb0adea0b408742977fe122a 8ff82f9540381a20ba68681f6e5442df8852cf38b2476d0a6bc61162d6eeabf3 -48500 baf6f61655d7a53726d313806841300c1d729f7206f62a267c1b4c351b365763 fde6fd7055e1f6e03b9d327b3c502fc02bac00738ae0fb079f128e2774d0078a -49000 854ab5b99aa89fc7d03f0b2d7f8a54aa7c98b23957520ebc8f4e6305902cf2cd f39213ce4a4fb7c2de3088ffcef3712113958562638395dcfda8ff6da621a09d -49500 c964b7057db84d6b9282baff7f2f09dd72fff06dec110201904bfc3846923bdc e2c15ad8f20ec681283af4d88c56e1433c9c20ccbd11e269ea267bbc2f9ebf1d -50000 fab7500f5f0b1694a9c65a4b02e84dff228af92fa447d810200a3b14c35242cb 194fd02a69a66e9293a06d354206757e2bc23484e3e8cd80522ff71feffbdff2 -50500 ed4e556f251680672e442c00cf6a48f3a787acc589ef3e83019851808ffd05a5 b51a4252fdbf12378dae10ac1c94690365e096f786feadb8e75cbad87c8f8a99 -51000 2410005ccfce88835da97372f39ba6708e7eb10f97a4428ba2cd51e8ee87f7dc 64e4a8d5a545ffb1af7a5dc66be6ff2aa517a99c7bc5d7b2d1d1afafc1b93a84 -51500 ae13af1cc26f53deaa57482111239bd24f99814dae1e01580a1957f11aa49a63 4a0c54d391ad8bdc303e226fa1aca24cce0ba24370424396bec9917804f0bce7 -52000 163e369cecd2362ecebef4717e206124e3bd47dd40104efcbbc8610fb48dbe46 3b68edeaf66e8bf1e1b187fc0a5e0424b6cc896661e2a4f44882cb060f9815f9 -52500 c3e5334bfa7c8d5d577b1a74df2deb553a006f68b384ebd44eb7bdd7aca3a297 fa5cd9249e7b39e2aef8bb19e83e214d77a45b4c67c4504522f94baeec2241f1 -53000 3a790689d0f51fe7dd6115b7f0e5f5265a3aeb912692596d2611050a17795705 23b602a52f2e393f2cedd9c8ea0597931f6abd7b4f4f1d85f1de8d6382c03ec4 -53500 70a1da282b26b9dffe0b36a6dcdfc0c4bf218a86164adfbe7df4cc9c0b978969 f6ffbf0fc14817b41ce42831d14add2f8ec22307e5b6baaa9f07dad06c387e8c -54000 630d02d2f2a8889fe47a4c2235a60b2dfd31ca78e487860f59d24637a2032af3 901287c9cb47c082b5329f422d94e71def436bd0979e939e7def8c60f99272bd -54500 4943f865d3e75ddd060f8145558ec7f57c10d186b3bbd3d90377be4713e1fd22 26a8c618d328579faee0816d1d723736a249dda1e95647ce7775b0aae5b72854 -55000 6e96c77b0964fc2077455aaa2067110351212e2ca707fda778c963fbbddc844c 350612a0426a630a0b001ec51d875e2d1c87d20353a480539e5fddf91cb3097c -55500 cd718716c94cebd61eafac70f8562db8b48735765a8613aec79d901e0c5a05e6 234209073d425564622dfa5268e7f2af5aac71a18e2b15d23ceff1da4d876563 -56000 04002106ca4da32c5c7889c8f17369d23a35bce62a8196477c8f8e0e0dbe4efc ac25f2042536f1a588ac6747b2ff3b45de9aed063b096ea59632b3aa45441ddd -56500 6460fc580380db980f3b76e9480b2dd98f4fec5c9642b211f7258f50575522c3 12c289cc82037f732305d895742cb703eaa35a4656faf84c6f7dd9a2783cd2a9 -57000 7f1a59ac62a06df2d3d82226e03a1081fa9a8c72c5333ba485565f9215423362 5363e6896a5eac3c62543b82b6260a18b07597b5963d038e728a9508ab55b181 -57500 88bf14d568f5b9d8e88d27a92f2aa97a569f371850be3d6d1ec175fd9e1dee54 56aa31dfeccbed31839cc2399397a826f2e64a16c4fd309ba87ebb2ae7e7f695 -58000 0ab0e582e675d0ead1173cd65e71157f13841b22560251a2aace14ca86fd66f2 bb20d53b616962e78610b02a60785252e90c54d78f33a3578172cde77075a776 -58500 637d24d3f5e56f5481735d0853d74cc85c170dc95dba4eb733af11ec3ff048d4 aa8d5505be6a30af2a0292fcd19800b0744acd87634bc49ce43b0d767117a5cb -59000 2d88b4676741afa7b183502fffd15bb1580f81b4b8631844be86bacaeec0524b fe841a70acbed4f52a83b35cf30c0cd5ad38b36b21b24da1a0ead110f5e7b2fa -59500 e5b98e82ea2968293969b1da31bbb8e30dec3ab5cf10308d4a979e3264513bff 17429be3ddc868c9e3662b5aa6223340d57b7284138db428c725c8fe69e1f89d -60000 98764fcdc2a2f8a740a4a1c891ad966b44062f64195effad2ba0aa4bb9c4370b 55053a4d083f019f602ca159faef86ddf421c4c4c3bcef9f0849f45e1f8c1c44 -60500 24bdb847b0ae121363eb0d2a7ab69d672627b4d68195fee18df5ab5c076ba3ed be197241a0c377fa6982b5c24af043034024f889cd3ebe42d4a9b3fa5dd18953 -61000 54222686316d912f144e6d0bbaee1b3fa50549e9da65ffc21b04c5beb3ec6daf 6c5a388a8dd7f9d104377e1f5b2817b50f9269145da48dd0d71f48e2af8b8731 -61500 f14bee1d7d3830f8c316f448ca36fd0591371a63fb9d04596c657051ab4c2ff8 86c9232b738073c671adec011771072c92ed0616c361bcb6e9af6074d09bd6ff -62000 5903eccbe3d0442fabf30748705e88e9cd83128a0bbfbef66841f590b5011bdc 4de78ca5e16fc438337a8d5f7aefd2cbbc66790d019a1bbc5de082a79e39c303 -62500 35db59c0b059705518e07b3beab25716c9fa347a1fdf7bfa0089d011e2586419 961e208bd356ecb07f838ec1d1cba0eddd79d5e026ae350f0945cc321dec970c -63000 5fb6db58962ea9eabcc50dde4f473a0adf58eb9a409665d57cea3b2d3d2f44ea b673d848fb79ad142be92514c27dad64fbf98d26e1e4f5957376bcb2f8542288 -63500 92e31a33e15bb677aed01f2ed669a2700223a34fa7342270275561ed5b88eac7 7932d5bdbb9c2fd7f172a79a9e93f73aa3703c284afa98e7530ea4ebbb4ce7fa -64000 065c7297e545fd1739d04c6ed41da4a82a24404c7b3573bbacca0c266c4cb716 912632c93e91f5f539b2f9d6ff8b16a1817c8eca88b6d579dab56bf4d48eb31f -64500 a011434ee029b50acdd49262a91b0767a897a5dfa7f5c22dda0a32aca9ff334a 37993dc2223b292109f02e9eda7db4178f6602aae957b80eee7cf94dfdcbf020 -65000 5144e900145e481fb1e569b1b522143348a38052d35452dc7d97e2140b812e26 217530b550c589b0de7d145fc8b1059215bf5c124be7e79b5854acc200b511a0 -65500 6db49e04b2c1ed108caba28d4de98628fc786f5224b098de1636a697ddbd6e6c 5cc92190d39119982836cd5b0759902c4c61517aebaba16e6515cfca53bbcba2 -66000 559d2603be7835ec386467221e23836803606f7fcd7068f6a42ac5054e48fe88 68c9698e2684c3375d6b4d83b33155e15ff1d50aaa0fe61276a854f7c022e3c5 -66500 d724f78b706b6a58400a729586b050fcbe843a3e632376f24db6fd4cb9a44177 968a75dc8e7e9128b5e7e00b22a78fb53553102b54247bf644247546a9db85e3 -67000 8ddfa37cf395f7b4b8d6d09e29cb7f11e7d06f929d7ce7a77ced27c79011235b 9cba1d323704f1b566fe4b639737ca2f6f96ab6f9f1373d95e1d8cfef0a0a1fd -67500 2c5e2421936073eb47199fb03dc0023bf42572f507f484fd9181eb1a862e8972 4928ddef10d983dccfdbcce08743afe2a0d1238fd84bb4b6e1781ca7847d6ff7 -68000 cf49fb97e127593bcf3591390401803095f71ea86922369e573b1c6bf59ca692 accdaba238ebdebdf85fcb74a46d17e5c29a996e3f1be6147a3f6027a13c8412 -68500 eb68bd36c8212efaa20bcc2d1c17f17af6ce65b060ca7ef80dec2f44052defcf e04d8a45c474fb6ab8071cadd8fb14f5d208472089f6a22ff5c04904f7a01d55 -69000 03609399659eacd9b55c608e6f35195530a35358812bed13782f9d5df5da1ebe cf4d7449a4a7aebba820fc84f3dca2a48ada14feda094a425833d4a5aec834aa -69500 1d23b15a2484a71d270170f32918f36fb87e80cf4020f6a3e6d61907276fb3a5 2a218f285edae9995b3334352864684c66f4a919c92031ee3b24510b568f6246 -70000 5667dd2604c90cb15f49a75456b0bcc2a0098bc025592d48379f4360844b79c5 1b6966e82886048d64879d2b76663fd70689c7dee808cb42352f57af598f9bca -70500 745715d010b5ab51456342b8772a53b95ef0cd409980df39c443531f2f6c2346 a1ca05cd11e6f3d9eb2f0498b8a4743defe546c7602c3fe06642f0226cd22719 -71000 c622f3d2de9a6aa2d649f10532164082ff6ac21da796b037f2b2a210fd2910ad 3c24535ccd8328940b86980f1797d0c4e0dd0fed2ada72a0d9ce7927f4e3b040 -71500 c4350561b063c19326afb0b38b7aa70a65a928ecbe3a545f26f1dfba40d16599 7167266f09bc1b259fc6dc6ddd1c4e03514e4b4e5a985ce79cc320d80f376e9b -72000 df857691f4e2d2ad6a7de6a3fd77cd3e1ee19be220f7f92006e30c4cab62eb8a 1e962f15a4472d511bc049be123041f357376d95df56677c32ebf69640fa5459 -72500 affa0299a9d64d61176179cb14978c6dfd116b0350638b5e2633c5a73bb9e5ba b04e559b1ff6d04f2fdd2693c384bc89f05ee28f5ba8cee49cd057c575b0acf4 -73000 a50964b3523aaffcbcfd0be0a6fda32ceb87018450ad2ff81f1ba61de5fa20b7 e3301d1249deb8b1065c59ddf02c4480af9208ca0fe70f0b94f7135e3baed857 -73500 629acc1dd038725bbad7598fc49a7178771332ca4f12372248da579ee5dbbe54 8d2425646be01e20cf3554feec43cb91bdd92f0a6e8791c7f8fac4d21767b45e -74000 068954a253aa54239a0a4169f50ee7d37b0b5bdfcdfe9719ce9921a5917715eb 722bb617216427a0cbbaa037d1234bb7d6765707108aaf171cbe14e24392a8d0 -74500 e688640c22b3c55fdd29e86a159e1cb665cb0937cd6a5591730a1b5de7c04b76 4ed22bf35c9c19ccb01db47714af7f2ed0a7d2506f40a5e43b92b971edf62250 -75000 31c015b503c6830b93948a51598beefedc78d8957af82aca6ccedb2aa592de8c b75f99a073680d704089e1a77cca65d027722aee3a4fd7c1f9578b535150d5e6 -75500 3eb906d2939c3f6ad815a51421f488025326b8cbdbe28c15ef32ba410b7b8ab4 39ed4ea10fdb97d192dc03a86a397b24f6883439e7ff6e82d9e6738cb90ed5d0 -76000 d21f08b186c4d763e03ff71b1ae4e7c07a9dbd30c518242740c2c93119d8d96d 3898b748f911a413cf66daf2e319b3e72ad25ceddb77f56a7de9165484405cd1 -76500 5c8f54cbdc2f5f83621da3e57c28d8e19faca81a438cb5f4aa144a4c037a0055 979a3726654c4e3bc195da85f13e24639650c2d65c460c91ff1b377e27a3b73e -77000 e5e2e50e27fe46845384682b593999c03b4848a5912bb45d22974cccb551d125 75be98b3706894389661b6e9c20057b55cdabfa26ffd74bcaac8fc01ba273340 -77500 be8371eaee6d9fbf2c550f71e9b41d135201b8b4657b94e6660c908f239f986c 32b8f8fdb525510204119ba84666c0713d8f486328a98a130c166f36a2582523 -78000 2eff5feda9ab021f5afc380a7f931e7d52e7fe2ff3e2cf1ee7fdbde0eef82b64 65fbc737d459fa4f14f34704e11ecd9adfd51078f45626671bc698ae18d849d6 -78500 3018bc8d8b545e9ec88e936af13fee6bdf3ede83f61d2bab5f723803e53e0062 7b2380f5e4d64db1aefd218b868cc51902a54d0a0db42cefed99c7e8de87a218 -79000 b0c165f1302d8f19256dc2e278a7a5ecb99eac7c998306a50c8b4686a077356d 491242e8fb5fc40eb435f931bd11bc42428634a5b83abd1fb9f19059712b1ec5 -79500 68a1ec922af3091b3f2d59824979ab0f53a92198465ba557236cd41723deffb8 fb4a299d949b55ea78834906a69ab9022a49d8de653310369fd8ba9af477b7ce -80000 3b7489d3c34d0848f031a2325269daeacd8d00cca588b2b0155a81bf5bead1a2 9ec13567c8ceb32e9315afa4321f0a088d662f7853d492e8fea9aa0825f0c8ba -80500 a4bdbb1067263df39ae9c3fe98b7e436bfc29fb020ca4e0caedc4b92409cbabf 5d94d51295cffe3419841c9aa1afe3a281863f571789ded22dbee32e03726946 -81000 ff01efad3f1d35001246db4167727135f57b0e2603185bd8f43310d2725b4da5 41766254f9700bf8590b6bfa6993eb56e866af75377438b7b7ec4aecff1062e0 -81500 1e6d76e93daa7db4bef0b866414eb884b80193359343f7984cc4ad813f10a555 87b53a2233125cc8b28fa7fce0ed9d4030665fe83b9e63a76e545f7eaf332fd9 -82000 f77522692699eaa7adfa876193ff59d445443d55389e9110c211d4892d0e4501 a283d883a0705d2dba7c61cb45d6019a7e464aaaf297d8cb28103358c12e33db -82500 ce6f78297eeeaaae876c2528e2620ee91005af068e45c079f16523772b1ad1ab f52cb36181b62da6142382debe8325153fa672ea2a82ae0f4f1f05d3945ab944 -83000 fb926dce75fe0237ca38f35e58a77ce4ee8be04da61b16f360b029ccb889ff75 28adc102bd9b8be9013e2400e65d2d57750e995bce1b03ecdf1cee59712f359a -83500 f41912c2e881115560d9b957f91a8463c082efd4b887d3a9762fa7aa70d7dac0 aca22527fa30f5d0e0a8f2505a12fad648526bf7c7a0012b2ea02ecdf55b6fa2 -84000 04c39ca3103cde71f02315b339936f58cb04aafe9990c46326733493897f848e cacfdbf9b2ae2aeee8bfc355d807badb9cc02835889a999e93c14ea7800d54c5 -84500 5f40a8c35de9dd97ecd7244e84a895deb4fffaeadc22ed8d206d303578471ad8 e1c2dc0617f6e76b2ab84179c8bbc55c46d9732c6952beabec2d14babd7fd9c0 -85000 b181b9521ee2b12c19c5db467c39855af3e1f636a4086e1c6a728e2b45165402 8243d308e207fc44be4180ad0a63916aef3877e6278d30cb6f795d463541d26a -85500 b010687cf83e100f2d398b3927659ca342b25e443147badc9be5f13331fde93c c635b1e609f40f3bbd4aaee0df1ea6b27f18094f1d00377f69430b6507012e88 -86000 291fee34f060bf3d1c39be96f5ee8cf18c625515947c5495775924f5702abfad 47e1684b5b4942e0719228e060af33e8f13389619e91925d58f86408ea149035 -86500 bdaeabf298427c06e09a2e646e10ca3d17056bf1ba9619371327ccdb3f72c09a 4eda2aae345266db3c1d7f8e49699c30e70c8675735a83972d0dbf0db2372c24 -87000 8f8fbadad337ea15f63bc845e472d58d4c6467a516d77d08fd603ddb3b98d823 2d021df329f3c3bd4a39a5ecbae773b063f4baaf776f8ffb519b0fd4d803373b -87500 109c6f62e3aa5e0ade745ab3544f8d055d4ee1bf27d217bcaa0815f8b31118f1 1cf68acbbe94735132fe7929ae72e1fced6fc8cf569bfbc088a16c93c3e9e403 -88000 f46e00026587a254cd7a382218d9f2d61d37139d7c3c4f0ad76d35c76a2e8fd3 fc2e809bba17e3198bb92edc5999820f19a4d7135330b2f7b055252ab91f4896 -88500 a048c5a363aaf55cee60a2a4286afc8199b7bd0d57d5e039027d3db2a6cfada8 fcddf7448b220764d0452dacea67e5a91d537830349e307fdd20763143f92bc5 -89000 95e0fcbc78961eb79d44bd8e8055a26e77056036cb235779fe1ce22086a8705e 3454b0857e99663789646a938c33241ff00e4f7f853870665767bfe04ffce0bd -89500 8ed9d4f7f4c3ec8eaaa57d893a9464cafa4e2ea705756bc00c9b9719d51ee56c e836a5257dd6be6b167b7cf6c39b17a2433b07e86b2ceecc6886e57cddfa2a94 -90000 bd2cdc7f05511794992b0ce31ee8d58e428ddf12874905f102d2ca0a37adf8c8 e182353321678e537290c24a2a9c09d226ecd91044cc139038dd134ec1ef1a73 -90500 a996f4865ec304be3972056e4fa5890baaa296db692f4442c5b0b7337e75054d 98a91f31ee5cfdf960e1fcda3ff3d8d058471e2df6db7bea0e3937dd09baf06d -91000 f6cb4c4b3fe3b7365cd9e05f757498cef6da8eb0e6730f4c569bcd3700ba1d2a 91a792fa965f57abd8c8c95a37069682f68a3ad2112883779fd33fddf3cf7368 -91500 4421ef207f0a56fe208ecf3cc145cefe926784dc163500dd5018585c6bc4c0b0 2870e9bbe0c6ae16f66d6255485d6c6c5c198e16b7a721c0a027df05bcbb46d0 -92000 eb18cde79b36e5cfb7047d7ffd72374892d294d97b19965f67c264a42be981c2 77ce5943ff19145cab30c4b25f762f1e93afbb25e284388f88b4078fb934db67 -92500 2a1e0986047c363c557e0719dc464f44cb2a5530f36ead6455caf22579fa728c 3fc8941af430a2cbbe3a9e51ece9042410bce0c9eec2905109433485e8dc6eb6 -93000 759bd6b0b243739d3d6c28227f3a9eeca8afc6d341d17da49751065ff6d9027c ff40f2c094d151ad356ff66fd39eaed507a78f9d3c4ed2ccde744d600d3ee843 -93500 0c1648e1e670c38758befb41e8fc48f337f3b9c2aa8cf162c2856bfd44dfb4e6 e417032b5b7a38c5a9812822810148a15818047c2e8364ec0766a33cba25ef34 -94000 66cfc1f322a9971bc39ee18125a9464b9f82eef9c314670e51261402e50086d7 34ddac2e7b943cd760ed4863497ce0ba2a723bad5afb6f391082f1f1603c5a51 -94500 0bf23f1c069fc47b2289bf52f8462229a39ace7afa517a43a52276f5cb8a0f00 6d333049619b2fa4f612c1a6bc8bf82ab8a7db7cbedb51a258ea1bcc33b03f90 -95000 1781fded2a4d5a2ab054b04de3935c97fd5f535f0bd109496aab9abbc6564dba 18990d4e8be1e75e4e97a92e16bb4fbd805afa2d419629a5eec4d46a269438a1 -95500 ac453fe6cbfc81ed0c9b32241f121410d4caae7ab57c62ef99e08750f2d5f153 e3c4ea5da181b0fbd82e45e106a9c3dde36c28382093708d8cebbb72d001960c -96000 e464e4c5f135dcbdbe41de354730b1f633f00f458994d6ab3e7b272a5335e3b0 093f11b3784b1ef794fb06db18424f84c6a1bea0b9038666ac5eb0d36b18258d -96500 82345f602aad0d7ff796eaddddda22958f4d3c9c41fb987378947be6ee12f808 f6bb034032bc77c931558568182e10066932b5326940dfe562048d83dba4c126 -97000 eae3af1d8bfe6d1c40c118e0c78bae2bfb1800401d532b63a3c875fd3fc8a24f ea34ca2227308ab8818f085e7fefb2f140dfe9479558e6dae8c0dc049e09765d -97500 60dc3e9f055602d3673ddb11ab25d7c094057a0c71db2a327a491b3be93eb9a4 186a25fa3609da954813d575a4128ff890d571f0c003f0e6d62a6322279125a1 -98000 5124c9f250499786c2948dcf5e2be2c7c61b446be3972adbc0d65edc8ff87b0b 7f5892932cd29e78d17fda5c3d15bba0a600f1e9ec2281dbaf0fb1dc67d5e8dc -98500 6f507567f549b3b1e387f1bf80ec0fef03a9a1af73147dbbbae2134d6d1633c1 60d73750b6ce4d508dc18cc64adc9e68b6bb7ea4828f09e8fb7419b56eb652dc -99000 64999aa405a2a2e5de34a4c3547ee525b503566532d82c35839a9e74a1389ffc 20052d2448a28485dee72fe536fa8b6ffda1e8465af82491e87980c8f806c8ac -99500 3cd60a841f4913bfaf6183237ebd325b7baee3a5992f092118fa49817240a385 08f5df63fb4186638211b70120a165898891fdb195aa8a5b4e41bb0f9f0f16cc -100000 f0394d3c54a8687b6090333aa03f93f9369846e7c142653524adaa9192b37b7b a739c2cc2c59123a161c9b9864a4c834dfd5021066198f51fde3ba9348d195d5 -100500 c5ad61c2da15ed8083a3d3dfd80d226b9977dc831c11e83b75b3ed68d2af0e25 e3121bb1573ace63889a3fb9305fb95857bda6e889e9a88aa2ad4c76cc407386 -101000 27c2691b9e3e9cc2008da070c0af12d0997c895fea5c405347496c6a37570f95 d465e2fcce8e1b4bf7355b4d87445d2557336354b86db40bc924752796aca840 -101500 80c3bf7835d6a11fcaa22931aae51bbc602af4412ee8ec0e8b96c3a9c7128f16 1d7c3e519be3686c4b9f09708e225c8259c5ba6647fd78653b387539f58bdbdf -102000 52bf59cb7e10047df152f35bfb683611f084d444aac4301bd0284d3e458b6022 7c8226cd17af258fd69631ce4cfdf204dab70dcf93bfed953d6cf488d576f56e -102500 5dc7c42f2501c79ca5d610b8b69d408033bf0f7d16d036bea01e90e6c1ac9342 403edaea352b4da33ec3269ccbae23c226a39961f457e5d3f84b806e517074fe -103000 719c3b85ab62248c015de680a8fba158d0a336492668bc0b202ff9fae1b1b5e4 d90dede7a044e1b11ae429bd313e841c12e8d0303aa6626db4c953d198b0f531 -103500 fa0bc10bbd112c733022783fa67cc4ba045bf93115654e1f25e680595024ef04 e55422d2e8d2b8b6429ed85747a8ee57c549651eda0fcb2871ae5762862a86c9 -104000 e63af7f5547bf8bc2f36058a43569a30f7edd8286ce44ea561e63a3bc11ea7d4 939e2e2c30e66ae3b9077e947acda9b7dc0b9f326c55cef4e4d2e5025a0df9a0 -104500 d73f74f43bc0653041db94c60b0e68c194199041c830e4f90345c1dee78b9c23 d1b14fe1a0631af85d0da1b0376a93ed925248fb2c5bc47d4284832d40fa318b -105000 460580489a262514f5414c1fdc95ef0d8290a23bdca4af93fd226d72ca79bb11 11fedbb936fb27e227c2602d32f688f1d024a5fbc8d31823d273818ed142ae62 -105500 a461d00c1217d40b1774f631ce44e78c974be18cdefc160ec33e865b1c7805d5 24f67d2f822429d89701691d7834c58593be43e7249530a9c1dae9aa12cde4d2 -106000 70b95f002b31d55c7b523451d746df1ea1ab182f4e3d26a6a8146daa6b175f70 f59d284adbc90a549c211187c55814e85b8343c7797ade9c5f761e5b4c5855c8 -106500 5bcd8c94849d744d137dac85d734d893dea9963746e1d5adefc0852cc99c3c66 67b4fb04c0780ac951d84e6779fafa76dae5d46e84ef41cf690cd33392c6f926 -107000 aa50a7001438cb8eab4442c4635453881df972b8707150275fac0867d7254341 9e2451f91358f222b3934b24013be83c1fcc78415c12b4fab2cc5dd8a3d3c36a -107500 f83ed835545b9320da20a1b2961c285adf11dcde168619a3e7e746f93cb93cb3 e27c84ca437850f8aeb0cf3bd1a727caf91808663679f2dfca99f4c676a4cef6 -108000 d9cabd49da35be240bfaf8dc107e13fa3ead3029573f7711c51c874f09e2af83 85f41c365756daf80d25256a132c25ced262eefd77547a42a51603fb98f0fac2 -108500 e6f6bf4d75295e5dfff4f979fb12292736dfa7d4d8a7dc683f6238a4e00caf0d f294a30724f9d9ffcc244995acf528e501f6ffd0840f5ba8ecddbba1d1bbe250 -109000 154e12021e0e5198def8989a1d68326833d020409a76f980e4e41cb1662e0d47 2e486aa0080740653141a5219ef25dc79777d3976bd9fad1a7c7bddc2fae858c -109500 02a8b8fcee9f8a420ad024de30fb8f4b2db683b4f93e37d5a7936728ad1bc1a9 f9c26724d2d6e8398a66e8ac080c8aadfc5155ce4be3521b3ae5aff95fca7541 -110000 587654021f4afef0e863df85d5c48c1da57af439c890cd7c82f57112b523e567 41299bbc731c54c00252ac8506c5671a019c2f24117534a52a6dc243de19e60c -110500 1b144103a2729d255d2c79223dc4804e9ec38bbd07105eda2eda5d350933c8e0 47988c8a2b50a19d5c4cfd5c657b3bdb19848828866e762f5fe40f8ed3b0fc5d -111000 d2dfeee7017ce245109d6fd20d439a58fba318eb0853369ad740a4c7d8cb3679 89d0671f5c51cc5e682fde76759bf130bde74a8c3d0334013165cdc74df67a35 -111500 7bad9ae95d958cfdfe5f6f1ab0692c74023e9676aebf77696f0dd92f272484ee 8711ac67cfc650bcc9a9a3b170896959954dce728667035278b865e843c5f5d2 -112000 aaa6a01ee0e8be04b54950e9fc47308bea161476fd9e5f7d931a9ac7a177c6b1 cfbf8e1b380186cdd7dff5b1775e68857e0144a6cff5c699cda0df8a9b755879 -112500 856c253a4ff511cde2cd1138cc415c15fc4601a9cf20f97a40a3ed5a8e4bd28a 2418313d86bc12dd0b7ae5246d70c5c95ddc342c5f522d33a4faa38677b1cf74 -113000 d39c76ff2213efb6aaf21e1831e8dfd86e82851311214222cacd1065e5f442f5 7027dd65582113bd83834da3b8feb6f5e724156d8653689be02acecf664ed8b5 -113500 072de8c792fb777438dae0fe6605d05f84c05c478cf045595236439ed614c869 66e29b9bcaa1beaa8d901e8227510190b64b665c427147e79fbb03f4c7560df3 -114000 2727f22d9d9b83d232fb91cf7fef9923d998166a632e104da344aa5b2c33f963 afb687e99a9ef1e794a049e78417ff2b0a15bf3c0f0a01b5c04e381dfd3eced0 -114500 fda2f80a90dd787eb236d38096e1f73b7ee1b54d067c53ee62d4201004df7f96 434c6e214b4120e3df23c820dfbf7ecf3facaf2f30b55fcce4dc094d0d052ff3 -115000 f8642fb7ecc176c23e6919e2a5f9a3f69d60c1bf10329e853b94141d7eecec79 02a4953482c2887d0dc4d2980de20cf75b73ec8d81d5b3d6ca6df741a3f3fc7c -115500 96be8c04c6533cf914499dfa780622f64e3362ee67b888c3d187c7cd167c124f d160418c73e78f1f75972ff6fce579d50f936678a03b8e3e2e8eec885c8e7f97 -116000 6efc2af9311adf3ae7cefcd558b25335048a0344d0fcca48f4a8302e0c2f4e4c 5bd32d67887dbdc6482620b347a1ad8eb9c8d124ecf4e6966269a1ee537f7562 -116500 d2fca2b2bf347959eda9a08e76c269d1e00d475d90ed02ec7d5d537e542c648b 9476a9957e44fe4de208e4c707f0b6d1a2c0c0b3a32dabd912707ea86823f62f -117000 5ac65e76af1b75c9aee7eb49b22ff2fee88a1bda49287fc5dc7762b2c5b8768f d357d64072327f9db3d73ea738abdf89f5bd20ed4b56733bc9df37d200b6db39 -117500 3d7e8e1235d8f137cd5661125cc0627dcb3c18945254e9676e21f2a445ab8b9f 0f9c97626569303b76ebbd2cb960341f2297f69ae140cc84a40a83695993605f -118000 be2144efc3b4ccf0d4d3d7b66c5f6ba253d1fff069b89a69f8eb2cc4ff44fe34 9bffc6fa6a4cf35486018721652d5358be0bbeeef8b98398c9373c352cacd4be -118500 58ca03280dfb1e73dfe8ae35f67b60087586b36823e7fcdfb0509bed23c0f9d3 58ce09f4189a7f9263ee9292d7cafb880bb3676175c7553a04e25bc261ca21f8 -119000 907a0fea05eed4572602c76515bfa03d5cc79da72496d41d84afb4ce4098be07 32779d699cd1abba0d653a332f07727b9a2094a4149fb66cb11f16df7c68d34f -119500 ee7317e1516104041197ebb0bba085bb14932972d5bf4ce305a3bacb9ce17dbf 6c779c5b384b94c7649ed90936688e83762407a89643aa89f730c6c399abcade -120000 7105703f4cfd592d639e0b5bf6f2d25380a1787346f24331401eeed04f146130 2a44b6fc864aac66301c1b20def1cafb0704830fb07e2684651513a6f8a89843 -120500 1dc347ca251ff3eda0a459a85d9df212ed27b9e7521bcb8445d5a377e23da48a 3da9eaf002870bd0bc46688093150e254cbc0171abafafacb2c03f6381a532b1 -121000 7b8f755c93b69f842a1f9ab68f67e597f0fce31b94e0cfed7f3847662dd1a401 f175a7b245645b0f769638a6ceeec460e87782994586ff8be749cee06da716a4 -121500 2e5aa2e8bd0b018cc58a7d1cfc18d19903cd57882ed5ae8f2d6eedf72efab59c daa4a0635304dda991bc047ed1e075a9bfce603bd3bc1dcf93da809f82b0c5de -122000 9c662917653809b60484673f8f223f3ccc52f9288b8598b6414bef79181de9aa c8c62e402da8ff36b5833ba9327dd92a501367be811157fca1f0b80ee49a4ef2 -122500 74a15173b1a78cb7e95f220178205db14c5bb67dcc64f8a1e4feb2cb5b2a6e28 f480c746a1436fb843e7f5935f2a8eb79007857b4c110a9348d4391302537110 -123000 38b438bda7e108f97112d984725fab27d277a08b1a72affda99b79654c21e0f7 b1bfac6a48327a4005f79408df343adb7c9cb22d2b70ebf2ad79121cbbfddfde -123500 ec7a4edbed36c3d7a0eb4098e6c6bca397bf08cbc0e0b190a4cfd506df0ac656 7700c27d9c2e7a0360bfa2426fb3688bc8b3ca935de69d15b6dce9ca6b31a4fd -124000 c3d8229a44faa337d05e0b5311a5dda37b91babcf95e5a8ccefbe872af0bd2fa 793481678c778e8653890f1145e178e42effa2ea7f8e50522187ab298ec6b512 -124500 1510db798814caabdc90f2b18282456d1b1be40948ba43fdc68e2da017c2dedd ecd23539bb6699ca362d898cfd6181c49ac97b0d9031538fdc0303cc8441fe9d -125000 82460aef9d1133d30707bd416b3afc2929a388ec8d1431e92699aa625a4cc3e9 8ac7f7dd700d26de62506f88cf117282a7840236bd66aeb148cde751ee3f7dbe -125500 cf883230f6afd44caf802508a9bce39adeae83cfdaea0ca10c5eeb7e6e0f7abd 269f3d0cfa2df454579a4b7bc758970ffb853aaa7600808071ff130b994adfc8 -126000 e36d486bbf7eed518a2a1b1668b516daf85bcfb0359337042bb8c278a5826863 8ebd6563987e0969505718a915e7945f0d26213475be39a4b36ce9928d313935 -126500 41b57270dc8a7fdaef0345502f3ad6ecf8012b680714cf7723aea4c7cb03a864 e422bcde2c4b3e00c42dde121d189205de9acc58be35d92bc590a67fc11b336e -127000 34d5852f2c7ab91f6b7ba43851efe2838a874f1d47e6c41dcf413f263617c4e0 296613313aa18e97281d6dc14419528e0914d61bf8eb26f4ee08105aa358c0d2 -127500 07f471a70c1d559e6fd70d2adf4720987ac72e71d29c4bafd5f78e428aa6dc00 c32efb7a2072cf74b7124a008939f8093f7028259a69d8c9d175e0bb4910f03a -128000 063c53a0e11590d0f370d0a3c2fdb3722c1c91e0203558436fb43b16b06f572b 2cf68c71009f221feec16d73d8ec1b729b0624f854851153bf78146935b69148 -128500 32a9b0507313417fdb97dce6e15852a8a55c80690028759b577723b629ec0234 b2e0756fd80ff838386d84e8d82e2704a52c07e56c10a88fdea969948893b808 -129000 b3dc6186f79ecf8e7d4b2937ddc1ff5372684cf818665a730771a932461fa8b6 6da8856b4177dafa784a25b68c4df9c250a664cc6831c9804403cb021239d03f -129500 1f5e8b0c9c4229ece2580e76e5164e1beb86e165d959cff8d7a0a9f74660505a fc76b8f58cf2fcbf3f2821d871788cf4cfac6e52b0fb0476e96769311865d90c -130000 3052fa9be8c4f5f24f40c5cdf0a8eef8087e08f1d168dde5d1e502960183f137 8d108e91ab41a1057413efa8794611be06459dc53a8d2099457073ba932acb4c -130500 73ed2cd1c1fa06e01c3c6fa4848d31b24564e667e3871ee032a1ae04812c4383 df3d5e20f9ebc94bc84af002cdc9211efbbcabee00cd755653a0cadfe4cf77c3 -131000 f78703a391119a15b5ce6a2a2bebf2988fb164656c968f72359af65852080c1c 8fca74427f6789147cd1e233e020050d9babd0bd6f078ed53f704c6922b5ce3a -131500 e8873601a44048b85d11b25b05c225fa970d4ae14a3a30c0072bcf6459f2d828 140c8f3bdc90be5ca51e7c3179c7b8839afed4458278759a35c4a078ae8cf4e7 -132000 98752c54d7a5238387599ac3a0fe44b3ec462f88eb0c3c6414160ce79c128a14 f82ed570eb9d3c9078ccf41e675c13fcf6e73e6e5bfbc4b6b2c1e4649dbf8a0d -132500 7377043aca01beda7f7d70c6c2a9f59ecec4769cb330c231abf8439f231a6355 3a35dacdff298a95ee0fc61728b4711d99c4d1bd4806dc738c684d2632fd48fd -133000 0d70e8ae76041c02ab65bdd3b0f6a456288532d5447dab7f7e30123b28e16543 d6b3a5ad40a90d26a4b218b8b90852d49f508cde1bb2a23031f64e765d519dbe -133500 37aa235fefa6f62af6e393639361a4109369d0393d66597a3c63736fa5113a02 9c59c20c57628b250fa5757d8d2d55feec38752453f21232141f82c1be4dea63 -134000 2605e14bfe5b9a39a4d01da070c05d9bce4b6453b599a1f6f95d8a6344138edf 1b02cbaad0ab46a737dd848c3db0f111c3fdc248d472636765ede6a6c2389b74 -134500 12cb93a2b1e5ce4d9c6d2266bc6984839271c92f8ac34205dc621da8033af81b 6346ab5cc2bca05485ed517f9e494e1e35e33ab9ce011923c6713dd0bc28fe1c -135000 5d475b01fc5b6a22c775b89914c3b148431956df26fff2631111e9ee7d1ea55e 182dc60ad5a4689e655a00728594807ca659ea3e870a4c71152b220279fda836 -135500 d4b244f6df6c05a1c918ec0c80b4a230c2e40de23847a3c6a48b8706b55191a0 c0ea29271b681e460441fc515fe8af217459716e9116ebfaf9899531e55b9181 -136000 123eb5d144a44b6940cc6194be4ba041c5fd8a5ffb342b5d62d8779605d1fff9 9836476b408a143b336dab7cfcee4c07ddcbf6939fd40267f8315a7d4d576fd4 -136500 c169555d2b59eaf45046d5c3832203dd5109c6e3018504de66fd99242b41d5ad 0884992c307a5b98b026f9885b6c81082aaa18a12ddd0b302fc5e358e313c810 -137000 123d022b5482871c55b3638324b5713e225c6e36ab4f83120d883ddf3c0fbbf0 024aa453462e49f50c55c36736542e4129f56cc81956b74f7c77e90b0e6796cb -137500 3dbdb568d735e6c47c5fb8f459bc448693566ee30140da275f786fffb244901b c0e599ed4901402951a3663d225047e94861817b0a412b01e4c770c9719cfe53 -138000 9dcdb63588c3f9d43ce67bb6da88a144e98b3340eed60478d67941bc1f3e48b0 0c04f84ec720ccb4908774fb474149dc069c8420a53e89e9007dea32d90e380e -138500 918f3566304f92ee937b50939e5224bcefce1b61503b8cf5c75cddd293115037 345d16e0d5aa525aeef890c1cd118edb3d1e6bf784e9445aad720dadc3408667 -139000 5a5cd26abe8d7b66b82dc847fe582d00c1aedf51bb747cda126f35d177df3780 b11a4c12939538a057f35a15f561da8ad09ce4ec33a1b6b965e6c35d7f6da935 -139500 883ccc866e98513c10d46ce62ffc4b2f52914f9d3c77835ea88b2d772647098b ae7d18414cffeb5073a788005a70e1e80b3c04abc1726101177509d0872ef2a7 -140000 0d53fc7a730aab5b7751832647af30f6ae6de5f66a26aec228c9642132460c09 d157b0bf7301f4c28143ea0266a95c92a05a3499dac2ab929d57ab75b2be499f -140500 b67b7cad6c800acd1fa41cad0e075a544368d679d03d620f5cee45cd966b61ee eec57bbe03beb832a99ab0bc6b77817e6bc459e365367b09fbcb905f3edfa85e -141000 68756fe78e60cc7191d62c387eeccd0030ea6a67d4b1fb6667c068c5dbe20d53 113007738fdc702b03dc17993f916d40e24e88d12a95726aef18156355990d7a -141500 12aa3f916704a9120c99c22977c22b16bfb670c9e9d2807e0cadc444c9e8d02b e7dc3dcc436c770ba20dcbc3f4f762b7ab343fdb180e867b3f3db34f8b279871 -142000 629495f161c45d033130f52a4df5e06cf5f705842039b89c3d499aa658ce5a6d 865d4be2b339178a44d8d9ac4a53abc6b4f710b723583053f23b73c0dabd77b0 -142500 941a5dbf034317971407a4743fe1c5cf11ae87be184fe4e7749e2d32632deed5 d8d4c2edb8362a39b9ef8b2693e1b4ed597a9b315e60e424e26797ac5266f353 -143000 b8ac8abfe7b81372299d2a8be307e13786a5aeb4c3a671c8ae45d32f4bba9281 8d7e1ac28129b56b0ee93dc931e54293f181d3aa253e844d1807d47b31193f56 -143500 610bc499b94eb7e00d1aae8388937087aa421bfa9cfa70baf798b8f97e1b23d6 e990d00ff71509c232b43bde64c749bb1fe597e52e40116893e02937c7943b1d -144000 58ab7580eef5d40c0ec3d7ac52425ad5afcbccac834192fe71ec5a1d15cd4ed7 d9194f449db3d58a1784cdda50ca32d4212d43a12e85c6ad9f8b77687ca04a6f -144500 9a49c8d5f6b072b617ff80d4b70116bf3db461f9fdf283009cd9e9b2c2df0925 a2921c9b5ac78ceb49666c487d217ec303b1f5347d6902baca9b8e3779774c5f -145000 29f1fe68b8289b62a4eaabaec5abe811c61b6f2220dd15f04bf3d2ed3f98ba02 8d3672fa9d6c4767e8d3819f09a9bfdeb98a6f35b83f01faf1f7b85c6871118a -145500 677d2c090d3beb31d1e611e42801e75fd3e2004e10ba8ef1cbbad5e2b17eb02d 93a4cedb34458ef8b90ee740a6b19364f5ba6c0096a16142929987d2386358f6 -146000 b85efd80a2171505e8e2a83feb7f7d12e3793fa4ed2999d7b6148a1673e574e7 c76311a2cba2713e1e7706f71e22abd117ec5c45d7463bd7cf9baa7734468c79 -146500 f1dec5d905557b23d644829ceb4f9de311a05ea717740e9103d155157e4d1354 3764ee8b0d6ae8dc762a3b43d012eea45e1e5c1008e90403ba84549502c3b62d -147000 1e59d25367fe453ea1e39d7f0c870f14bc37e99ae2899a6f0e67dc8ca110804e 238df05f6e2a851137fb165117f2feb458487307ae95d0683bc85fa748cea31c -147500 4547d35c4821dd671dd3d4d99fce894d455c083985eeaff26531187f54349bd4 13f4a0105947e707604293a632917b8b93caeb00c02a28668a9559de36e5822e -148000 f50a828d973baaefd78a069efcbc42389c7a9d0e17cf4476d6bff763d3b219a7 7d057f6f26c87ead3d5a3bd63b23ad81ba5a9a84258b46921f27f07919be82cc -148500 219d8ce760106e41d5b6cb72360801884950e795cb80c5cb75a4cbee7c9884cc 66abe4202adfd1c91b092dc15dcd702b0e383c2a9a87dad84efc20f2391d6024 -149000 e13e98351891f9940b40210188016098d67d555ee60922bd710d234393583886 2751b92f77148b0b55b15c1e1939f566749d8bd28b70f9fa9445d5c66b116a4c -149500 bd0986d58541fe55bc5615de06174615007bb0a4e9b7d52a6e1de27660ff5e1c 075df9893a744f62bc60e850104f6ad60764b8098a18f89eba4418789bbb7c6b -150000 b0a52b599b482e9e081373c2d0c12adae59742c92c3feb16f2b56a536389c566 2b66e1c89afb06043357c8a702e15f37c6cebfe2c3ac2e2994b387b111852c2c -150500 348a90e69dee425ca95455f04bb8e0a9a5e8e4c9efc06e8358e90069f33cbd87 6296399a3fc3e48c09ff1bfda646b6f19277f2c2562c8cac5c850d691b2c2110 -151000 c2fc138fb4f13487c8f0ba65b1843cbcbfef598d66205495ce12eded834ed5d6 6b3d49e0f596367b951b6939dae4629d81758a560d8bbee402b4258fe3896e18 -151500 f22af8f0a616af674ee4e07e5821c6ae1ba54d431200daaf39362d203283af2e 8c445485555c915933539ad6c8ec776b65480a6b6100cc2f2355af041d37ae9c -152000 ffb05330a4e59f90c081b821c1cc26def98eaade28aa6fa36688c9c9ec2a0ea4 7c94c4bbaec72efc42d8c00f50f777d09fd0bf0c71475a31183bc391038e4fa1 -152500 b7c7e8aa6953c0ad15cc9b003dea50f9f8bc08d8c8ffcbb287918a9e570affbd 16591b434c6436280873b7b1d81157359b67969455cab02fcbf7ed9dec87e64b -153000 fef11d21d57c34ca41af06608c09e6d0a1623e6970123e654a81959089913630 0683353ede70fecca1f5f072916105b0fe941d24b2744dced890e2d4cc114356 -153500 0decdb908b6c897fd269156ef088ea6c5c76ad98cae97cdab6b9958fa458c4f1 458fa9b12274e81b31d551966d7992d6304bd3486a76d9e484af250b4d725e83 -154000 8e921a4716e55e2c03536ace904f1b76f2e1c1f44eb1efc293e819619fc64a6f 9f3faf97a3d07baee0cab898c7e2c16e1e75cb08b8593b30897f9290e7564464 -154500 b2ab747c57f1e073712e5c7c63d14e427e4c5aecb70c749d686ae6740eaccdd0 5b6d69da753ccb8fc0e7cc323bc544e272b607f0fcd7ecd3afc27fa454bb13c1 -155000 4a27f6a366c137b5b0d9a7864ad6ae3aa2aa4f92fd96afad203f9750743d1b25 5618bbb8a52a4a6523d7b79f9da38af51c38ec0b250918f9fe13df1f5ca4cded -155500 44de83681d8bcc4a775141039552a3bc94ae7150ba6cccb0eb51d12f67cfd3db 526775b79eb1e6f88bf7b11c21c21cd3de6b70c591b146f75dd6f7dfb25d8258 -156000 fd67b25d5f2f9e33e0717ef2eb6f7a8b61c0e369d1bb27d363c2fffec6934c6f 069fcfe28f96738efe2241bd5c46e5f9dc2568399dedf97a3b222e7db1f8d479 -156500 e4ccbec221374ecbbed5f7515a62ab145566ca98f91fca6e9e9e5faa5a302e1f 0138154cbb27aeafb8785898175459b8fad1a50e5526745da4f3e3fce73906ea -157000 7931d577b76d43c21d638b392ce9e89deb30440d5965bdeeff5ddca528b23f8e 2b3023999ab4fa8af216fc6fcd1b74a6d9b91805c25286b3a9b5c21d111bd929 -157500 5a785cae6668099aa3bba0aced796a2efd3f32357d5cda07964c38bbb8547f11 92fa0afcea0018aa72753e44978b29517c44b86583a7e7293bf41d0fc52adc33 -158000 215585110369813d5c23324bba75c2fba77a3cbbb8074822747d1d5f7a54459e c2bcfd99aadb46819152e678172eca6ea41d068cb9c3644effd3da1d90fdb6d9 -158500 33ea7e9a89e3e620f7622a67f945e6a84caab88f8df84416920e34611183a012 fe4a8ca54ee30957c1c4ff378addca94aa3c2faa44d6dff2c90aa740c94f322f -159000 5dac31f23e99492315f0ec0395c5913a197ecc6bfa5a1f1c38fcbbce10f5b2b1 3f33701f476adc2de539a516353507c2319ee322415cbe2d2a81d25579320df7 -159500 e49f3c6d819ba98b65a07f3e2b4cbd4ed74f8f352ddcc5b29cf715870ffc96b6 8d4baf5eb4e709a1749ffab123eae1c16c84c08c2b10c1bf35b904214b55622d -160000 4ffcbf8641b4b794fe4e304f3e33f8b252b45c99d647e26c174830811d5214f4 d9feccb9318af01dda19ac1b834e8aba8f1a31b7e3c0c874c2340e5f963099f5 -160500 940e235e254ce7e8c7884b846860faa5a7f8fe08fd7d05bedf60a178b294bbc2 4c96d0c1b2293677ff55acaca052f84941b801d35426f5f6fdd0985a772e140b -161000 49a2fe7b8f78e83709f195d11f092cd5bf6756dfbea8b61f6ad4acca38e0f433 c61985a4419ef741b3255effd2490b3959d9a37b9fa458a01e314acf2cd110c5 -161500 adf7a049b0055137358e82ff4cd0b223d4f1e65a99cd9427eb8892e9b3956546 f2ea625ab6cfbd295435c3e70fc60ca04f444e88a9951351519c27066044094c -162000 78eb9152a6249d26cfb9acccd3be7692835f61a70f9c4dbca7dbce97e8eaef29 92bb404d3deec9249fdb8e8b0c11e1e6ffccdce4f6b76e49185e0e0aa6480b30 -162500 f0016f65cfe29b53a443c3117392b631edda432fb508e67f537158d939bd24f9 7da855957173b1caef3a5be9882b88d6be2feb3860bc528822ac203df9480ef7 -163000 16310f334b323b1c422388a77287e590286b436eb1d54c99a7dce533febad9d1 50b8d182a094d5709040d1f8be2ed7aff41c50d3dfb49b6474ed04c7563a2afc -163500 54529c58d723c981aa51c3bf7202246d09e30d6bcc22b28929b2bc80b970a46f 81722de9f999145ae10c5a72cb03be616a2c631f6239f01243836ceaadb219d8 -164000 135d6c860f9cd670d82153e8e37e5202b6b1632cc35280c0210587f4cb4d8f49 c5bf964eb82fb51d1f5a4507bc2c9d658ae2f868cd517674ee1d81266971aef7 -164500 08495f35f925470863e7dfb79ec17bd61029899bad972ca0e5bdb0512a0ad908 8901ac98fdcdd833938280eb495214ec81269d8ee99e0c10886b9184b0aa9d26 -165000 5178c8e3106c700a225efb2d7453be3a94616e980fae5a532c0a9fd103aeaaab a71b7ee462788bdcf6b6945da2a2b426770bb4e31c7063db4b9c80f82ca88af7 -165500 3d1e48c8657aa62207f24888630361eb85ea3f8225e65deab240e5a242fcc463 b16e47a7ad5a208fe467efb2f7a2aba78cccc41dbcdfde571ded9b033b2c660b -166000 2a5df181ba84755d4893b8af164abc28ba9d67f0fbf70a9fe44f78202c19e78d 6382ac5c3033076f67f758d9d4a66006b6c67983e46eb4488b8482e5d020cc7f -166500 f33bbe1188c265e4f52649d90a9c853742c89348276119166d9dfb5b0a1c1d1c bc724795f0704caf13beea8188647ee2d0d8c05593cff788541d1f694f02e7df -167000 278a49c7367096b101da81aeed3a9b3763b9087446e3f3eb7d279bbb180ccd1a c90bba777861cff1db1ef3cd40e240a74bdbeaa23e2d4716dff0700608431547 -167500 de103832de75b420ee01b8eb238c7e5ab2fc2895848f1fb934bc0979af54ee3d 5263039373a72cea915df57bc9369aa15e7dd2ca6c3b6df27938d5240ef4cd8f -168000 c347ff8a9e0c4297f74db5943de2edcda14652f1e707b0d789878424b0f50555 fd732e674ea0cc59454e599365d9526a135a67ee82a1e54460f90b934957f9cf -168500 7c4bd55cdd16268ac7da91c44a5c204519aad6dc79a173d65227995d8f480ca4 66e715d9afc7e37855c6f1436bb3344b440a7db44fe5163f2674b542a3a8affe -169000 8d8295fb630e487b21d46f82e5e0bb95d667635b1c0cde080e9965ea021f0d3d 32309e6dc4e7812fe36a3e9f14079eb2f9a04dd910965a631f76fb23f29f2c5c -169500 3ff4f89571d4b7f8e2b25a761e2b03dbe82d9d2acc565c8f06f8e61b7b84a48a d71ea82c1b352917a9a60feeb3ea40f35447c58909a0832d17451458c4a0a079 -170000 e4612c319a4c8cda00c8853428e0c57c4c688d9c7ed0ebe3adb4ea410066230a 2428df1325dedaad3c6c2e18ba57184348603cb4e5d4fad961d9f66a33e8d4c5 -170500 38f6d4c55c456c85b59d965db3386f3bebc9f3ffc101703667c9ada2c6f110fd 7fec7fc3f24c1f7e635e06427d949e9244c3383ae8a1cbe5ff92c20318d1b303 -171000 fa2d2abf42e47345b9b06ab4f0dbcb6d818815b383959b5b0f69a207e755ae18 6943c6e99feadbcc5f22d2000b715e609874953a2f6b06ab18c6f6fe0d9ead08 -171500 b269e08b7b8fcfaacc4cb1cdc39bea13237265f03eeea6df488039715959d60d f978606a7a355e240373d149a0bf3b2a80d735371506f6d83a7eaf2a05f6a300 -172000 c1ff70cb404b9a3f97513e00fe8d713ffc5a1ea49b29be1480dfd3b0e4410d1b f2d46aa05b23a697e347a4260c9d14b51e08af5108bf22123b820a54c73c3fe0 -172500 6af8406f49ba05570e46ebbea295e07ff856de60f7f7a85f29ccdf0483deb414 2bfa8eaf8be3fde78ec35b8bc4ec1274cd089732617255d9b1450f676d359631 -173000 4187e88e79ee333c661955addb9fd1ff4853bccda1c1f73585fbc4b866d46ffc 2c561a6112ac2531467818ef79bda7fd294cc2d1aca8d700ffaa8ca3c7e2cabb -173500 979cd0755a559b4298c4e1af1ca1ed389c152f6800718aee777431e3b84b2975 817578adb3539145804a17166425c07a798bedb2637e8e6567e77406da8cbab2 -174000 84e476b10a846c1f76cd25ee8721aa8098a3a794f56a5a6e2fa8ea08dd7de954 7e3015ed948fc061ef3955ff4d18f5c9f2ccd86794be959d5e51e604c4ba315f -174500 daef6a8cec458daee2a97f145d74867790d12697f424e390fa5ea96c0edc5889 8edfed33a6db9e18b19b49a451c2278d0df8c17b86a5be2703336ad41ddecdb7 -175000 3f6c5c68d024c26235bb054fe0e892b4172a50c900ff7e36a061b17bb4adb44c f36837bd4b44bb99bc4a99acdc71611e6bbfef26095aad173d5b6c2847cf5cfe -175500 2a25fd32974c49ec621f4256e89f3c1569734a675bfde35fe0ec4572459a99ce 0de2de8ab8f49f684a4ed93762fad169165b9f29306fddcce37a10b3e0f324b6 -176000 ca43896b57242e50c5e1b0904b12b7008d63f30810c9d1728929a45a051b1c28 0c0a240dbb5b8d9c5303c2e401b1a9be3eb940a2ccdbd40482b18ebd9d16fdc2 -176500 01bd824255da4562af0cfe656645a2e644bedd67f5c4c2266e9d706d724f77c3 c1c8c3eefcd2a0dd893ec58a59d9b4b9fca2456b4ebfa118caf122316ec1758d -177000 1931b94a1d1731ee2fb2b959098279a73f2938815dabb1689c98ca64ca265eb3 9ecec3dcc0f626eff5310a338ac6ec36e52cde0e31dd2668510985504dec6b76 -177500 d5e641f50d45b9d3c2f81c255fab7812b79d778bfbf3acc3a905255009efabb7 780102c55e6488511505df92213d370484505fcc63e36844adb4e55e28b11891 -178000 41dc7c791cea13b0c22c556ecf0b9c43bcabfe110cda05fdffc9a213d07878bd f502dfc4f8e1e754fb19789de0195d3f76515af97df6f6a4dff9af35e9e64cc2 -178500 86fd0e05f7c975edd10fa04040fcfc06aa5988f25a24dc475468023fb5ba60d5 9a9d5b0da31bb391cfadb78b79de03e6d2f9356b6e8f2a6b6f3561718607666b -179000 9f87f2c50cac2bf6596533b242692ac06dd59688c85711dd3075556a42b5a51f 62c5b9a2f74642239aa89a9468c1959af35f4218d16ae1c0e22879ce5aea14fb -179500 2802d26be7d5a8dfa0e84d507569ab54eb2815addf1363e844143d4d1949aae3 04a66a42a874e8a94de4b35e0fe5b2415e2806089e62b0ce867206a3bbeec923 -180000 fc0f88ce08e8dfefa8774c7b9e101f82f4c7928aac246233b5d97b178ea1e8c8 d2cb3429b3bb7ca9c4bdbffed735f779979900ec989687ff9563819b3f340a40 -180500 55068efb221561b62da4c6cd3933963165b99679274f0a18b57e12a0f59c02bc f4a3a53f8756a0f1ab9f0dde456df65f68b487f452e35119a395990224589672 -181000 87c0badaa9ad1ee338a1e0bee51f0e5d95eeb69b608604b687e1b75cfe28b1fc 55c6a1f3d35e1ba2c56261370b991094f37b2e0c94c585c83c91ceb0e66b4205 -181500 0223e4ac4db7cb7aca8c5dbcccf4dd6d67c261e158579465c830d00f0b2065a4 1523b5a7b17c5f0a487b27b05911b0b023b7b70c1e93a676178193e10dee764d -182000 3bd580fcde83b72980a98de1bd2bc33f5d2e5260a45b2025f8993ff148006fc8 b5867c690edbe8ebe6938bc93774d516dc0de5a71a28b48539e4029162825354 -182500 d5ed6e8efecd96800b30644154dbaef8704783309362f9cdba26c757fcad2d70 f64f64d8652b12527197f54411334ba0ba66f2515e4c99281a075d1df597c8b3 -183000 e926c6476da9f0d3fd84aec136e029881901667ff07d80ecd1e6e6e4a1e78979 e74160bd9ff069b6511c0602a1c72fc61dddb22899f805cd9c2c0be184848033 -183500 5bde7c982564b58b9d46d8208922b3ae8cd1d50f2f68c7a4a8d71e636b66181f 00d016a3247ef22887c0909dc0a7370c62bb2601b09425bfbcd93f782e1466a1 -184000 f1cecf410b8d9f5cecd6bf19ddb1c7157cdc5c42e110a42596620d9b54216dbb ca3d938eed902785feee39efcc9a60f26ba5a53ef969f174ffc7f44dbe544bfc -184500 89d6e5e381ea4c429428a773caa457945d6e5986e77830699d64ca84b6b7cfde 30e5fef97c937baabf267183b5f8bc9de88eb72b00c204abf6db1962ad1e1f0b -185000 d55dfc02a7dc5e64f615b9821e7738cc3f4b1cea50e291834b3d950457c0befa 3976b8fa6d5486bb07e4f6a5a63f200089781bc8c347f858bcd2d4a8eb4ebc7b -185500 b74792db4244be3b16341cd6bb1af5c7a9b71df58b812691901a59e2e6889f8b 4523193666a8f6eab2f73949efa94fd98d9ac8821ffec1c8069abfb1dca83b0f -186000 673e42a71dc7428d516a2bd892f5bba9740deb4a8e7100afbb0db70de4432d4b 54bb7fcf882d25f7e4cc19b41bd13e44d70c04d31a6b4e2ddc388b6ebc0b1818 -186500 ac9d112147478ad6096daea4f3b9b76912367605cfb6ac68a5951478787d84a5 7e112c5297f3521039d52a994be89b1dc3b6387b4be5398d7673542df3db0945 -187000 b06838fe81d8bc39304fd98dc9f24ebdc0e6a05a363713e028382d77334c2afe 53c32d4af24bd19d1dda8c23186b6cbad5cfbaa6ee169666de3b028473f3d388 -187500 c3f730a1d3977c557401a7ba920f22b768e9e89924a07598af8f6dc0930a4585 a83e748dec264dcc6494d6ef7c63025e554aea410915c25db93249088c287442 -188000 4a74ac7ebe38798b80ff54f21a428c40915895bc44a528bd8e4ac3b9f378def9 847a11b8eb71e0b5dd698b277fbcbbfae9c54e55477320396a602a26b1f73d8d -188500 59891ac998632472cdca935fa4a3819fc676d23702621f0c41d6d38fb9e354a0 4393d0b0d5af19f6c123777762a186fd30666e8498fd76468c3cf928b4e6fe1a -189000 7c43d2b882946af37b0d1b1e0b3c08a8c55e83b9d93e0d3c10ecd3ac7a49c1c9 0a5758bf838434644aedcccdb7905d4bcbd576745f82e53ef74c9539b9c95cd0 -189500 4913cd6821bb3900bb012df98da308582c7f99c8907d1dcbde5caeeb04ba1abe 83dd01f4f3544a1254fb7b6c1fd8654a10b4ed99581b1058c79ff2a3a08b3ab7 -190000 825d6842d16dafb7b6d3fff172fd176916478e6a14c50efca5e2b6990f7c2299 0d7f3744d4e18d9132d3bf7e94b9325900ad8a574c6a48b04e6594f2ed07083c -190500 b7dbfde08c23efe184956485d0c19d62325d121b493560ebb0d45321b1832b38 227eab03ea5949234a281ae85657bb5fa39b271fa2218e294c4dade8273639eb -191000 e61629b5f59b130b4e6fbe4d3aa8027d13aafd890ac3a16b1ffeb1d3f590bc5e 7736329d7fc7d226fbce139fd58d1b21a41381b442fd62f1d03bc53b5580f906 -191500 06e8304e59c8f386db5f89bbbf524959e5674c1f560121ee65e04b5902833f98 5e099e60aa5f56a39831962822390e897947b435b4b84cc2f45a1e98319aeac3 -192000 7a94bca1896611bedd44c28323897ac0b065d2832d36000b51da6d8da42ba38e 640f07390bf420c0f65d0b59112d66b148df416f2a139f961bee379df0928bd7 -192500 23a1270346e2cd8b1439b2357aa6d9967285d727963656385edad740cd66922c fe551350fefafd463b3d5f47a53ab239b346bebeaca875c6c7a87d42ba976bf2 -193000 5c7ee526691d558d00b30f649c4f77ca4c595742f23e389ead78633f8ce2dd35 68a041f99854b2ea4ae5bec9b030b48ef9edb3aa89a144bad9c7e744b234d409 -193500 d03957be53c5a92ade2f6caa1e1999c3dfb567084580cfc618fc7bbc6758fc1a e218bdc4ec703cc01b2ec52b860b2bc0ad51b90087088c9cc0e58736d625de91 -194000 d50b3435b1f5fe763970370fe9fba1f0a5af9e9a9abe295e1e61d8832b43ffe0 6f3878f181e0dadfd1dafc8b2e75c73c6ae0fbf97a6bd1894b20aa93139cfd80 -194500 43f28b5c1af708ef1725ae8b0e4542dc6c6f33585455e6763038d93b37992cf5 6792e3e7d2ee64a48ec47e9fb86823aa726ac49948e3843d43ef80995a4ba7e3 -195000 27deca29e0f720fa505c64794b7904c2f15e2b2bdd539f6066bdbfa8b9cb16ae 53d423505456177cb9e6e39879e51b1a473abc363a6df7025d6c523f71fe10aa -195500 4996255d3fc243ca9b29ed6f5e7cb2799330bcf2c11e42ce9a82c017fa4dc47d 1ee2de24a628d83a4a9b796d5f3c6c65d0327202191554d0362ceb1418904a26 -196000 c3861c14add9fd9665a1751e1bee488a13e0156bbd37013e3e6a8da54da26550 4da431d08df43f875267b70903b275831281c28902749fefd4bbe544989a910a -196500 9e85e9ce7c9f969af748556cb124ec97c581e6ed8367c4c44e8b9b12d5495ea9 14f7254f9bf3d122eadff425ddb06f86c16c4a4954bcadb5e99ba6ea78f8f0f1 -197000 387b990115d39fb36240de77081a933eb7d4f8ae20cd72f0dcc162c496717a4e 69c3b4cee6ad5d2d315e2b133a716b8640b170a0f5ea53269343bf4455a886f9 -197500 0db48271823bfbbb62c8d9bb68a0ff7f46724dd251ceb8244253418b3089060e 0c2cf4682db25fe743e7e2781ecedaa243dda4d9944edd9d1aec7a9e93b831df -198000 c65104e71ac22bf228691460ed6036046fb091eed1059ce756e1056bf149148b 3c3f1f86ad2cd5cea8a979c55d01fe3dfcd5d6ec6fe485c3461d65604ad4adc0 -198500 30e8c038e2a43c5ddc9e0f3a030070380cbb09e577ed7d783b83651df9ad5015 dd0bd23d500ed9eb599249629cf07236244c001e0517c93dbe6debe262e7f4ee -199000 4b4e61aa4eec7a39dd94aae2c114994fe32185c72050d3908b7fc0860d41458e 0443985e3352c7ec9e83fc34187460671679f71a3eff263956dfdb306f4e518b -199500 09e62ab674ae8526370e0059097c80cbf382fa098e67d4a1175bada96d5d87a1 b78d27bf65267b4e1e7298efed4270582f8c9e26d53af59d73250d4862ca4968 -200000 cd9a04e20b651dcc4518ae71ff5b0c8bc2ed5c6eb3d5fd2196b1e636987c3a95 6160d970d27a8f799d74d3e01630761bd655268486a9107be28b128fbbc9dbe6 -200500 03609721a5de60ab9175d5cf5b9dc444f8c9d420b94814be90e39e4d5411f33a f1625e3d9d93f152c9e351928677f1e8cbca9c6812473c759de6216321fbfe53 -201000 f1be5c8c40f967dc2f1448f38a7e7e6a47c6d7e6ae9eae150762642394644f19 562f88889f723e4c4d2a7b0f8b0eed383db6aa34c8e094f88238526206af125a -201500 668f7b1463226ffe529002e0dd28b813c68396ed381a5725d166691660a0383c 0077ebac17ba34e5d77c492ce62473602d1010d21a99380380dcf52f1a6a3318 -202000 60ea6173bbe62b24b704cfe2b6e1d1995dc8854d618fb0e42e0c712110b70e50 aa3b08fccaff9887aed03778827f73871a658dfae6ad99b7521142cdf8e86dd0 -202500 6de298a7a2fa7ce5bba344237129f982b1071969df56c15d0ca2c0fa39f9c1c7 dedfea5340d820409423688ebf7c236cbead8e502dcb39af7686681b1f4cdea2 -203000 0e117900e8f0bc91b0279b83445b8d9cebb374dd81c84a52f0b3e6b94c880e1c 74c1495fb1f720209dadc85404e75bde143a59c7d21ecac61204734dacf63545 -203500 ee347878394b9da8a6c11dcad54882196eb1a6acd7e323154167e764d57f00b5 6ef1bef22de744dcac118ba398ca60424a713140fbb76fe0555f1e89369458b1 -204000 a687e4d0cdb3eb142d1acaed94b80625e8d9a9d472545ed1dec3c5e966db98b7 728306e941f0ebde00511bfc3a30e50cbf283e1850ad4145f2697671f14c5775 -204500 c813ad2efcaa352e786ef9dc912e133bb1f32fe408a54c114152223fa3c4e96a fefab4b9604535559292b1b31c4996dd815f25a8ac474cf8bc31d0c176aba97b -205000 b67beac20c8c3dc2e07c7d88d8bd4922b8803da3a5cbaec8c8b0a6601314df69 88197fef17e17da657552b7cc5ea2e09377fc466d37dbc22ff8a948509057d63 -205500 0937f7527f96ec479765e3be263f25130d7898056813dfdc67f3f95f4923f2c8 716b95c3c62dce9b236cba23dfd9dd3fcc68cd41cbe9d13d6f8349503fdc3827 -206000 aaa70022052f41b2195c68a4c77c11b78e1a8136f03477d310a57ffdcdf835d2 dd9991c1a086391127322eec9667bc193908aa869a012b36f0968270c8c679a0 -206500 7724e797f7f8e157fe2292c5a76a018278bd7bb95924932df289d975c4191c6d dbe2029b6398ed4f32b906956006915345255bfac82ddcd79e44848574c50d36 -207000 3d779550ba9dcc4e29106cfbd2efd9b22340432345c0df139ab31eac25a45226 cbe3c2dd884e9ed7a1dae427c3d475a8c9f3c8803d0f3507398b92a6cf5ddb96 -207500 5484677fb6f857f8009fe0e371280b61ba15d0a5fac08bad41392dec1f38c85a 649c2c9faebadeb93551828d590b757b444b6a54b40298519e5aa8505fd81009 -208000 cf31a458b286a4f77890e65d02cc506bb0454be9f373a1685f2f6b2b91a76207 22e9abf8f61d55f7fd7b85e0efa3d8a0f6579f43020b19cbe921a79d0122000d -208500 4fd3fc158e9219659c7ceea1c4f02bb89563c7524e9b8e9f158b61bc82c52881 4a0ec89610a1cbe8193dc195991742ac08583b9c86f9d24a5b63241f8da4b476 -209000 d54f4d0b5a8ce4ee97d0ef4cb455ac54b93b0092e177f1532e6513052439e9fd 59a0a1d9ca71393c4e4271d8d1ea63d8f0fa6e8388c610fe4bfe8362dc0fb231 -209500 14e2bf16398fc52492652cc0ef3fd516eaffaf2cc3b7f89e37f3bce63d1117de d9a9a12a655ef80cc830f766200a05617bb235555e7cea98818bf103a3a6c1ab -210000 4e035fb68e9d78b953e76e14a90355fa127db686af2bed4bdb301fc3223c322a f6916044d1b6a16eb726cbd05a2e900f5b9f828625c850cccb699327c22037ba -210500 e9ad24df7fe871c7a87de17e0c091b99a332b47903d8d39da2a18ccafe02dc1f f2cb48175161b22cf3369f59e67941f77675c6109590ad622a4bc476364043a4 -211000 21fc2c297b7bb7c088668fa502215ac26b2ded973796765acc4feaf2bff112a9 e21b83547b49382c15c8fdb2929711d49eb8693d08c0738813df68c359fa2442 -211500 a83b2da994898b752271b844f26d88d300646e04c4e89786f24fb4c7397ce6fd 4d8d8b7364ca603e61da4d09bc9c0b1dbc2373e65f5db2297828aec6395b5991 -212000 ab0f9dd7169c2b902f4762fce10983fe94e3c349353e189a510781244d66b77a 3ba1a0d61a8b8a750cebf79f5c00362bf3c909f11725bc9e9762f21de08a7945 -212500 b1fb4ee2f329a5664e6be5c85834dd79452b1f89551d599a70852bf49daec183 d9143da167a6553a85f452745577ee6ef19fd21565b09ed5fa6cdc00a0f01a49 -213000 dc4c87ea7c60026a65104a0d8a04e5540e3952df79a62e59deebfef6ae235e81 8da8a14d3971436306dba00351d265f0bd06b1f59005f94336aea44880498b5d -213500 2466c2e233db8e30bce3d5ba87f694c3095fd391b6c38c2edf907a4f97d498eb c3f5734faaf87bcaa9be69122a144ad1f26009d8fce1f859a17c2fd4bc0c2c0c -214000 fa84d9bd1c6575cabfcec73e1834d129821b6a94d7814d15d038239cbc4a568e bd1413d32f7719df41ee9caf406a30c8b97e2f875efe7c9ab2fc56555136b5d5 -214500 556dbda0caa051476bf896fab40e8854a166c7bc416d5f3121fe1d312369dd0c 4e5d7dafa56fbb04283e8c41e18697dac7beddc742d098bfb87d4df1fe90679a -215000 b7ccb76ed29ea49301f630ca5e9cf200ba7a9388156304636814ba6a6b417265 8392386752e5ac61b9856b95e9c833b57fbbc5717e93f63e3944676202df04e0 -215500 a56a071a789afd22ee4a9e4abcebd695a26ff824a895f5291ab639336d609bcf 6dcf6a9b561236f8f627cd567d937ca4d7e6e9df72d466fcbcb505af9bf1ab11 -216000 0e1a9b2d055f2e7b637d9fdeb778c040967a8a2fbe0a38ee57bce4e8f4bb0a51 c5532c221b5cba08f4ca281a247e98d28654b934c8595e57873232111c347ecd -216500 9890c0ab7b427bfa46ae90fda04503f1b17a2493c7b36f12fccf0dc010d3f9da 24ba34ff5619c38e4dc516e815af584f4c5ae6518a57918aedb59403a3b356de -217000 b282a7dbf2dfcfa4a46938422e557404ddcdf11509053fae49f5add5dd101d8c 645bf6456c36a43bef5c217fd00b1e457ae136d52396e504db5ed9a97e406594 -217500 9539ac7cca0ca0524060e3fb6ee956d28ba115c7ae3f54d5927492d0a43eb49d 21f680a60447675216989ea718c68c63361fab5615c683a7f047960d50ff8873 -218000 dd15ae9a3a001651303c757cdfa162b252b9aea2d1c4fcac645cfbc1d7dcbd7f 78cd6e280ca819c264e6447e6cb93c616f0bd03547259a0f23ae38234e907dbd -218500 6455bdb4441ac37e8f0d04b645fc033010698430944a873c2c097f7c0d3a02bf 466f4eda729538e0604472f6c00c4f7398a28c9e59c89602716f611ed8731edc -219000 a8944486d2a12285430d1764ccfa03bfed013dbff38ff5fada97148b883db9f3 5e8d4e1d9d6b8bcfdb3ca94ef5d0f8c75b9620b7bb5f360d8172e1becad9353e -219500 adad89636c4dbae0dc680326d95d5a2bec6ffe7baf704f26889730681328b3e8 d17aeaafa2e7a17d6aaabe48e88ffc53a8e61bca58de2e844fade3461f4931e1 -220000 69fc4cb8e3103151a20add15fcd55a9ee3c1f2cf78ed3bf9ddcd0692b78c2a71 25cbfeac28f67981d5d011357c01ad82e097c0d09e77f0746fb11a93329c6958 -220500 fb7731f8712f081c1e9f446217bc1882d62d3db40bbe2711a25654e2e74c6cb0 796240f85e38b57a751b19d648938d9f8f66cc8cd2e8611635832cec8d25179c -221000 488df413aeead90e34c182fe75cd71227be759865df577cc6a4508cda9f13213 bce1bde7cca72a43d9d80b03ea33c845799313914905c7800f7672654821a7a5 -221500 84d958c341c484ca8e85984cbdf5ea436fc1564c95baac52ec00e9f03d5dda3c c493d1eeb83f8dad5c17eec83e69277fc98e519c639d3c892faee2d6f80a5fe7 -222000 24f8be00386b9a38f5507e77e72cea34598910fb8aeb57c5d7fd5b8b082b1d16 77d77f3bc606ba0a8ac17dacf2d6d794bf655c58709a5e6affb1c2238149fe94 -222500 c9db027d5a71c17a32dfd7694775edd913f829900532a36cc673168de4b41cd1 c98ee6b634235506cd78e47c3c51ff7f20e2da5be5bc51c9269e0585a77f344a -223000 2491331dde706d72557719b2d51300a41185e0a231600a748cadf6d76cb97be2 f464bf83372078d78b37b0aab9e98a697eb07bca9eb62d65919635d9a62c29f6 -223500 757897eb0ef5db6fac3a16b4167e73ac300fdf2126d175ddbfab527fe72e5cc6 8033074e1db6b73e123b62aebd8983887d50385f70770bec207b628e9c945425 -224000 b07c519e796e7ca9ecf620e6437128ea8762b00f16ffb3f2ee2abd5973fc3b21 eb8135fbce4a5f3d73713eb67416be84d02239e85bf87dccd22763075438c693 -224500 4a873566e5cb9ef793cee37c09f7bc11668091934776eaf0cc5254cf8f565ebc e0b9c689e95ff5d675aaafc9916f010b7e5b9a13b201686d4a600c5516a8e263 -225000 b4b671d3954ba70856a978c8c173096a9db7ba168c8815730cb445ed0b921f7c b16288a5f727839ad38a64139741eba8f93f33035d294365e841e714927ce5d6 -225500 17279999d391f86406797119b105c9f5f6a02678f7c3d34d9f272c73dd77faf8 d555247b00f10b1b9825a09d2692d22129b967e1ff244d1a60a756e7b2d9cefe -226000 94d997cdf120719be0ea6a4eb198704a18baebdf13f65e28e51b49df7de1d861 d3d5f6655db1fa41b2f916399ed5f36246ad98025f6943480fe15e43b0a8a034 -226500 dd41f722e300bee85cd30450c9fd08c3d4102b1095f88617c10b100556c5da49 f43f89d4fabd9330fee3336ad9bf701601c33aad3abdd56eb6c164c21da1ff10 -227000 a0e48510962ea5a5f18c8d413b48688843e5cb36b8b74b5e61bf357b43334ec3 0fcdb763c6a77599a872c5baa6fd1ddd761889eca1c53e882b616dbe40de391b -227500 7f5337c81192ee64e2e1fd4da832f60ba2d89b0336e8e169423dd403d6f76a7d fdebb66099af9283e9c026e1e9a112a66af6e3bb0f657ef78392a9dad4768963 -228000 a8779b9ce01000a531f400c46d8930c487ad00315f0ec4ee8acfcbbd02ec9e7a e9b6fdc4d73e7910e18d95bf096bd5becac7b96a9989d60e564f1ac2480b1fcd -228500 074c0079bec868361a58eae22d107577538fcfcd531bd3b0516becef48d25083 b0bb15325aa285bc0890e24b0892efb113246e6d785554e59022c0917ee4c35f -229000 27c38d7adc92ec6c3b2e5c16ddea6cc06d25cf138ebd45a935953a357143cc68 f916d1f8fef52c7532988bb984eea0f136d7c777fdbab72ca0011b4535c91e46 -229500 1010ad9db0dbaf647e510b73feb8352b927c1170dd09dfa15fa0f5b9735852fb 7a7b2eb60a9dab15faf8e37370dfcbb6684a67faaf7ec1f50980694c26dc558f -230000 e84c9aa480b0a7900f557d49afdc6273171bfea6e6adee45c3c2c7408c7a172b 1f03b2bfbe709d7b411679979aaaf2eccfbf14b2a08aecb7139b191691acf77b -230500 1cab5352d167b21bf28c9b3b0f8cc821eda60b32ce9f2f77de5737edbf28bcda 8867625cb142e048d056cfcfe5627fb7ac7a20a83de0a9fc008bd4951ed7def7 -231000 a7e7ae0369d5839690ba5cd0f83167cf68e6dc9c5604feddeb986b17cd35ae76 4f7deab8e1ace7033b726836f01863f33677e4ecf1f8a488fb19b99630fd2176 -231500 3bf6451daa832303c2242f195ad2ee1a205ca168fe132087ff899461f29dadfd 6b87a643ce4a5cdee1f45ea3ee7fcb9b5df8452209970de76513c846c73ae7aa -232000 6e1ae43ba56524a6e2bda4d769f8ec8e99620690baed8d8d1764c3a42509af81 eff179dfdb3a490f2038514a8ca3c65a1ce73c266f808378d767c60d1a8f9b16 -232500 95589eb200430bba2e6660842109cfceef9a90889ab8eef7091685dd052037d7 2b8b93e3ab1fd3b12368ba3dcb7b087d84528932cd4fef51ae863dc40718df55 -233000 edef1536377488c20d7836daea81dc7b542347febfdb3b7f0e89ace9a9a2f980 ef9ee2dc8e6eece115a4fa188288ac21117d58bf45921924db619655394ef4d5 -233500 7cef0816722fc26a5a131003a9df2d08cfb005d752a7211cf52c6c27acb735ae dc9115037b26543076cef7cfaa03c2839378b0cfcb8b164f883f2f73cfa95b11 -234000 da363a034d807c2ec1aab013d8695631a0d24c50c34dc0db04286a1a53fd58ad ef5a49fea7936d6c151fb533277c19b7e2bb3e88e9351cec946bdce22c5ae5b6 -234500 e35fd8c71da099b9f3f1d6017c9b799b6f150e553ef827f83f84b4d62ef723cc b469f833b3d307d9f12fdfcb7a9777aff2c37a2ccf713d2239275f39ccdac37a -235000 903c98a140b5e8ce72a2571fc17c585544c4076e6d2b2efa8c58b635adcef6db 5d048227793f68e79facf5538ee5980089562490688dd1f929fbfd459edc3263 -235500 1e0c48356729ddb9196f9bc8cfff295e2205283e468534eb127eac2a8503612f 152dff3242d0914c503c8ecdb376d1cec2426abc09cc99907b1f43b31dc197b3 -236000 48c76115fb5c845fb7e9b8d9bcbe2270755b054db11cd6ad6c2ad89152607576 1420e404d7b541a053200034e94f9bdadd705dbfb57532c2a454b9b17c36cee9 -236500 76dbcbc51593c2ced3dad33d42a9f8c522f01a21383b227b0e6511c76363d782 f432ef854ed6a03b4809d3ecd8a46def940a0d251d09484ef1b6bcc3271b0f17 -237000 8c821cb30e183a3f5a3b28bff8b16d1606566e3836a2eb0d47f6c02af8d3f324 b4bd12526051dd6ba2a2d616a95212c8ab4d6adc18ac21822a57738eb8284e2f -237500 ed4f21e0bf654339e17083701448309eff81e272b89e00fdabff166cdf812bbd 9d03191f41bf9d7bfe65b5cea79e55f32c57765ed5909e11ef961fa56f3f69fa -238000 5af7f4d9b69ce00a56f5c7d89de2ffb0df0ae23520ff218ab2330ce4817ee326 509f60bae30c0cb7666f7baf33fedb510f3364abccfd0881671650caceca4cf6 -238500 e95df9d3b7bae4323a4562627b9926d2a3f4c152e93513f0b57d83ec88ad8868 9d0e160a8f87e36e9fc815538b27d8636daf94ae5c8701d323995054446ade18 -239000 17dd8f7338c85dbdbaf0d87bfa224d5fc13e58aa465cda17eed21ec1e5a13051 61604321167ce51b0c2043524749d385b40cf729814d88e0394149298e1d612b -239500 d10a85ecd99d5fa8df9df4aaae9ff7b6360bf0f6c541fa6e1c8d743ba350d1b9 085caebd6ae46fd58b66481d21579720316fca78552121f9252ff8fd5019257a -240000 dd21b880d234b770079e0478bddfc53646feba611a1858a82be2d68a5f70b5cd d0bdb4e68e287851256fe8cd8518ab06b2f8bdc30984ef27feb96cbf2625bd81 -240500 4bb3da166c854ac97920a04fff729b2da619b130b3b257fba10f5be47354faed b7081936dea5f45ae555b58ad83d42234183f80123236a1474f1df92b289dbb3 -241000 cad2acf8c8a9802e5c162170b2cb7112447b1b5bdf3184dfb6ffca5d5ca066f4 50a13b720476b0d72efe8fedb30d6c24265a0cef374e1de14df89e3488fd3930 -241500 f89869f168fee009c6b743da990e96a296823c795da2fbece16346aff95cc0d1 f1e24d47abbd5056f7d3fd322a882ef885585d877ebe23b86787fd8bfda5c03b -242000 8cd2957d89f5937f87ecdc188f5ad6b275768752b873f36348fffde02bfcc4bc 9e37495c487f19227aa0b4312458907ff749f668a3cd386d46318281e03497f2 -242500 4d84991c165bcd35c6f24e4124e5b93678214af88c683ba82419330162070a43 dbc9324659ca8a138b7f72edddffa009859cbdfe03dd397da0d897b40eb97efc -243000 99f2ae7beed98478d52ce8a3e8106262d777e9220d54159cd29173f823002468 f1af12a5aa6ba842b39e357a45bcdcf93c9f718992cc160e1849c693211642cd -243500 84b668ed1334a0f60f2b7cccd9a1bd05b758fcc1d3b6de13314b60b1ce8dd69c a02d27be36d8ff1a07ad35d80e1b2340c042bbfeb7ba7c0f4289eeb8b66ae117 -244000 58ccb25106990e5eef0f7118707b96402f853599ec51917347012350230701ce 989a5646dc6e9f91b27d9d3f3eee07de2267b5b62ca8c2e0faed6883f1d04e18 -244500 60b50cdbc1be5d94c144f682c62cada4668154d94b909100baa392bd914fabfd 15fe02c7705d1c3860305d80ae479410c94dbe8ed03f942dde09d3a3094163c5 -245000 538eb0feb39a02cb69f673a6707d23f80be40a922ef8fb43ddb1782d8bca83e3 ca4b24d390ad10642d096a14bcf8fd51d7135681c9a750a80144b107ea02ce1a -245500 8e7a40c1deab5dedd03f960399dd0a59ae92ed849f0288ed447307112a4679c4 fe223451b524113b6d13c696681af1a1004e5be0fcd14dba4edf5d43f1b52894 -246000 e5410e4186cb320449ee28882d9f32cd3eeb79104f807651b8dfa0164ebbef82 0a4203ec776383111ff8f9ff697c72bd8fe1203d55242790a9cd42086b2f6013 -246500 0c2a1c0920dffa7e8a582bb47b121ac02167b2015deacd3cc2a4151419dd8dde 1df603f77f223501d3036d16d2201004c712f86aed58cd0b3d89b32fdd1b2032 -247000 def0d291743461c8680127c4393f912663ea3e8105026bc76c315de3f7471a17 830d9dfbf53d41d49c1a28631361db55fee2284001c16395ed3046f9a9278212 -247500 41c85aad59b4ed9baa25743ed3b2205550292eb7e5e4dac974f0839053d0df75 dbeb22eb94053b3bda3520ea239bf64c51d046da08951074dabeb73b06cce009 -248000 e34f803c19b9214d128703d584947a348459dcb0191cfd0a3928447747b7e3cf e58a6b50690ab0de2e1d7e5eaac39e60495e7f15c0e494797c49ff0a83e80d6f -248500 779f30864bc7a0eff2ff65a65af9ef49ed7125f708e923cff6a7a88d661c1688 34ac76a53fca6d0daada5f7f12e339fddf5d654bc1ebe03267716822cbbd0514 -249000 46d582e130542ed696e49a52224757fbadbf61037d15182cbaee9d6895261d72 7487aaf55ca988670dec71cb5386b80d8975446ba57feecaf64b3cc9c52a18e2 -249500 87fdc18e9972ab01bd0f1c0314fe017d5b825b2a802da4da2be0c495e8a6c2fe 364509f6a5c984e616212b9a328735397515d8392c612f774a55e8013b80f868 -250000 f345e75ffd358b61924b0bf3fcf99156f97c1479a0b31c53713c219a38846b5f 156b414c9c8d5782e5ff3c541bae9a14641338757b351f8cd7340d91ffe7c8ba -250500 111446c3129d174c80978898f17b8c14c485a4c92396a8c2b15c76d7da4e4ee3 67bc454190eebae6062bcfbd41b10f18161d777d0c7f1547d9c922fbe59301e3 -251000 a1d9e94171306fd7e28559cfdfc8be43a89ce142208f0b4a4319177bd6e1821c bb9e6ac2b06ece214228cab806b96fafd12d7fab5899ad4b8f6c57764c04b65a -251500 011ed051ea80d7aa8c5631cc3f6c808582b7bae9533a47a1e9336280e244a66d 5ab6d307a8215f078406e4ef5256e86f30683732743e4e102fca988e3e9bf157 -252000 0f60353af5fa6f614467ac0b793c0cbfb723b48353e45a163384288db9039860 977d7256cf493f632575935a40240e3cbc08e8b82b9cb78666fdf4e17a80748f -252500 856aa75176f71b2613ce0655d8bbefc03739a2ea066d1a396f608d596de9214e 6edcec572883a3e3e60b10a312a59c1e4486a0c4a73f5726b7b3cd1fa5ad8a8c -253000 135cd797ea002f028f372b545ba294120d92fc0368996f3f0a4a2c3aff5e2178 f6f35b4573ebff09a1d86085a7c5ad8f5154bc67cf6f1b821780ce3f39d845c7 -253500 7e62b3ed039f164bd4b37eeacc05736f7160fbd8ab2a0ed7c8789817ba43f47d 92fe7b5cfff4d6c5fa17c317ba47417e2841e65a9a985499f3ed0ebccb05993a -254000 413a5fd20a447bae48dd74c04912c73ced49cb866c96a65aa447164084dc3723 dbdf24cc5fe71f376465115ace1ebbfdb9382c6a47ffeca175f7b1d71d077109 -254500 dae6ea70719a1798ef4cd7eea67fb84482f58695bbf68106fb1ffca714532549 aa0bf86ce61e6a6801a133340c93e099d26f06c45ea6a7d0303866d59720cd45 -255000 48686fa37b3f22077cadd219544c1d55015b613ec8c5a4c367b0e32a1d93f114 8419590a10c931fc7b06e4f0c9cd66add2783839c03872569a4d84100fd3ec7f -255500 3480ad9060e55cf444b9f63adf976cc48c8e68e9c5d9f2e173d30ee5e21f8e55 22d1784cfffac5b2f3587152e60a93c18c3ba34d5872ac90a1bc249b98aa17ab -256000 773459b90dc0d860e1caf2eeb99f85410a17adcd86b9c7a91e282d7375f69b87 dfe7baf5a19c7d41d0be344f1c0648ae6a720b5c9b50d1a1755908da38ca28bb -256500 5c5a4002c3f5675ed11fbe0d1640a0cf72150462b9f38f2b6fefa04e2d47e57f 504eb85fa2d5bd399b16262f3ed52330fd25eff4396ce7ce96604c58c835314d -257000 f957080ceb81d1ff1a57fac8d99d89f92332198d332b82ed19f116bb2e4bb232 2aa6db9a7e207b621656e249da6a29182bb6e77489137f185c4adc4b43c2063b -257500 124667d3ac4e97b204a238e688229f21aac351bceaee670bc86b048aa25a326f 0806775e04bc4c3536af5ee7c404d2d53e780775da20c269b0c52258be37dad0 -258000 281275e81b624913ab150bb6061bfc3d065c3b8e876c1c84c933d1340342804c f2a8c5a57fa4b177d510bd095fcdf765e7b4c08d8ded22f12c07e3fe85011df8 -258500 99b3f45ea656e722d919f59a89e1ef97e171f1422ef68fe6ea17e84496369d31 4b30ebda14fbb69dc80d6219066b66d8716e2235595125113444f28e2e0e3ee0 -259000 a3c8b1010cff2df85b748d06b4070653855a780fa89c1fea1df8af1b99e1f71f 611c731a6c76c22ace3e93b064a4f73f2debf5f63d270a9a3a59a7a46544d6ba -259500 6f80b9fc49fe6de69d6ca2ec1a783fb006b73c7e2fc0caac427088dc31d0b527 d9ddfb40c125b781b7780845a78f6c90c2b887b8c28a0a930ccd6ce7020bfd3a -260000 d3f3a0df265b13c30fd6d529da8a8628c98144abee10ac66feb2d98972e52f54 31ada4b62db504d84fed898117105427ae16309d45de494c4a266316f8225d25 -260500 10c9f1214c1a77cf5d4097d05a4ecc043d8db4dc9ed855892763104094e4a1f7 273762c7e60334efe73f1325072dd8829130ace31287493f4028fa9c22c98619 -261000 bed3ea15e53cd2a4b2f8d515efa665b1552ac7bcdd575048efb6bafa8b3d0f0d 3fe66c2acc1cef4355c4ae83ecb34597060c44da2aa73f0a51618f4f6956a8e1 -261500 0e9b83d06669715a10a70adbd0a89d58a56a853be8c6b4e6fbd3894fb865c224 992896ed5c5c7c262850a9d3f7b10ab729de8fc572190e0c08745ca9aa2a5433 -262000 61022120589859e23c0c4fa1f2650329f44feda0823bd30d597be34ed030c86a eec28d8aa336511816f17eb3cbff661e6fb35bdd9cc7a63e9ce830e7dc1261bf -262500 957872933b3a7c22e527930d65220a77ebf04077130f18703f4d9eb8384edac4 e267fc444b94c0c3e8312c063746af1e93887e4f9affb11d03d5728885b63cc6 -263000 e06e647a254beaeea41f7d2cf9d88531c5193df8a75d4f1d8df403e1c2a24309 5aa9aa86564cd18ec3e2dca55315b46958ed92e4ed8710e33ecf3da9b051107f -263500 152388327d812eedfbbaf6f841061eb28be5ed87dc9453402355d8d06c64011a 23552aaa4ce81d4ada113f198ba4c848defa3870f8093576be677c2e3c92c149 -264000 ce414cd76a86b1af60c778ff9e5b04c31464198d303c9f1d53126cfa930e706a 2a3acad69f31b7b30208aab2b1bd15695cfaca2d8aa20bb2751afcb5755ac0c6 -264500 d259e8637b4b48b373b6a1a7afcd89b1056e2adda59b819654f393e63ad2653b 31bbff6e4910bae42fb446c184efe8191dac8d6a86156568daa369230b5198d3 -265000 ead49b3a388fe07616d1a8e8c391d50dffa01899a7444df60d4d2c40fd8afaca 9fa60617a2f080f521628ef3d754f1706c464fb43a8282bd07ce2ed26994be5d -265500 6bacbbb516631a7922e9a988fcc5e102d6f58601085f09511601f4672a3fe316 4a5b61cce54e08360b9b2e338f39f45ae427b2cc49034fb0f1e71948a7eb92be -266000 b6993a4fddf6404fe544fddf2df238c999366b43e7a335b81b4524f9aed32999 91407232bbaf55fa658262dd6269b1ec6c620eefab326e556434fa1d0d64cd95 -266500 a22adcd41d7ee4df6deb8633f53d381e9826dfbc7709e68b7b1ad5d71e8898f6 314feaaf908e8a8046ab6eba7cbe3c97aa478b2ad93c39aee7df9f5a72955db4 -267000 d270af2ee0a98e7e407e39d50cf4cd22005faa34480d638e7a6b7c10b8d59e4f 024ad7c62e3a9ab757d4905bba29fccf5ef435e4471fbed49ef50f6f9bd1075b -267500 1fa94c5777a0fb5f2c0b89389d3b537d5d6465bfd432810fc173dfed7a666c36 b4e5805d093717d9c5d8766b1ccbf2791eb10118c9fb51898f0c49273c3ace31 -268000 ef3af0dbba05b3633b87348bfa9492b90d0c500f8427c2f83e485ddb4e326b7f ea130ea23e47338355b0336648892d7c09251bcc9df307a7f587d7a425d2a741 -268500 f7d6e8a528849da7d14e07869feea84c406697ae7a16ccac0ef890aac5fcf4eb 489c417d04b8a41f630bca15696e7a05ce36d4d216c04b1a6560db25e03e3cdd -269000 0237cc909ecc6a560183034f478c44d9f9fc96d5a0369b89d5f9510676274123 e84c666b3a8122ccb250bef7b603c2afde722fd985aa36be484e76368f13f10c -269500 d342e101fa8308700ee1a663fd05b05da014141725d0b3655a3f0fb15da83771 93daf70fc7af5e7fb37d973246c434cc834a37a1fc69fb522f9ea5b82ed2bb2d -270000 83e4f6c8831be3fa7b6b6a0aa13805ae107ebe64f496be123a4ed9711cd69065 ef10852638bcb24c4341161935a116bf5b764ed34380ee55243a35c938fef7fe -270500 557c88f51ceba0d2dcf7bffe8ee8cb308f8fb2f14998db8b6c23764d00d756eb ed1e1382a827b3dbee6c583053acc263ef365697a9325d3ab3bb60f80621b66f -271000 8cf965660be26838d4edfc4ee6c9e3f700c5074a0537edf09d19fa8b25f9297f f717dc6ecf1404858433dea8353cae36a181baec3c8ab3fb0c8eaf17e76f2f46 -271500 940439c29f8259ebd1f7a7a76f9cb7c34981795365d06cef15b272ceafddb513 e013f425e7b9e0c919d3a8a6e584fda18d798f64cd32003c79d1b9acffe92f8b -272000 6aa33a0d087f0a56f911acfa99469611ce6a9fc336e2ef2ede07c854c0ac34aa 34612581d8665965d653cd9736459b2708141168a297c9eda4c73e64ee4b3511 -272500 e165b1f323ea11ebff46a9365e5c15c736a639c87e0e7866a790c212398fab51 6e2b03ecf9ce016d375afd28e4895a3905c5e79e64a451f4b5863d6f8ad37c15 -273000 7e8e42c625a39262e7cd8ba81d6042788c5685fb7e1925556bb81d87f23fc9fc 60337941f27f0191f55253642397b4141c09a3796a2e8c972154c90847a04adc -273500 50d2fab64d92e6bd34396a65ea083c254392b73b806c9c23d10a64fa2046ef63 def5f3f2d73ebc5c90d4a3e5e8100e51e3144b63d3de0fed9a6393ba3138f62b -274000 86afbaf7b386a0a5ca9199f42849ba58e03c52c3e14e4796be5a47bca65c3e56 9fa018f6e78596557adb6a6294c3ed8c02e5b07835258d38d00714b662cb88ad -274500 f4a2f13cdd599a02991bab088d21e7d28d907caab124755cda5b5da1a0ac3514 27a84bde9f23b95957a07f3950a238602bd158eb9fc3d8b7ba88884425fa2eca -275000 a655f397a1362429e51239e663aca0a3582f4a984001c6093e48c4e0a2e05941 c3a045ee8c5239615793c006587052cce7d63cc81c2ecb2af75e67f3c53a8ab2 -275500 b3b6e311d0f5bd738f2502c2684af690e0f71c2a4c55afd5661d069e604ef3fa 0690d029ffaee874f0407d12906116c79bba67f9b8378a31334b25483daadf3f -276000 f24a85fcd91ad6a82056c8a76c2d3d5d04070ffd7d9b84a94ad0d6b8acc0c187 5c21716aa2a15d63d306717b47e86748fb203faeb1c6b19d63a5349176e9fa06 -276500 787f090210f18af487a5a4f9f284f1d3314fafddfdee64723d3237f55d7597b7 3fafdf028ccf9b4ccc043ab7159a37ec9740b5cb34847a6ef427e117ed86f206 -277000 b431470e16022c9e3e58e772bc8db6482f309cfb72a197a773b67ee7ffcdb756 894962f8fdc8091b4f15d60a3ea4de232e7921227ec9092e4674338c6d0907d0 -277500 d4f3d44e493b537d6f5a6e63e315dcf5031240fbe6b6ac65a76eb8c35f5db13d fed8c64ebc096321c5b99ff1d5d424c213c3e75d13375645f37dc5aa807eb57d -278000 4f76c78fc8d544c1e8a0d0429f7dac32c9f0857f906944503c80f58d809d25a4 eeb4b5d853e4a976e994c9e129bad662bd03d8f2c7e78fe68bdbd47c28480ba2 -278500 494b9880d486e1151d466eb73004b3f226ea90b6127a4aef1b3a90edffd4d0ca d9b63101013dfd8dac4895a0d5ece4c62702aad7cdb81a6b186e530df840996f -279000 8722865896dd4d2351ef4e4def382a2e622b1e46ad54b3940a16f5073bb1d844 2ee3816538cef7b1d029887af7e39d60cc1e336036fdbf089439f38cf13ebcef -279500 3423afaedb970d2a590a0f3e023906bef4110f1389bdf54e2c4620c36b72a3ef 3e7446b32ace025408872375b1f3111075f305cc83f615ff2c6133e49ac96d88 -280000 9cb8d7f3caee172f2a7b8b8c2bab3fd01326468f8b5932bb88921e06167a0e31 468c01acf084fd4986b21d1c0e1defef6a874a01b0ec21be66098d53fc4244c7 -280500 6cdf47d170a6a5e57f6a9cfef7f2239d4f15a61d5c37f5b44a72188aeabd541a dc58435982155aaba2de5c124a9f441a90a575c9cda3f071fc9c4a3c9db61c8c -281000 3228123dd268365939c7fd5d9ea6a151b6a95825ee1a49b9fbf3ab9f3ea45508 9320e6e8aef527e622e610ab13eddcf82598b3f2b744f6e90727ebbad920c080 -281500 a35ba852d6be87b2a614ceece176b04152feb39a95e52e641e7da7c1fcfd220a 547cc277e5a3fe410e5265d8622bf0ce0f722c39c23b3274458f7f99e68f0ef0 -282000 2533068b9c436719d1eadc4bd7e3e805ebd949d57e75cf5e0b17321d109a9a10 1ee93f862e7504974feb14b488a590aa9221ebf331beae0786bebbc013278457 -282500 47262c1b2c424270254ebc4ad32694e51ff4c09d8c8da9e944b17ca3bc734e1b f940a70f96d1369af5b0318ee86f9902bd122036ace273643a8aa0ae7878764a -283000 bbaa0da5024d6e74becb1d0d62b2aa4a8ce1c3bcfe27c587d3c89b581f22b893 b8f67f07d3e46ae0436cdbe91a4eac1ffd8a8de111cab322c4895423393be210 -283500 008c22a6e8d0b46e6c785736f6098de9ac43d5d1964b2103ab383498623a53d1 77b3fa5d6f930d2da8b1171725e9f6e7ac340b88637955083de8a55a0d129b70 -284000 6273a37ce3e5fe2c58d6b1bbc1f31822f9e1f78e434d62c9aedf2c6c18faddb7 0e5422505c2be9b93d74f39ddb43b8f2a6cebccdad41d3e631e56a5c075622ea -284500 6dd5efb7d0636ca3212a14ec60bdb9940d355e75c4c3890958c2120c4e0e92e0 8adad9dc3bad71a55635afc41505883ae38fe99f3c96f021137e049a1b829a55 -285000 7d49941cc51ef16e04919b3dc5c5ec87b62e98267f173202167ee9a359d8a5b8 d947bdd3999caf548887208f2049fe528335634f5762d6882d4075dbbc6c6b1a -285500 c06cb12bcc248f8a0c2e764e2c160d85ca356ba7235faa143eecf42f7ac2f7b8 7ef16bd0db693d3ebd90f3e9152a8cc1c420a3c57dbb6bf02a86cfb3b1d19dd9 -286000 45583c3f15ca70ada0a0c38923bf9a7c63a82d7be1a05dd2d3d098fa6040b522 d497cde577489bcf9ea8e08eec093ae16e80f5c58ea09344c27bf55b98fe3fd9 -286500 94f13e245e46c93614627914bf086bde72751bbc3f88b35877d73bc28bd4a7b7 83245d666cc2a32058839f630baf72c0d96977e7aa4fc400f58e75f2f9ecf78f -287000 eda15ec5157413f65856008baef31e5d124c511a95716b1f6b7364f5e3b5e75a 5ac1908f2739c718feb04686b434dfa4e7ddfd5213d9977137354ecfdf5eca28 -287500 9f7a944ae0a5d2caa33f72042e674d47334445b2f47ac89da38e29357301a060 b7fca600d7445e8470e57c18e2eadaf73aae7abe888acdfba5d458197ecc1e6e -288000 0853047a1ac1adb0d95427898e88464c078405fa22ec5def178eb5de7ad31e02 a3369699142afb6a7da295ca36953c883d67a31d3096d158486b578a6a585fae -288500 eab408ff9eb88ad56e302df11a2513c1dd7873311632911cfdfce5ad4f814066 4f39359784cfd3619082b590cfdef0d6978434ad01885e66ea50f2d96abb2674 -289000 1eacafb1bff01bc0489b29ebc39bf137d040e6641170ce3dd89ff6ba59abf97e c8d5fe21e49f66adbcfa0c7d71ddbd5bfd2210554315f1142656f3802fb9de86 -289500 887dd7480f6c7ac0983d66c8af20fde72fd415dc9341eb28e1c017cc0ca046fc 64cc676cdff6225d910a798088789b311dd78932e090292f289b965e35812bfa -290000 d537cc92d4d860c7d1e74c77d63543d1ee28bfccfb33a3798b8fe4ee6aad5fae b1422ca72d6adfc0c8ac92b75dd68b19615bf27ce351c07dc461e4a483a01d36 -290500 1f72a0f641f0e7c0a14ae8aa3a90a93130a302bc82616e7df2eac6cc893f8826 7cfd6bdf925165f98609e9ac990d9c91cb484a1b0c4f26181f519180b2cd0ad1 -291000 045c570b2414764749905e61329694b5feda76d2656dc07c208e0f163e8d8be6 ff11ec49560b7c1264cc610daaf95d5bb7f581edf89568fefcc83bbef13b5835 -291500 fd55aa9e9dcba1752e4c20055a1c9b6ac46a21a3a932f059ee574f49b721f507 3575b8d9556832ef3d4d929787f0ffcb147cb349499026edc50e4be282b15863 -292000 37273300cca125ee3ecca17ef0b26cc7880ad9b6caf876a4eb5f248743433519 9e2e93489d99a34477c9e7e60d7a971b7e7a14f2b1d1af1d797d95c945c26d08 -292500 c6d6356e96458404221b2fde26482fa42559dfd1caab1b600f045d8f6a2302cc 5fd0c22eecda0a4ec51190a6356fcedb96e3d4662a03d1c231575dca131b801c -293000 d3cadc149d4b135ec11e9b97cd25d6e1caac6560b16c0d53a798fdc191519682 e8fb2e323adbb30a6ac4a40239c68d2377e9c8fc2094901d694e0957b9815cb0 -293500 a0ebf3b0b17cd3dfce121b5a4466c2a60a9ce0169c79aa070efbab912bc0bdd0 c9da3ed914a818f8973e44fc8a4d450e68d775dac064b9baed30d71db09323e2 -294000 492dad282770f45e70bc4cccb1ff2d69568a4d761395515f41d53d0d703db481 7c090581b9e3e74b2ae80d821555b83a563442f01ec32994b87b8794c8a94dfe -294500 8923473c7806f6175ad2be0cc98c4066e69dd2acf8e7f965fdcefadbcdcbc930 689e66a64c3f66de762b38b5cb0593b6c0f076c84a04823cb1f927f5d6601c12 -295000 3d5870c04b03d0cfb60c9d47169b81aa5c669fcbfffc602ae51b930391d06f7a 34ef893941a5215eccb47786b0d108e5150cee56d691cd6d54280afa5ce5e85a -295500 96c1ad430e0ca606b9da9929ea3e6644ba7d42c02371abd5d1a1ae099654192b 8e03c6f39a7dc904f768bb459ba01c623791992208f124c37bc679e61a49fbe5 -296000 6407e9c420afe4be97d10102c8cfc0d7f5ebaac40f6d5e678cac8144f007fff0 d19593e2ea6bc1c13a6a3269bc9d7c6ff918f0a01dcc61daac670b37d2d80347 -296500 1f8d31ccc299f2c5b05e93383d8926862fbc09ca5b01085b3a1dd82d5d495d8b 31fe78d77df28d71d73858589dd74fd5362642fafc9c8d29ba137126bfc0fbc3 -297000 9cfe512e43f2cd52ff58f90464a04f076dfd0d12d59cdeb100818f109a9003e4 5e47ee43df09cc31576cd9b0440c619a16298d39ab9264f639b5b9c86f8af572 -297500 95a02da1b06b1593ea08b020b4bafdc67f5e176dde40de7a1feda249571e53ac 43777410c9686e5c56891eb7eb0c37f2110b339e5eefb75da0bb28b78f3072c9 -298000 0d802cbe03a4b85c23624a03bb35290b461d8d9dcffa128de936649b7007f622 b5b3a839917d03e52ba179edc51c12fe47a6dd9a5c57d678299387299219d164 -298500 7e4e639258fe47ffca25a4b7bc7b908cdff41c7e1a737abfd45fdea1ba62ec12 a8c88f6180fdb40fc4524197c5eb32ab9bfda23b88c4eda4a422994710030d1c -299000 d2980e238042ab1ee113dedd25dd97fde37f474e6ea666efc83ad169c7ac4cb6 5f89ed52f8866c340657985291ef23e18eb47e0631407dadde650801b632c010 -299500 a3f56b859e1362c88c4ff21ad8cf5c799c2ae565f46f15bcbd275e7cb0fbef1d 2a189688c70b29e449f6b3bc93fe61d4b2eef5af756039f90fd745b47bd74403 -300000 5a2452a4745eaa9cd3c1c42b7e4482193c4f7c3324ef185a4d0a403d2002c0a2 0276aa15dc1d6f0d96dde0520e357fb5ca4d8469115a894dd76e4a34d79b792d -300500 d02571cc76f7cdccf536b836770aa02a0d238cde89f23f767fde8e62e2648735 25fc046b62a57b71347be8c33dbe9d201af1efecf98e973b35294f32b745fe25 -301000 b8ef5fe2861b8750589ed344c9d8edc7ebb9630dac0ec507ce09bdd532af32b3 bdd32f8faa1bebe0c4d250a309d8e983c5444f63b8748eef76470b980c2542c1 -301500 573f412e4b6a3a7cd2506df938810bee7029b9af102e096e83861eb3b29647a4 e8fb5de4c13ef24efd099f7808c0952e287aa23d51a96d37ca919c3fe08b9685 -302000 18b4cdc5a75c82496545009007b5f488aaef67892f6886bb36ec2526f02a5501 c8898b9f003e3a651e963ce212412e35d3d825ad2170cbd1cc56bcb1f7a0c4e4 -302500 ca57a75391cd670c7e1ed0fde565c1c15d67ac4fadddf92549874fefc3a51c74 08a7221ce567158af54cd9ebb89e6cde68430c185f6ae18f1c4d7001970f0dad -303000 e6dcb8971d8b0e379173bec442b5e465d02e700b30a79598de9be17a5497cb89 41c38012157119f65a5404f0e62a7656673f033eb64e8cf4275bc81aa4d88805 -303500 e737b5b4805e4740cc8c50d60ce3769621294b1d20ea8b1bd3f3757c2a37e1b9 b5aba92d8014d56fa32993c21c908b42330c6ca382631f57162cc63aa1b842a9 -304000 9e5aa8da5821d8594bd9ed376f69dc851e5a7e0b4cdd755c6394f0eaf76d0e9d 225f9b063c89eac0ee1e3136e644cba4f65fbb475fc5a0e2c1fb66270f6f13fe -304500 45a43ebbca6f1cd31a03e301398c2e9e9d15f1bf91db745a7417b4d8f25ac394 4246e0afd88d5225b8ed8642d8337681f42952d0df01a71aa94d268790755cf5 -305000 153be3e755e4953c3810e08165407725c11fbf92665616c708bd3b824e973cfd aa39085be20fd4450a1a03bab45c09f669a0a50d84219505b7077c0bccdde28d -305500 c488fbfd55f3fc873ca49d57111f71aaf5a42c4bbdd720c0d96a5dc66eeb6736 546e53c9ec8cab56e41df87aa26122e2cab4077646b800b63134a712a1e3d543 -306000 83982570d251358e02e1b359a0d95b96b9f64f3736dd823654d47da633d48708 6a861e2b1c87c8002bf0794ea718b6be98b4d77ffa95a22a3decf18aa985bb25 -306500 96485ddc1d2d81f38a752fcf1ed3d7b734197c472e8ccfb0eb4ce3101a473394 068dc5f5f5064a475c7c84960a192433e9bf18098d581f0877066c60ff0a8861 -307000 0d209df0e3d2879d8a0f356f7d4041d6e0825ed0b33011d5c8db9bb1ec0c7d42 1f41650a79db8f7bfe188f47b7f1bb293ad4f178ad4cbea99d8f87876b68ce91 -307500 aad6c7f578667b9527223b8e4785e9a6739169528d9b0bb741119f224e0125a3 d56e00856dd907339c3959733761bf3d2ed206bdad2bbf9d49e8ce6cec4be663 -308000 1a02c273d30fd2bdfd3c0391715a78f6223c944db913c846927b8a20289ea527 232e616645960a14c845a721665ccbffe5a70408ac38dc2f9d53e306c40287e6 -308500 b5f04f2fd81500e1f7d817b94c566b97c38cddb21041bc5ad38757a1d11c3a74 5596842f2ec00ea253eb5a0a5565d21e871a511caf4a40f7e559d089ac67ae08 -309000 ec31bf5b86d611359ba7818f0926b3314c13e7fc6be4771e78aa66c65f308e1b 19be4c08d59662682dcf27d7cea164915e94d1ff761f8321d6302d7de2bafdc4 -309500 a40c3dc8a06147b339366c16bc1a21d4841ffffb9721f952276c35f6ebb0fc67 161fbd3c4ba1d443606832471979959ac0281462f897801dfc9e4a48d03df741 -310000 10eeededb4d54ad661d257fe3ee8b383d88ea175da4eca06cb0d2afd91d705aa 82535ab42a3a4494e51e508dcf04f233df0ee6869b14f12c2eeb3de7d0d9bfb0 -310500 5937e9322a0b8b1886bdd639f3fdea48392c3a1f3ce5c729f4300307b30a9858 463320d4b753e3deae3eaba1c7c0c81de49d883a7205d34efc6f933287bec340 -311000 106bcfeebd4f8d313bc06f691e30560fc6d5fd4e8eb2d3aa6e5e553d5d7d6769 efd1663f7e472207765e064537779ac8b52090326f6afcfbaccbcf0dd5c7cb49 -311500 81c0cd746d76874a8add01868bcc5465d7ff0a28ef2ba742b75c6c89986ca3cd 1e89778081b0b13e825bf16daf61ee16669826b50efc794cf871ea170399ca1f -312000 bdcec2a9a093b8c5e6a3f712c866bf78e720862b26918e7387d511de18af59e0 96fb2b8bdf01cf8b391a87158b880f38acdf15a6f761abe2cfbcbee83478566c -312500 a9716ae91f6c1577726c38cc4fddf8a39f1bac41cd1d9b5605e52184e573d6c5 4fae3413451a71a5f1e4ad71341035c582aa1aa721ded95eaabd734137ddfce8 -313000 cfa985aff09b9e7f22b17a600cbc428dc8e2dbb9c2b22420050ed8dd4597963a fc3335bb9389d77b4323758d39d7391d4896b94ad440a66b178b9366492fc79c -313500 959ad500e00153dcd9d8b6a8cf1190c799f69d3c5f6dfdff026a5d78ca5d0c5b 711b49060d7eee4f08a198fd3fbb3c611915c64cb12c8152210e9c4ffbbe9c0f -314000 ab6a7acb2629ccba949934209d7dc9cd895eacddcd7143dcd7eda19604ebe05c 3faeb9f09e3a75ed2247e4e6352c5744e091f5f44792ad20000721198a075c79 -314500 d9527af7b2e46e049c738a9d40f7720d8ac2e8e94b847cb8884d922ed004f543 03476229cf97cd0f2813169fab1ac07b9648a4dd86ea864feead69fa34dc498d -315000 626c5f923088c9093b00b846a1ee92657bae30a36370f679804743d1decf948b d51b5ca87ce3888f7299e3f2c0ab7f3e28afeef234f63337553c972f6e688be2 -315500 2446c74456b4b4b216b760d567abed176c12c2f474459d6be711490190904e07 23a8dd7d4d710ef6a23aada5e4fb960bcaff7873416c6b9904e1cf61c2abb0d9 -316000 32e55b2ff3cae917e3248bfdf7ebf79cdeb323cacb54348bfdd0b1f411c92186 ed4b4d67a3f55e5e3247f48d32ff231d24ef6970f8223e255c2870aa2ddfc92e -316500 634fd61f515e6ab677e142e73668fe41e462f25351383262b369e1a622bb9784 0f6cfcbdc1408b6bc3cf64c897fb67126affe7e82ac682707d90894d0c6768ed -317000 1a8b1bfb7cf59f0ea1d7141f2859a289b1cc0cc312836f5754121000a5a08dae 189e9b6ec139450bdf78eb6e37a63c60a13551e1b9d0ab737051cd5dc29dc445 -317500 d2d2e1c03ca763382245658d9e13d60db1c11199930c6edffa504cea704e9cb4 5ecf2ae923e1b0ad4bb52dda4d3c5b6ab31dae5a1152f40688992ac56cf7c1e7 -318000 14c481ed71e0265d9971041215ffa9d80bd9ae3d8a20bdd514b3cb15e6d820bb b83d25bc14861317c60d2a38c2cebc995004a3164e49dc4109d195ce719165a3 -318500 fb1bdbe68f6fa03555a52cc7c70086b585d1585bad7e7f36bd7849b20bd62d7f 56c93b2ec1e226511dc23b53e7c6992905a4c4875ee9146558712faf39024595 -319000 3d520676419671efd72eb59b19a912dd30419f5d50f9dcdc3faa15797e8b78ee f0cb1c494644102763b745ed186810fd2fd2443abbf4c8ef02dd42e20e344e35 -319500 e6f93385e77b36b8bd02e95a7be1daf93e43c2c15df61ad7a53cdf76581c93e7 8679904d6abde60c2f8b0628024a00f1357357852ea5e0085a8557cd55a3d5b5 -320000 edbd0041bf7c7fe4378c089724a0dc3d91bcff7efae1aa5a5e9b1d914d9f4255 83d2528f44d5537305cd76560b0fe1da24549b295e84a37ebc9f7e442f59a2d6 -320500 fe6af92a7429dc15ded665d91c0280feddee060e7a12cea78ab54f591a2a97c8 3840d83015f1c9053f2a74305ec9aaa4ab9c8fca66c62b71c898c0d8e40f94a4 -321000 09fbf5bf7f04579822b0643da9de72f9ffb4e3b086334876dd7ebd4a0b1e5456 3d01cbb877ed01843faf98fb687aedfdd63b6eef204d7a08e5177e93b6315237 -321500 79143aebef47a364850164688450127d503fb0b5fbbf6b3ff422a655973699da b65e2511ade0cf401a38d1089a5ee4a0747e003fdc2c29cd48e47b288d776801 -322000 03aa6946623b9252193d58e6dd00bf586ad4f57dc8fa04dee924b5c15d08d8ba 378b057486d0bcb43313d5206b5e08eeb06be740ceb84456f5cf8549e46157c6 -322500 cf8971a02d54a830b3729fb8f1d1c283135b1a7e30d5cfffb4462a2472467d66 233e6d4bb154d5d3fb1739a4e90a258f0910ceab33eaad183fd2108d8ed464d5 -323000 8d6c05ddfebc0476b7ea506c6edd8b1e7a1f04f46d3d44c404936fd8c8c97089 c8e2bb9126149c636285107b6b51a2ea4dfae6a9362ea82e9a01fc5b62317e13 -323500 f92d520784eb12d8ae3c11ad1803d5dd95a497c0084c88784702a5acce66ae41 81e2f522cc756b27794e1472df684a598aa925938ee87027d455dada0d2835e4 -324000 4d33cb6af695638f89500645f741981a2b96eb2b6f1361cf4915e9df14639412 0d5d58a71b6fb721127f551a4744091aaafc4740ce74e1e094783488946bf46b -324500 9cd5a93ac51080a0a3dfa6e7612adebfd307a7c2ea510d033368490c6d25b7be daf9a838f7b869ca77d3d1fbfa8631bd99aaf46967802148dc7e44fd261a530e -325000 ea1bd97d2e59f6bddba189466ffe1e7be63f5574f110d5b87ec3e0294b2bfe5e c4d8725f512f352599b2a7506b3c52e78012eded7fa5f6bfd99058046342b2a6 -325500 df8156f044118b84c3e2482e346c5639a19b2f1583944286cb9550931c3ca0f2 4310bc5bfec110e5da8fe1dc798b18d1b1453895c70554fb4d52dd7d6d7d813e -326000 d46ca9a4ec0e9126c9b570d00f7b47a005d51f25d9fcbf0c4ca71a29a5f255e6 426c81fa951ff0ceab76207fe576bad3be2279d802d5b95b45881c73827a1241 -326500 603728e060b7c7cfa603aebb548a3362364f3ebd83b07742458a412777ba9259 16fea467df6f746c0a430e00b12d568c7103829328a2bc9b57fcb55c74a66bb5 -327000 6913cd3da36dbaf5c6d407da68f46bcdabeb504269ea70c0cdc219590355796e 745d85006082600149a72c38c32e2d378917153b7c8dbade476f6ba32726c893 -327500 b6538b2705612808867fe5d1da0fb00b6257c3a4314d327b0c6403facc8c06fe bf9d4d5ad9f15c14615c36f8cc7ae29defe64971c5824f95aa535c1bba7083e9 -328000 ff013ae3b0bf04df355f954637c6ca2510479c51180977a99af805bcc8c2d63a fad93d54a8cd267fd2e63abf1da6b26f2f9bc1febac401d4731af0103b31fc6e -328500 ab64d04f26e2164824afa50c1b5592c172469531a20f35a38181993a087a5cfb 24d35a5eb7accd3545888e4c525742d90b01981447d1c2969ca744181e4d6b70 -329000 79384d9bb22811755a4bad2ca7d238243ad975b956019cca645144215ead0547 295fe151911572801c0d4e1ee4e753852edbf6078d7bd798dc5e2da10692e7a8 -329500 1839ba9cdb5db971f72defa707c006ef6ebeb93dfff2bf36ce873acd327531f9 a930915c8a7d58ab4774dffb87fa36a6f9b513b466bd73e5c96965f85ec3300c -330000 829b9c203a0c146c2794aa0ac22bc71033ddd15a68959064526afc2722febf94 e09093eed9d282fce0825778bd7d2c9415fa5b9adcfd2263e7137537d861d29b -330500 740e9f27889b06a301e355ef7dee62cf10dcda17d4023c157c55327420b308f3 a298a8255a0b30782c5d968988514e0437f4cb34a0a2f7df8475a18809007d1e -331000 e2a4cc3a53ac8a24ac52f6fc574d0e9fed0d240710de0694ed5656abfbcbec46 74e67ad885d1f874c4ae7453085f29d254c684ebc71eca3af50f3278c9e1c266 -331500 afdc42adb73a6717f48e35b3b51bb13dc6233645b8a4805723dd771062dfcbdd a3988534eac8b2c3f5d557d1277440783c624597b8b922df33b6fa38b824fc33 -332000 4812ec71190df534e5d8d4965492cabc3606e51c11e4f9181c470a779926dd7b 3d1fb3699e9f859472fd032915cab01de53232e123b1e4c93db2871f7c2aff6b -332500 50ae97dd398c25069522d5eb3b45a2332fd045f6be4d615c7d36c7ccf54c6c18 0bb46697d721417a2217fb4e632513d2ff82f34287bbdd732b9e2f893ac10df3 -333000 fdd8f58aece53dd4f24881f1007cbd0ed25d9f3c62f356a00dc92aa68a13539a e0ed76c2c22a2e784c8a689e1032cf00b65a2702f2b3f025c78e2d1e5190070c -333500 5ea2791919a4000f9e363e277b7522fd9ebc9c06ee5fd9dc15e4ca8984a2d8d2 69d3bcbe827a926dca144c589eaa175f16b6e523b487773b93fee7b45a5a60c1 -334000 cac1a3b80353133e863014d138b408202c77a5759cfc5642546416d73f66ed84 9005b02c03c93c41c6c78357f4323a3234bf12db1eaf36e81c1077a324f7a07e -334500 50861ba6d952e1f0fe4dac891ff4339ac5fb7094205767f2d6233941d2821c10 f77408c3140c620c63f8bedefb370397dab67077b4168c628d787d5b22419aa4 -335000 594b37798c188fab76d6d65c058115b58757893ec32173b45bfc618e8c857fa8 fe50dd76cb7dbe52cc6a9f6c25a3497dc5e4d141e59ce1bafed04367fb155b3f -335500 69b0bd40b74e7fd15be354b734717bf197f1800bec85120b26ca21ea5ac0255c 58cf057f1edd07227964239e7d220b4a6bae95793694841f7a06479c5e5f7420 -336000 71631092dff7d8d09d44bbf35c187c7cb5521c7a5eddb1422f790e52107b6797 e3bbb2e549a6c857855772ad5317902ce52231c464fa78a107811c8381629a49 -336500 ec3497d60fb7d85cfb349bd96712903aaf8a86e6d746f8187a54a1aa5b7b3d51 dc276fdf1858b7a7600213f9b06d4377dc53ef54e112efc864006d28c6cba3ff -337000 70b67fe1ffc39b65d7c3834439efd501fcb9e5d31202322a878be2cb78f741ff b91daa38e81b0b79bbd48c50f9d5ef92cd965e729b075e10b270e29effadcc3f -337500 c5df2f17757c5cf77fc421904662468bf003326049de85bec43003d97a5fc47d 29d4cbe540e3ac54271d12308edae379b59365521ee2f09a6585a82a046d7550 -338000 60ba652d7ad31c96015323efbe454694c5ec72dd732c8f4578ec2f5d072afbf2 2e3a1bbd3ea4e0f318830e43b20d53162ab6b6fbd2191524725965c549360550 -338500 c898aa2617812d17eaa3f8ee142c3018fe2807862ba6d06f309b3344e7d799ad 6bdee06900bdd6c83f8fd8538d75af113af8893ff99cf9a25de6842d3f0d9889 -339000 e0d97756042e78b1c14495a68291e5033c39c56f37a48adaccaf350b12f59202 913f62e783258b88638a7c42b2f403328b683f8c657520ab723ce2196af69666 -339500 1dbe406aeef28cf78b7d43eed5fcdd8c9d7d6d11363cb7e595d7bc1d1899140c 8cee4f37f98fc3da1826dbb96aa525a49fb1fa6db5b2bd64dd3bbd4fb7d6c238 -340000 99ed171ddc0aafa8a5b6f9e5890822c34f6ddf4bf63f1488afde10526c74c8b2 ffe05de29a9901370e815a782c7478c3075f8444ff473b20ff5a2ab311a63022 -340500 92da105d515c1952ffbdcb5f5b99acaa565500d8f4b6e45aa093b61ae53fb7e0 852c42d37d42f8d2c740e57b8e9e769e72445f57c8fc9d1f91e62f029d7d985d -341000 da401dfe258750911b7264ccee0de1b53bd7b90f63d73f46ad5d5914203b59f6 84e7b57cabd661c1cfb68407595a6a9607e0dcaf68f74dce2f8487b1f43a6ac4 -341500 ada69a2ac0977672d08682d195934176caaa7de0baae2f3a32b1391ebf550eb0 cc1d077aae6a1c18f60c874525182f8cc211cfd0a851381773cd0166c108a43c -342000 ff83fa02f1e15e52a1e6ab3f8690bd9c4bcc7f3adf77dda003c6871283b695ac 5983b9dee33342727befc15d5982f9ce987ccee38fef71c34c482c92e062308b -342500 cfcf80f28aefa27c6f09f71080e4af7bfb33f94d1c47e80633187f80a806c6cc 08f62f928db36fa7757f30edd40f93c20dc43c65c693ca5de4c87467d40377a1 -343000 55e1b51f72f048231b675c90224571930a59146003b4ddd3e883bcbe4c8c2685 1f6c53f636480ebaac6569f100e804de9a604dc1bca0a626004ba9852f2fb546 -343500 3d1f67b0a5d905f15f3fe5a7a07aba456ce3ce41422a3bd94f92fd19ce7960e4 4201088ace85294f87bf646209d2e9cea09ac2587654d57c8105b016ed3adac4 -344000 1e718e4e82839b50bb5409297dc94bd783264f1bd3da639f2e4b5444c6765025 c2e0bdb2e293d2940f99295b59d2fd9b57a02632605bc66e4ed69de4e26c4afa -344500 aee9558284286ee6de93a1456fd3cf6c81ff542b4c1eac2c7694b869742572e4 56b70751d01bc1925f288a0af1223f309b7bac54e1cde463ccc9667ea50c9ddf -345000 852cae52d99ea4f4f299f1b5f4a7629ab0d32f8693f503cf74a1f0a31a9a80e2 a627a26363ae216baf1774585d1159977d378f34b54119670620bb82cc9784d1 -345500 09a3e1f7d56b1662f10470c2497e662495b62065364f40dfefdf8d34f5939fce e4d96a1576f516b5303b60dcdded21cb4e3f382f4e7c4b10399ea4b6fc37670d -346000 3dc0fc157c00c40ca92c8125e818f8b5c6163761b0c6955a88eb48498b1d6a45 6f60e0950cb6f6ad48e5b56e9e94a680ac85109ea90ff94df6ccb58adc44d3a2 -346500 bd5552ed2748d686ed3540c52ec7a0f97b839254c953074357fc019667d69188 d1707671c71c75edd986ed69fa0d8462f1d7aaea3e0b5cf519972cd3ce7d73a2 -347000 68b383fb101b4ad08a4ab58777b9f3e34c69143bc3872785c281b155de8769f1 0105724a536021bd7c8fbf2ca7e433c247009c97aa48a8688dc7c9af88018688 -347500 af3af4870dfdc980d2bc5c946e773806957c2f5d98200d5e9ace72e4301d0ef9 20b564b903b75c62b5c7bdb911c753fa67a547a47d47e5a60a0a4790362adb49 -348000 e72024ff3d0ee72f4f78b7e63ade7a7ea037da43bfa9deab400f6739fde391c5 c0ed8b08b6b7d50bf86069b1e8f6c7c36435817114e27745be63db96b5f716bb -348500 1d9d9ad6a6b1a8d5392aa6d35a7472fbf80535ee334a043025cc3637d9894db9 101e9ff2c05137c25a2a270055264bfdcc81b290826d968ca94de4038f791790 -349000 bf0cadc56a8359bb703738a06f7a31b305fe7433989e7e4094f379511e27a19e 2a2cfebba2b09215327049cba461b4c56cf54cf31a0d3c6f8b21a637e6a4db5a -349500 78065cd5e2af5a3a4e838289be5d1460605048c1cf2fd1ef9ba8c88619631e91 aac94ac665bc7ba954323a07216ac1669f19bcae1541459f41534d8058dfd3b5 -350000 937db7a154c0d4c5043fe8bdaa0969670f132252a6c6bf8f7ed5858ee11c97de 8c276300614c430a75552e0cca7d83834ce7bccd7ea1d592012300ac2bc5bc66 -350500 6ebacc5b6fe9ff0e34d64a047981fd170f1b13d40139073e6e65da9a617fbd18 f181abacd6038099f96854c2c0ac8f7d19504609f36dd0aa085af150f21ef930 -351000 156a0053ebf2ee2e68a7ef337edc14044503653188c60669ec924fde43c21ea5 dd728a51d7f9e8f04e74e2116698305470591a6e7937b2c4b714193843eeb584 -351500 5cea6cb5b1b96a2641bcd705ae86c40ce7a8572ff4d6815d7531ebdbca13b958 fd4148c5b36775f35873746e962941ed43d95db28ef21734f4351f1d8a69d012 -352000 43dc3dcb74fcab2f5e90992eedd8a7719f7b7c7658b2086583ef881092f88aa1 eac1623de8acd8fd497f9da85f85614f5cd02c69aac6044f24a3685957009f58 -352500 6b895134f53c26c0b24e9909472962abb3dba5f8b8ab65693ff8e45b3b77e566 aa1abff115fc49dbd6847ba4779ee7c514dfdbe3895e7bc3105b74d0fcf1f4e4 -353000 7785e099822d5b6bac5c707ea57d5d2cabeb52e1e2d82619c8bc2051b486767c afcd99c877d144c3253dacf018ca36e61e95761e44f993e0a4cee0854a7030c4 -353500 c0790882442b7ad61aec5a64faa355a8486f8112f9a691208f38e9bc96230492 f7888632b88cc7800d381774153c34626ff63d859ce489286d9fe904403e9ec0 -354000 de0551272a32e89def017385ba1833443c4e2ec02196c33739deb8bac6cdaf25 78038315c2d8c142ae67a01dfb98009847380ad96cbf6cf700af8693f6260caa -354500 c2e4b7243560cd6e4511d175e2c3fe98df223524124f44faabfc252f57d503d7 1d0fc9a93c812ad30f81462a5ce1fb62d74f14a1672e69dee3a3b797fde53270 -355000 1a11051121727fbe8bf80391ee403566e3b0dce4ac611b37a516c7e3432aa231 f363b96bad7663c981865cd98aa36aa2cadf8b4a623a030e3c7e8a58dea81992 -355500 c877ee5b39b2a7ea9723e1c90b2e307f861e42275c826ecf5b6c84f97c120385 d7cc21f18f45fcba316afb516f70ae028723a709a1a0ad2994579078aec10ddd -356000 4226d4f7d74316c4f9baf33868b492a72f2a2deabe02b5568ef40606641862be a364b4408c45633b64ca685f42f4be377a4b730fd762f28e0015e2ae6e23b0e8 -356500 f0014d06574914b9215379d2b187dcca46081a5fa27d6a32a38efd382a9e945f 853c10ad51f992a4bf0c46c8471046641edaa972c537c8a92b32cc79ff80b445 -357000 1c78c05a5a6c50b6d0372745b8a3f0ccbd6c4878e5fe2227c81bf36cbe31fede 118150dac00bdc45c95b36d35a57c63379205cabc42f8da5d8cac3f8198df0aa -357500 44900087fce8f2c01a87a2ab15befccc1d9b9e702b17c0184cda90876a07fc86 621888deca43a1398ce69ef2cb1ea7523e563dd552e173c3af45eb3f00667df0 -358000 40d642581118288429f0b72a73930470989ff443944b7215edbddf7ad8596d31 819138d682f96c5be33a73fb51c7b698f347c76086d468a3cec421b5ded9bdef -358500 39f707f88dda6ce8bc39c64bdad9d1fe29f98b517080ed55466a8a221ee19bcc 30d012c4929eb3131b7f50c34986d7e1337b46ce6ae7065a0613ba6ad336d2dc -359000 8a04b19b8f068b14a987511d635cdc70ea66e37b63a5c3750bbf9bb2881439ce 7d053e5b5d919b21a1ca21dcb5d31126f519c76f8c0d2816555816496229c970 -359500 15293eeb7f425f8f041248d3cb15cbedf19eb921389a4425b8a14a30d9f6f08a 5b47bc2a1eaaf8b83461d28c535cb1b6b376826c9b554df7498216cbfbd5e76b -360000 37577d18f84202e74e17eb9fd38e760dd94096b4623917c8fbe4eb8c1fe727b8 985b64f248199de5acb5f6dd54aadfe6b2eec0580ac17701e1a6590b46830cab -360500 2db2b88ab382de78f62fb710454fbe0a9e07dc7c09ba76ef26bf72e4768b8cfd a1f4e7d6f52f1fcc610793c0822a6c9a40e0224deb7e56495d34ead537fe2fb5 -361000 3891670905fc1e7ca588a4b72a30c57749cb7c9c2ed47907ed3a69c7339caef6 164eecf5a84889a1ce42accb7ffcae55c4bf598b13720c34eb403fc849dc5801 -361500 ebe6b83861d092f8eff3579515524a45568c743e7df656feb775c45981251891 ba453dda58aa37da9c4babea1597815a99cc4bfc9aec16fc3f8ba1d85a031574 -362000 8524397d4612f5acd6fe921ca9de4e9338e2f74221d4d1755c3682fdbb2bdada d9de4ba457b0d1ae37a2dcb9c8d921acf206e96673d45346ff85de620fc08334 -362500 244d8c96246dd1772efa9b6dedf90ed9933f9a1fef43a5a61fb9d59e9e19645d fbd24f0a05dad2f8048794e8f0c48aef1d9419e28e125ead88eb1127bef72ed8 -363000 2d0854b709d2c4fd84c1d66a736c4148a3b1001fb083f1acb38aa34416063487 eaaf97d25a09d024b71fb1dbe1935a8cf34bf0d30736df8e9a7b6fcd4fcd63c7 -363500 eb76872dee58ba1a3285a93cf5b257a12a903f9f628828bde4dd320ce44ea11e 2145d5e2136393a6d205af57d6544782db4c701b6a5b3f14a90528f30cded69b -364000 043d7b87efe77f8f2d34833a08544e15838bd8b8e1bcd902d8b1ba9dc30285f9 71ad76919b65882a929954ac642c401dd8f298faebf7208aa01301815df4f32a -364500 10b77b07108cd3c1b5166e51eae74df84f39313508e8093af4fb5a5c8db99c8f 9738d20593ba72b8e0f80a8c960f343846b639d3b5f3ac623ab7d7d0258e8c61 -365000 a88f0052b9b490639e238ed8d2bdae3ac573c598eebc036fecfbe8d0d651cb62 806193a3ff83178e6847129340bc66f087903dc85e8d45d50a3843511625fe4d -365500 07674af4f751c8a09011204107b77df887eb0989580ab710bc28f86e1724b972 a59376d69d1fd2b3601728c2eb2f3f935177f5abec94f9b441a6734b8c9dd57a -366000 e7f0e9b3671c1fd8ac289879d42ff60cb2decb8c9fb8095152e444d183d33d55 f04e0f59196d771ea62c59ac3882474ecd053519d37899e2ce9bb2d1a779b3d1 -366500 28fe13630301f2809e429288503e7a341a536de22c078ba11f5056400837d18d a3a2aa196a595a7effa0e8a3ddf8197fa3837c1a55a392f456bbe2745442d844 -367000 066c5da3bfb95638c9b0c37cf99fe28f31cc4852082933305b1561f8b289ebe2 4d69dc379574aebfb8c507bc6791adee838a066e7de10e2e5d633faa6aaf7927 -367500 ee383e75691d5d76bd0d84fb2edb77a9f3e453fe14e3a0840524d4966eb3bfc7 addae0433c1a0e30adaa6bc21dc08c4c37c7ad6d12109458cc8b9c3deb4fa80c -368000 7718d30ae93a53584971a1aae7c71b99f17332702adfa3ba93ac53faa3131bb3 00d48572249cc7eb9929065f4d8e5a4268b69c425ab521e974066c7a15ba96eb -368500 49160ed17423768caebf15a07b978b51b9a50f88cb934cfcb2ca335db599b313 252c55080a47e986faa7b8e8321239a25b25d5109f3b60cdd66c2d7086c32bed -369000 2a35afabeb4c08f7e0fc8564b016b65792e64b6beba78e5d7c0641af63530170 08264c57b5533fcc49b365920cb2d8b698be6d412ee0693e4d78d847530eecc2 -369500 003a85d64df7bbbe1692464040b072934789d092d6f866338b0e9427e823a83e 7084540c646571d0af1e383b6753e92aec196cf20c88bd913e074ff05dd63502 -370000 434d40143a0e8d8fe2e00984effc5579bd3661fdf33dbd93cca7fd72351dfafc bef78b640aacd4fd8598056dd42dfd6557355ba44f18fa9aba104eba4bad9738 -370500 02cf8d2c1db6faf3e7755a2b3d144a4936dcd9f34214f1c8aa826465cc3918e5 24b38a6971f48836c71e37abbeeff129d21fe5975302103ec2af62a337c33afd -371000 2534f9c4ca46fe2df863db301dea97a3bfc6e5a3645f4080d221e9fc214efc8b 24faf019a5e3c38e1e9c941869b93a6c5bb2b2e3e3c754c37d83bfe009f78c20 -371500 1c3ab21bf75be98963553462f21fc369e7503fb8699d9f6e1f635a952c55db42 8dba0c68d6c580055ce406b81e3262b9c7057ba8cbb8b221130766e667c878a9 -372000 b7d862d978a007b9e4afa1f2f0650bb20c0298b8bbce1666d58b009c07014bed f070560c4db4d96f47694e25dc96746634b3b1f172ae1efc8435b29ab083697f -372500 aa2c34e6c03803e0edee9675926dba87db1bed0c89e605dc40c2213a330e53cf dbad4244855f790740309f5f7e49755213bec4d672cef6491758cba12b5571e6 -373000 c03556ea141010a523c44868eca127684b01e83f0a76090906728aa34e599931 b2d61cc71ab0b18171db2117a6d535128c25e68031c3c44c059c7c7965d05c53 -373500 b61ce82c38d812c1e72a830b062bd3854701409fed42cb8cf89d9c83a68aa4a2 3cb1ca2e543310ff8d22cba4bfa2973e264837d2a4a5052cfccde4de4a4a477b -374000 0a2b671cf0c4e82c857482fd9eae13f8212fabc508c3f6137fd3004038d2fb7f fe35de23fa234b6dae59ea82cfeac3259eef5f8d8878aece906a9e71121ed71a -374500 31b2c402de5e4f0911f5d14b927f38483fec9234b0ef67efa026a3648ffd12a0 63c1e30437b3fd68e0529230da7123339e9b8d2079576d68221897e443be0e3e -375000 1673933d5b2d1584e3c923b45bacbae604b308007ff19e25999f5a1d89afb040 cdf2c192e290686651e7f63bbadc54d0d8f7b1d2f7208a097807de32159451c2 -375500 6b35b7e04b2d788de6e2cc8909ab7fc5470b385905dc0e7b7b8524ff57d7d7d3 ce795b401b8cc3db0def999633c2835436348b032919c9123e1481800aaac88e -376000 9a2ec84dae6c1b6dd358c57205e0858d987b68bc1e029cae1b8239ee5ac181c0 d576e0d718d3f594ef61eb7be25e4083d1ead1201fe8eaabad00c63938144f85 -376500 bca044a02b4bd78ddd32eb668c603f16f14daaf04cf3541d019d3421868a14d6 9abdb75f5d7bccf402e2e02a07b5e6d5205822c4ff20ff5531d29d4a8cae5d4b -377000 1b4b732e1f4b18b744aa40196b7bc5d3e1074fee1beb4efc674e38f16deea7e9 04755ac05c88590c66be5b72ea85735df901ee644ea1f35772b82bf18c2eed13 -377500 a51b1aadb6f280e7c23ad430b8c59c8067f0b8dc10a0be61666d1da71bcfadda d8eb0789d6088438ddd828d02844a644a2102dcda7614b262daf994437be74e1 -378000 82f6ad88db9e44f44c837c7a117802a6bc4379ba9141c4faeb9e7731bec60f35 8c48f7630228d3c0322986552aa96929eba1314f8c62baeb801b95cd3cf400f1 -378500 c2fbdc981504762cd306473faab285e108b27bff83a84a1460bf513839d9ee93 37a18476810b603df1cb7efbad84e3b49a24676073397977eda35fb559e7dca7 -379000 5866ea5d40e02e5c73a1828d3c3bc5ffe23f9702292ba595560908f66b23366b ffd0dffc4b8703364b9885055b427f2bea2336714ad4c5fe567e1efbc8fb7b62 -379500 2519dfa5eccc5f59b59c89bf35ecf2aa0f5f8b43ccb098622def88dda5177b36 56df546c0e7bc87f0ca01ee62f0d0939810749cd5fe68fa4848f6f302052ccc0 -380000 7bfff4292f5f17bc71f6763e2257fa585c6d56470390648079609d8116988255 e5c4c441e3a8f0b5f55bb8f5ad18a9bf4bf04719a558e2b954109e5c47cb9896 -380500 386869e1fc8e3f7d6aa8bf28caac3d5a344330e974a42704885aea3cb459e179 279bf20f5fc0c66f97256a42cecb4597dfbee3eda52cc03c01239d2be7ce0e0f -381000 86cf8da3f13d65311d707cbdc932a563a44fc12e1c43de337583bc0d113a5a03 733b60f69120d3ba845a388871c75cec4b4e2479ffe31d83c0bfe980133460a0 -381500 3ddcf06f6b302ddea992508dc99ce57c1a7922d05a89decd38668c974c0d3d41 145aa998b1e691947f9e9c1f9d7bce235dd64fb3101664f2c310b59479a49954 -382000 5cbf96c1818addd8739c3b0a928605824a71eeae2cff1f520e644096662c6d95 0282ec673961b684b9c2c43f17dc47d7a1c4128a19b4dde559103986abf4ca50 -382500 01447f3299aee987ac9c9294682b89f9643f28bf18123ce8114b3ffdb6a03c5e 8a0e1f6c67098b89b81bb0769c520cb50a87299fff5497a87486417b43efb9f7 -383000 d5efe4b385b101b754b2b30f6f99c2bf3736e9fd0e5a06d0b5ed3064e7641852 245a1712512d17bf19156fd5288ebf706e85ba49278ed03c2d506364e7002e08 -383500 5b88888d1abb320e7d295c00a15bd74041ab35850fa768a8786d2e0cfff0948e adbbab8c600e751c331a054924b778213bef9b5a5e23f3d9ca8c9e3b877d8b30 -384000 def1f25883b2060a7b02f078b184a1fb50ebc9b9ee8190971a6315386382328a 31cf28e8a9ff6242a0e4c9b2ba30c018acdf9279b8326185516851a41a15535f -384500 a08467964a472ee61fb3ed6b622acbcec35b4903251cb99324f14f2b9bba7545 720e5881cab3613d6baeb94449d6695102a1e508f1b456ab03d2fdcc32486ebc -385000 d460b85b1ac270fad347a02c19917b9f38ce22c01d8b88e90d0baf63f011b117 b207a874a45789d7b09e0948eafcef8b76c9184aa370a508a4bafdf9d26ebe29 -385500 abe63c027a3d085071de60832600c63e46d78d244315facbee6f0f3fdbb02912 7d911e4630c29d4daf24ef749a17d8b7276c4c9c3f6194c6b0176b4b5f9271c9 -386000 656989d4c67537591081d194c31766bbd9fe449159aa2d3037afa3fab0f74a82 bb24425f9ada80398f6b1e4505b1f6eb372966389f0805b22f2e2d8607aaa38e -386500 2c055ea6793d46b622e43db2f1d25e05558f77edab26f4b1b200bd5aba514747 17499e0c656152df6a2d6096c5dbc50eadc4f19ed4919a04aa3a5c06668f3acf -387000 b25736d7898a4555b0e257ee1e4cc0a96c1275378dcdc0056234846010c29101 15a65bf7b60e7729a9c9a12883b882eeae58af6b07aa9e1e4b7eab5775de2154 -387500 623ea15901831a8ece8d44b5da072e281b237a693fc3524b523f658fc4ab621c adcaaf4a4184c1719060e828a12933ceaf54184d50afa75118d16df5a67aa578 -388000 91bbcc4c97dbbca8f88c68abad1a68e91c79f337a0bb7e14180bc2ce92eac137 21bc2be4b2c59b991ac29c2266fc1cafdfe59da48e957f3105f8d45fe2284c41 -388500 8b9552c05fef1a291df8a1b47d92229429ba2aa1c3453c274bdbf8d3c7c4fc92 f146203b047b7ecb750434bc317aaa95adc82c1fad15f35b22b879325ba38958 -389000 8e938a51863daea6ed977f9068092e5764c7dc9bb2491ac10291921725be7ef6 ccf2ce60dd83f9dfae647c30e824864a5c208ed5c8837420f30cbbc7caa3638d -389500 7505772f28c062e4751b5653080ccdf943181e5f0419069bc20ee6255c2cdd2d a4080018717b150e0384c0cae9a6500dac7779a57565cad365483cf79ea99a4a -390000 6f4b50c04bbd5aed6b57f287a0e6d90a11ea1571dd3635ca9b6ca6ef541cbdd8 b408a6d6415251b4b6ab6db5ae815ee07d0dfc8a8e9ac22c44470916d7d57ef9 -390500 b8caebe933d7dc40b9648b530bc042f1f93f4a1bf6e1530164682a1397dc1aef 192645f2fce9e3b4a7398c935db6ecbe5b79d25d8557fc5ee13d1a5c95fe790f -391000 0e6e6686e469e5fe43fe99fdfb377dc48f85d7892b9aa70e1ca46fcba1fbc940 face758288797482e69de640daa24de10d7a35e17e3b575fe147d73666fd0b75 -391500 fd1e752770b8e555108d7e32c8f6c7e1f9b8dfcb20502babe4cd541910a03b68 89601e3e196aa20964f326b166a74f7a601174815ac89bd1c385a464cee7a54d -392000 529453ab5db3938d1195a3ef84c286e8103c42b7b1b25362898674a66a48ed5e 892462e851252b9a2ee03c507d1acae80ea67d360514a4c5770d7ce0dd3e1f54 -392500 e3a3fd9781e171e256dbee0afe8373a2be01930182de5bcdf501db3a73a70952 945a626198abde6c92ee9304cec95937cb148057692f8a6c5080e0ae930be61d -393000 01db0c4add701bc81282082aacd1fa1ed032967c1ce44c88a46f22f09a00af6f 7b2b867b0ac1dc90aa91e0b88722f474b7d78a3322ba125ce36d0ac755b2c3f9 -393500 c045647644b0d7daac826a34e5f7cdb1f55a4cb4cb5500c16ba4791a8f46433b 8985e0f86f19a7a72fbe581cab68588d1882b9a4b1c236836aa1e559612692ca -394000 7336f022ef425203978336336066daf7f85850fd1ca5ce2be57119543211b7d6 6f1a7d270bd2cd756c02d24aed1e33fb78042efa052bc7e710cf37a60110bffb -394500 2791b8c33b59179365cb1f1e97a71a0ed8c4f9dcf98105ca35275dbfde1b8213 8b5c24c27b2fe79353caa4f2d7548591db269b31c1c53b5e7664a47ff1646a33 -395000 b68a97351f28549882241171a79cb58a1ae92d93a30e7524f3580dfa69bd70b1 a2d0161bea0620be17038a96a9c21a7c5ef08df89362f1e82ce8de29187735bd -395500 f674116f1af73caf4c6d464f99d55c1152f7529c15b0d28a12f35abc1553f91e 32fd584340a63818498504c5fabc21fdf3feb2a4529a6b5af5d9ad67f3679b20 -396000 ded515c3d960dfe073403b321aae9d66a1dbe4a9565caed08c9314e8f1b1d2df 134fcfe75781458a3899ad3330c143de491b74c09c98b8e95c16f79cac282828 -396500 b6745b3e2a46f458eca58083625f3eeab22ca3256087a45aa6457cdbe9999aa6 4124109f22fdfc42c1343feb20ed8a93ba55cd7f65ac34146c3f5caeee272d94 -397000 c79ef7c45f179c76254995bf3c810a62636c40d7283658c3d35f167f9b4289f7 a6fe1a5721abe2a12fce95bc5f5e12a4185596ce991d6af28ad2cb2972305637 -397500 d36dcc0090a5585951004c7f9dd645a5a2daff1d97b796f2dba60c78a89d5a14 a89cd3b2d93dcf17cdcb0f7badfe7af1077f916d6ad5329adfc38a6e1d25cb5c -398000 2b97743e109f78d910532ee0f342b1c491ae74badc58085ba2a7b9029f9fab5f 7ab0985407419f861b725834b5643d2666cbf5aaef6aa6eb94dc9e35c0f630cc -398500 4df2d83b00fd22751d5fc8b22743c9831701408cb9b788d86bf081c666e389fc 9c545b4c3cac0e1d1f9fecd92ba0f7c61ac3e8a28a8c973ff6026fdcd90c4a43 -399000 6a00c77818429d3ed4b9bd5211a3cca69cf68c9a99a89f9e1f9e5301c08afb03 44e27a5f4e4c32f6698257f5cd63ecf165cf4941a94f7473f3995b1a3a6bfd82 -399500 a6e49cf1def602b4915fbc2b208490f5a84c8a93366582f77ecf5575119e6cab 5100ff78853bcfc8606b12c5c335c772964323d7486d55af0fe315c05715875f -400000 641c6a53eaa3c9b94e924327e70830770397343d7927eb713609f14448ea6228 4252f178c0c42e28cce9ef5c0c40f08bc03e3b631a393de6eeff90e7b4d26d38 -400500 73e034517c9649420d36a641130bf16b8634fd3b2568e58198508e65def1fa37 a13f2b06f4b1b3daff6c10571f25318c3ec8e9f2d42c59f4f19369bcbff62da4 -401000 b249ae5082bc1eb852ce420a2361be80dd17228fd17c709761d0f52e81e8478f 679e41c907f1e82c438671466ce285437ba23fa2c845d8c07b43af0829692b69 -401500 ae40fda2bd776861208459ccc6f1d205b769de518dd00aec84f87811e006098c 2cb9da6c40cfc83129da322498da46fbb48f7509d66d7e5ad53b6ccf2723ab83 -402000 53a37e92887f0f1305b937538e060a4626675b361a28d8ac3cd88ce7c16adede d8bd6aadcc2b327c5d2ebe73f48ff2df81310be0b9c194cde8fa5aca004874d9 -402500 54008c3fb34d324191f2e8790f68e097dab91c9933bb83566e2039abd876818a cd1605e18479c4a48bc76ea463608f2c2475d5b3d603bf9ba7555194f6a77d73 -403000 7ccb2c59698108c6ada2be19fe72a1be124c9650abbad735cdcd1b07fb5888c8 208d179f6a09f352c3ce8c445468340beac166c28398132d642afa58cbb06fbd -403500 4307fac30841a99cdb606d9828cd6a920da0155afbea4e5ec770d2e82da4a850 b6304f7d096028bb882b39de8ab14f625d2ae63e4c597d34fddbaed7c2b9f526 -404000 b7845240f6d8ee0cc32e37d8682c587dbc52d07eef8c1b1fa38f73428b73afa4 326e6eaf313513e4a52cfbdbb0106538065a4ed8fdf3d0e7eb6e00ba46037af1 -404500 73ba4ce92e212342e14471f4d85581e85c402a55671db59282110671ede03341 b2af723149653ceffb01cae05de8860e28208128f215e3bd8bc65c7f2d03de41 -405000 3b3d4f18a6a63daf34505404d27dd936531654047b1dc9d1b1f864c33f7ed996 b6287250e883b8c416c65541fbd8cdb01e7d76f989f3fe3e2c31b762d9c3269a -405500 74fe48ee491e1f7e881a9a5918f1848dbd129b08720f0c9f2dac17dd413454f4 d57fd78c8080fb6739f260c4117e08c2214bd1afa6c4244bc16fdfd04804fa76 -406000 81c002e0fe1d6089bc83dc43cd9d616138fb16db20f8ff9dcb039a2bf54bdbd8 7e37f0088205c718348f6f13211a98b16ad8808ed51c824050c1c3793562197c -406500 20aa6245826270b507ea3aa44b5360d608e2d52b20109dc81a63181f9727dcfc 2d722a96f3605f68e844eaa0d3629408e9e20e8d5d095d33c435ea2427420a9a -407000 51c75ef8115644c138fc20ce9af7b771731a1efd11231c881096fdaf59591660 11b150fec2d433d57eee04489446c967a692ccdd64fb6c90f95b150f6d5ccaa9 -407500 6f24e1c00195775eda44acca48e654190b2a9cb22f2dfca41410ce90a067af16 8b49f54e99a2096f0ab8dcf8f22fe21db789b9bad29e43edd3566f5eb7045b5b -408000 ce3c90abbc8da7ea5c5df3c25ad6fd3a7fda496b1e0f696195bda3e6dbe7919f a5a21a4cbf89271969f43d9c808706c6cdb624daf4e5250d6690d40bfef2e78f -408500 ff9b888f601e151a141d92abe7007d40203e6cdbf107740c78a4c1c715608626 3a6e13fefffab34b8bc11418f83163112c871b7483b6cebaac9f9397b5894976 -409000 7f3914a988816ad71eeabeaa91e918ab92df56753de139ce9170256ea433c610 39c9ca62d51e871cec9c9724f12841ded9e81d1b684ba9bbbd118c4d79675e3d -409500 e3fa8435841942ec88357b1e3e0c33702412a83b07c68589319064dfdffaaf81 beda309cb0d0295f165e7ff4168eeb205c921f202c3c9524960152b7ddfa00d4 -410000 3ae6fd96e35b4a84bd063aaf72cb8ce5eda797e213dfa856008516a88039a94d 58e69a89912f506e6f4ed9e89229f9d81113cdaeb5bbd120ca273136117dc82c -410500 eb2bc9bd04d8c2c4ccfc4096116e390bd407e98f0d81b2a7a1f096ce0e86336b 3a87b4d2e3e1c6c5171edf685bfbd0694f293987197b33680dfd338e3ecb4b98 -411000 a57f32043fdbc1b8eabab9e66fdbb7f40066ea9e92d3b1055e7867faa4b73187 afaf24d67374beb37bf9b1c1f0e231ba901b91abae33f81367d55bdf78e1cf2f -411500 ea48060ae79a850a73fb9da920ff9d38245420ff20fd71ee09f5e1411c53f60d 248238d9ddd8abfa0b502311f3e2b21f3e5c5b75719915069a209beb7a1be710 -412000 aa2691852758d5a285217fe3a9bd1c2d29a6d337a0e350abd60809cecfe3207a 5a3ac34a9dfcdc2b17eb45244fccf0fb4e9a843dec6c6f76355c1a81b16f90f0 -412500 5a0807ca910611b9dc9992060c41491071f17f9b4f71b8934e8fba9cbdf95a69 a904ce16e3399f6e8eca3201ccc7fe5b15344c4bf306f1e63da4ab019e0d9582 -413000 6b93d17d702eef90b2795ba888ba49dd4d0d1545784e5d508bab8f3f3700be79 20028cf3dfdf9af6de78fd6ec4f174f46a617f2d3204ba22c3b487d3cc135be5 -413500 1bf2cd60f8c697785716c23db0c3588c42528d3acd6a8427311ad176e9bd3d71 b6e7e1e76a68c20f6909cdcab53f6e820bfbe896cf25a7e435a52ec6c2c3bb85 -414000 ca3778a71094657cab8c697bb6d36930a875d3c76fba72194abcd69fa5c17703 02c6d73c2091a860215de5aa0741c1396c9fb5334dad2786f1f483add87f1ce0 -414500 97f6a6e7e49a245ff3e2acf4c2882ec0173994a21c619f7a384adb93804bfea7 79845ca1a36820aada03e8c46de2dd19dacd64131d91ea5c102bb90df653cf6e -415000 e68357575afa23d47a2a7fd4077e14d22e51b786c8866042263c42ce2f6fdda4 4cf1d285f03ccf0ef31333c8b6ba0142b54791b826f29ed619266270c725b070 -415500 f975006a0b269a3c5e89fea165ec1821ab21dadd0e95d2f372428339a09b9476 a2e3b1b7b2cedaaf531168cf85aea230e8a27131f3643f15269cd8b7fb55387d -416000 27ac3cca7b525e4bced3bf89072f6df21ab97f85317dd242d9698a9f695b3d29 65b7175c50d753059f0955541a646bb523b47f1fa35f5d3d86ffec0077e5e6ec -416500 c3947b6b74b100c5bfd70c7cf1baf822871046f3ebddf211f20ac0ad00660851 ee1d3925d350a9da5ee86bd63c792406dc6a1c70fc0d286dda655687a0b83b57 -417000 cdd42386e134f3cbe56a5b6ff14b08dc50a1a02b70278f20a6982517868c7613 2f7eb3c08a36c3d1ffd90dafc4ce917e3b44fe62e8f545e581af01a2fec59891 -417500 758c5ed9fa53f6a940eb15078bfc3300f68a45174ad55b6d754de04344db5dc6 9d180ee51efbd082e027e34d85c9002b72233e99014924f3b56955f3dc2ba17e -418000 de38ce06e6f7c0509fb958124422fc1e0711c318d7fd1a0fbadae47352ec0eeb 128c492324c57e30449629f7a9d475ccff48d077ccb61dcc5b7f91d013d89337 -418500 52335906771b9b38787ad4381361b609d5eda9864ca2a7d2d22125faecbbf76e 192a8939e510e4b270a3cdcaf4d5ae7379dd0a20e4addae21c2115d0bcad0d18 -419000 d7718cb6a671d3e323e7f8c85b013f8f46dd89353a6f77672806cbddd9887379 ccdffea8a7310aadb5f103ae277ad075b9daa876c08f3bc4e13ca1fe85a400c2 -419500 311eb00a753d20b8c4c073eca48fbf44066e4c97dead7b0224ea65d24dae43e2 5d4d46ec84c96ba390f8d1ab5cd82fad5d412133341c4ec204f36a47462a1633 -420000 02abe9181281799d247884c1887745c6aa80f60a1ceb12693d328015d28b5a84 c5713fdc696198d00a681a1602a8703b724c13362bf059dee081747db8c31908 -420500 f24e5019cfcf1f0612785511437fb2eb94b0a44ae6207ff537b07113a6deaa5a 4c49208f8e5513b0dd1940c861175e2bf7bba04d6373e734cdac63237fc24f1a -421000 0ebae57f2319ea062c101095eb8c2cde71bb38b0df36fccd23fe6d5e40f968bc 7c50e4dcbe642218c07f3bc8df56974ea197f1107b9b523cc8d984f1903c944c -421500 3a65fa88661cc79145ba391c18d2eb928842a9ee2642c757b3731ef399323e13 2dee8bda6a09ea7ab0349f743da33dee3614c069af8977377a94bd87d072f131 -422000 030b699998f98d4b331ef746f96eda057e7a454f98765a0b695d16fd3e7aa44f 9b2c25f8a003bba7778aa66ea405ca0a7d1b4d1a44ab35c28124d0d147a731cd -422500 44dd126ceb8b88b2d3d942246ec2ff298ff07890fc75156510de8dfa22c121a6 fa987f8cf06191b45925bee07fa035ab558e651c1b94d1d518524db426449e5d -423000 93bc08b4a0ce5ef57f63ee483936125540dffca3d9d6aa1a24ca2f69df2e2100 a02f084ecd89f843bf976fcc5f5c3d7b9a5c2b5f549c12b896f4985f3fb18f82 -423500 4a09df19634b6b11e40263176de979e2aa0b3aca1a95825c3ad7eac2a84bad86 1a2acd078f11b82d5bfc43a088c8ad652ac993c2478fc2469859ee4885da2ef9 -424000 bad4fea158757021f14bfa735be04d0514bc3632f96600b1e4d632efc33c6238 ea4dcf8ad8122d652811cb25f7277c96380f8f3b1c839f63d8085d1aa69f5f89 -424500 bc5a6d616947f853ed4f4d9737fa063959d32b8acdd92b11e27dd47b435b38b7 80e414f560811279931e8906a37b79d64836df3f560e19ad9a9940a2e282ce47 -425000 5b30049913f1ad030235ecd4deb6fc86120b8206e5269d39e56e6c5f1bdef8e8 40b7b38eead88896d0993db8806af19167c6c2dcaf989e571a90cc689568e9a4 -425500 1c8c6b6e080abbbd1aae24639ad147ce9dcfb2836be1a4d5520ebfb3a9af61f1 c6e3bb5149886a4050a284990303b89355967d534894ec988b9b9be1f451edcb -426000 9a644de2cda849b362daeec3da5cc28e71652c6a2bbf37151d8ec938e728f2b3 a38d8a78768bea93a802d40ee5d92753afeae17ec5c625515512f4284d56eb1d -426500 4b3cba7009b8a7e4fca74996822c10f661db865afde3ccf0335607d549db29ea 91b61ada9596f861c6ae77dcb3f1da3ea0f39dd623b58910ffbacb800448a8ca -427000 6c5ce8cfc2031e16ddbc1da1b7854aa2b45d1e3a69f2fb73bb14d74a34c702ca ab6ed27075246d24cad1577e05b7c23f081c1be76318508cc5f08aa692ebad22 -427500 8156e4220e867b6f1f988b354b5a96ad98b7f7e83774dc658aef3cb7113d274b f8874e6dca4d1a2e74d442999c6f47bb74a49892a0d9a1894c81fb7d1c350f40 -428000 8dbc7ef6a382825ff9af8347d23569898d687ffd3743285297278cd90e3cdb13 21978c24fad677e5014f13ed54d547eb96722526cb52969673292324cb188b79 -428500 cd56d45be8fc1eef02a601ff132566ef3537c7a69f67f2d8ca6de2fbcff16bf7 f0b9826043f778014106dd4bc0e5429d0f217fce16e401a42ed252b1d2ea6551 -429000 4aec842c5e392ec18423fe3735e8f9c84203ef54f2b3dc837100e42fba29dd61 5e2a8cf8c42f6cbdcd136ecb5386e02eb993ab5314fd3410354159cb6497943c -429500 24d33bfe6e7a8694630a848958175d99c8c5a5fc092437ca95edb5e8f1aaee5c dc92e71cbf3286ffc80dd237cc7cf5ed769de81324291bb80548a79b6a12e354 -430000 64e5cb5e05477470b8068e35326c7e6779e4cbb740cdab675f60a3048e15fc25 c622476e2285d634a82c4720d0a864b11332b9e00c3379f7001f28608c1c4817 -430500 c7938907c4845919f2ec22dd7ff432e7e3e2429e65118a11ae5f2fdc1f5d9ba4 5b34e827fefc85f603439e3367c5bcbb63d94aef7f5389c54e10bf41c1149d09 -431000 a1f4642fec301e246762ea675616ba729278569d221b83e0fee38459ebb157a0 449b183170ba71bd90a2cf58cf0fa0a61ae8d86fe32075dd4b9e80c0a3d8f365 -431500 012e1de4c57ac640cce243e1577db4193427c285579d43614463815932e6f227 c5e13378fdc635b4f2d4dc61ee5d1c0ed7f60850a9de87de8307c9e7e494cbdf -432000 e530822bbe70b043e108e5101b6a684e9b1d5c47a8d0b2e5ace12e44810097f4 211321ba33cbfd213efb8e3df7e7ea774ea25fb24c82cb757e568b756472ee12 -432500 c40c2a8915c595ad827fc5097518aaeedb71832cfdc7f3336789fd6ec0fe4231 37b6a9e80f2b789d61060f97f6f7b8ce019ff788339de54fccb2101c184b810c -433000 c471b86324fb2df461084f3b3f91364c8e4e54b9c592457044805c9c0b1b1ff0 c3cac09940b2a846d2798df91b2e697dff55fcac233473d159da02f5d2a8865d -433500 7c83482c8fd9e4c57aa0dd75563c991933b314f3f18c7cc821204bc41d4c76d3 4d6ebbf09ef39066a45d9157273466fc6e1b08f246396ad00ca6a533a4d08da5 -434000 7d3607cb242e5daa146bb817da979a8874bbbb9abdffa2cfecc546bef9a2cd26 7bbd1335b9852ee4cb13b1d7285dc11f9c2867fbe267cc4b6c1b1a3dd6a15803 -434500 0534c7881cc8c3745dcac6942291cfab024520de1159d3cd1cd6fd853a52e1c2 b08a60d232a23a137cb4808f3636128335ccd3dd10fdcf766ae5c20b64d8a926 -435000 264a1cbeeed20cb538b71b99c8da4874af707bdf7591cc37e8f2780ed8fda372 f226d8a6d56c761d1f9ebb8f5b06414d1339c17889767ce48317564edbfb337b -435500 410932e8557a564a226ac672c5578f75653ed84c4669f64b6bc29fabcdd90586 a5c68267fd466a48ec4473ff1c904efa8eeed2124b7e4bab8bbf83ee876dc375 -436000 c153195fdfcf3938a5dd5ebb0d5dd0ec59692a8decf1184083679c46569b537a 5d8daaa7bff2de12b5d9b428e84e5ba25ef9001e45ab728ec74d6a22c61b269b -436500 5e3b108e26916d2507a40bc30211948a0bcff8ce4b40117ade096cb5f94d22c4 16754de8c6290ed9a3e8769b8a03375448921fdf847c7f1ed6d627e614b8f6ea -437000 06ad60451a13eb38ac6f9abd2375d50afa00d4d8c5dc1c2806bb5a05727ba523 4960cb8d1571d7c0aaf33b659c0721fb84bdda17daad04f0cc169dfe1a22ee28 -437500 2f14aaa3e58a32d5a3f17562b3ccbf8edc8bd17193a9a09af65052be99225a2b 8709492c2ef726d995e4a2092a2d062a849450a00582ccf51fd7ce3905ffd2c6 -438000 87d16a339b0ffda31c75b16f3fc8f7c45d0c67ed9de0bb27027524661b1f91a7 c21254cce7d2b9df55ce98218ab9d20d9d2afc3a450ad1f3931e9c7802de8f35 -438500 b84fb753cd672d1622e7384382069066410f1c27763902b5ee2c919ba3f20bce 075834fbe8e33fb3add9426e52ca900f7db370b85651ae10ac5079aae540153a -439000 cebe0aac7f629f59ee1b2928d8ce4340b247c0c619e3ff53b369375bfa71abaa 7e5fe6db2171c4040cf71a4bbc598983a4892689b7b8da5e3cd161ed7696a410 -439500 7a70cbc08418eb8b711aa13b0a49ca6cdf063a443a0aace6b8f78aa0c9bdc3d5 c7107988cc60c6c66c2c9fce42c97303bfbe3d3db9ebb17da8416d0b1a918e44 -440000 7649654fe753d823dc09f3ccd2157d9e9849e534962d5ec32f5a71775ba31fff 3670ea77b7e5a8750d63d8d846cc2e676e69539125ca1a3f66c1d1573e47ede3 -440500 9ad49b33c96384a916c19e0b7fceecc324d33aaa8fc45b5e48c661aec09c880e e594489948d159bafb11b9a4151a89280c37b8f5665d6d209766ccda296346a1 -441000 2a3a6ecf5d7defaaee82b14d7073402109769a5a8c940d6ee1fd35f23303bf95 e8520de1202a192e8f8bc825b528d2fd8805efb774b18c4ab2f3dd153063a0dc -441500 72fbb24c48304e9daaec1801004fcd4bb4b6c0c511932821a6d875bf4c9e6bc9 13850c1041b5b257adf6f51551051abcdcf13bf6d674e075c0ea32028011acc5 -442000 d8d9a1091bf2e48609bde3ea3140ec19cfb7a2a14735474c6f9ef6105c46c8f6 8879f9476a6a342e58cb8ba5e4e40a9ff6ed0b605f3cd9b4bd9e6cf5dd2dfff1 -442500 78782ee99be29090c13682ee644a47f85f410c5a24c1976dc047f3249dc1e0e4 b4fd6ca7a0b0a77143c457285ecc982da5b9639a5659c03ba88315432e4881dc -443000 a5d7115bce13dbdf436226400b23c30de09f68f6a5137cba50de278effa35891 cfcc7a433eb789185f88cd600fb249d26b8c945d5e5a5d7e978ae3c1c1118a10 -443500 f73cd58af88e5cc893f5a5981888e792f6a15cc06093c14e0ed91110778f0312 22b5b27df320f33c1856dd087c8537e5837c0686ccb436961189989d593b318b -444000 7c497c96ad4740eb68993e26ae3127c6c9e10b8625f9e759131574b87cd722a3 e5405706b778afbf261e0b4ec0a7fdca861baa26ec3a65f5e970769a8497ac1d -444500 cd52d7101a166f4dea73875c0fa5c494db3419bc3f63d539e57c8e853e96cc6f c874b6d14b66ae740907a7ef12eb55dc0983a4a9ad00b27885902a11c72d8009 -445000 30283438585b2c4d3409d61110cc5d400b0abc0cb8e8b65b9fd8619e54dc387a 3664d9de72ce8aebeaf5f1e844e44f5b3362d0faa80415de24c2cf5fdce153a0 -445500 a4496d3bd4aea3dbe7cf7d2d5a3f0850f5c01b04662dfd38d3dbe6736251e91f 8cfad175dbdfb208dc40cdc2f03d0ebcbd9f3b12847f6d069fac33a5c1ba5173 -446000 7cff0564cc670e8a69315b18b0ee229269682bb0286b5e4b3db25f02ce0c4d2c b5c22f647055dc1204b243da18d999adebc56060e52f1f0c4d35450a9e941c68 -446500 201cc692970eec864c92e5e7af036192a9562a62d2723204366bdbfdb0741fa4 f3abf2331a35c83fb86e4484026fbc40266f5551bc90551b90be2d26b3771e3d -447000 c06f8dfebb81f0cb3f19109f662a7dcaa4a023f1fbf735ed81fdd6bf9fa95023 0799398c8a29c71de6027c446de153b17b1bb364570328bf5aea872fa246ca98 -447500 05185f624dab270906ae111fb2c43e838b70a78e0420e84fcc94bfe4fc911dbe f73e1007bb6e28fa8a5add7dc21539c7545ca68c600ebc62b10ae00382c9a538 -448000 4fc96bd14509bf55922cb5d8ed4cbf372f7ce991646e5be3a086204fea0c368d 0fff78f76cbc925b62ffe927d50cbc02dc83fd9e5405a3a77e232b55a494812d -448500 742e9431b2ac6f0ac24e58cb8e6088ac1de875cda8f16739a78e0f1f7c05ce33 d892c34609acf3eeaeb32a384985fd2da70c4f53f59f8c459eaa5e74b3d61c40 -449000 335341c810fdea9e158ba78a542922754fac2e0fece92c27559d14c5c3ca0267 8d6340cdabfbfcddacf2991913176b17513be28b9472b744e7a64b2f2ca13896 -449500 2b97e9d073d0b8922e73a1b1d6fcb7f8dbcb0e22fea6a707d9faa2afa1cddf8f 52066346f6120422b739d9d1cfd8452a00c55505e0b2b9805351f7721cf253db -450000 a6448ff3de412e8784a4d0590120e0727c3ef1c6e98af7adec4b687e10c22b40 b12232c014cf52f4f8d0fdb4037642bc1ce2a4d709ae37b91d908c9d36830fd2 -450500 32343305ccca111d5b0396816091f1f169314acfb4974629e7beb8680523cd47 36cc9b37d7962e434782de92543635fb826a4d84fb5260ca0161680523f54272 -451000 adcb05f8f053823db604b6278de320da2097890b386fe67c0104721e6cd76954 c63c045a3117df4fef3287be2f66c5691b700b18b42d3ba60509faf162dc9720 -451500 c3f6f574abc62ac6ee2b65eee953b3386808361f721ec77e4df9bad7811b0c13 8ed2df18709fd8580694387f903d9c31fa4a7c5e3bf3845b4fa4e9a701441112 -452000 b47901f63e411758d074dd4181d87fe30acb1b1623d0e69701093d93bc505b4b 227dde0bdd2ce1659265ced176e8c5514aa1d7c9c58c5f92d18534141e157539 -452500 723793ff45924363551d433d63f58d9951d58791f6954a6aa906d8c61f80d535 1a931421c2325c0c2cdea860d128402f6ba18decc20e05279f62f0d0f5940f58 -453000 14a86fdf9716b2225cf80394126c1bcebeba3be4a4f103a3497c8eb079ab11bf c0261d2846f68bee936c5ebfb638d9d4e6bffc53519b76ce72dcefa8f66e948b -453500 4204f92e27edb642343263ee5c8265639a4e4bcfe6743c323e5915af2db0f68f 681663c10b07fae27a187f5512c63f266d4460abd46ec1f464e8744b5ddaef67 -454000 d7173ff752ac555014e60e3928c1a8ba368d9ecfacec9b302cda79a6c6162eb4 c34bd72a990e253a26ffe68a91553b0b771083a569e512c6a46a52e5c7b6a724 -454500 df134eb761013d3ba1bd9ccb38d735427a299f2e275a3a1764ae436ba07f09c2 4d9b5dfb6baf847acb9499ef9cedfabe98dd58150569156e5bd692d1f7434f3f -455000 edf2fdc49b76a90ecdfcf0e238e66d574794b7ebab6a4e7d212e1884a21588d0 c40b528799070a1964e73025da6badbda9f994fe3d83cb4ac5fae95aa2e42963 -455500 0728ecc53f1b1b7be2478f687881eff7e6ba31e9d565619ed628ea9263b67a97 700384e16447d9873213d70063f468f9e4e9b1f780104d9a118d86b09aab9594 -456000 fee4d1a2fb2a99260e941a74ab4dc87e0520c28a115ba86c6382791b2f06f1f6 e0487333ab303a6d155cbc61b33eb1b23a3a9bfc3d466c32d8e6793328b3bd8d -456500 b5f05116bdbe8b51f4c1ffaff1a0e0a445e3a0f0c6c718a72d346162820509bc c7a2de5b71c4c7b338b04adfa8fe16857ba3c926fffbfc97dac86b0b75033978 -457000 b414f29bc13f7cac4f028641c788a54786bc9412ed582f4aedd5df86039a8e00 ce69e9060126b330e010d201b073dfc0e16924a8c11acdaa61c7776f0f2d8021 -457500 c2f18fb64768083a462a48b87b993870ab96a70e325cc1b7ce676a504dbbf4a2 bcf97c78db8bc3b69a377a185a429277aa530aa853c7ea12c2ab06566e837c9d -458000 379e0643c8dab2bdefcc1cedf8118337bc0133f0c938a1553088230052f5cfcb 22e7617308101b51b4ddaebed23dc67e0d1e0b3f84c5074039ed77c466cc83a5 -458500 5b8d6a2de4952aa7aa38b9a1d403fd80e65f6cefb5e824c062d060894d490946 56ff3b66fcc71ae8550fd0630fc358edf11f7afdd551d69a2ec9d4b9fe154bae -459000 426443a695e4615554b95c1070f14391c199178d8be6860807b69cf2d686501f 40015ea68bd905903100db2ed67d0a0e25510796dbcd1bfaa0b8dffec058ec4c -459500 561074bb87ee4d3132bd22b91af78df7d2cdec1c6914b43b12a4004204094a4c 86a908568cbb19be09a1c70b4a92a0b3022e5d0008ad78d6ed536a9bdb08deec -460000 7adb9b6d14e8124ab25bb4696bc8afe6a96cdae5396ac2a5d6d859c47236990b 6ea2894408475e17a8c4476b5084cd76742a3cdb97292eba2e2ba0ad4bb17d87 -460500 5cc330e1e985af39a1a24602603f26535df43ea7e5e164c6b654f292bb359633 69c11c20de0f89ada1a65781a2b7e7a1e235f964341eb70434135888794032c8 -461000 c1c45b5a71cf6ed3c5d9a739c227b68fdd3cb41e8102b7e99c28084776c3d8c9 122728c928e7025fba2e58a3b70cf5dbf448e26389be3606b43f3b014d5f2001 -461500 096479184f5b32532940e42b35c51e50008b8224b2c6d6317dc69478d3d316ac aa693ef567b3b7c4a7091b5bb3d34161b4235e7bb3b573a22e66bab0e622f16e -462000 c78d5a646f9130aacd23a52cc3dfc5a084add7fde9dddbefdd13d5c438e024a2 3242055c63d5e14c1efdba0effc3580106e14c443a3c39c699931a6c4a36c94b -462500 b464f9105311560ac63c29a94f8a0a5f378bcf5c22cbd23d5818ebe2e62550d3 4b91a857ed6803609c0f1d514e5793f3f63ea3dd37f84b345c3c64c7248f8358 -463000 ad7d579916aabacd745a9d48122a64e420ba111b8633119f6110a93125eb6072 ab7a1e347245f8d9ca551cc5e89247e18d130aa0180d375673de0578dffdec36 -463500 9f647ead66c59424ffdba0067d38a93c33cbc5cce95c1fb19483d3138d9a2924 f9be09f0a7ec9832b7d2e238f0f3841a10e99967b378bb93e1e8ed95025791e4 -464000 8239a8c5704697db70720d8227fef8093751df0e79bc792a4583106c5229d97c 56a2bdda4613688231ea85b9d659f05000786ebd53300466da5dcc474f8386f1 -464500 b8500802e87f0a3d08b275296b32aa66211d93ba13dffce95a77f4d2ab6ff8a1 87c4e1ae3a488895890a0dda084969a43703e9abb82fa8a6b0fffda090b1fcb0 -465000 9c5f241c6d7947c078423264cd080eebeb852aca6898b71dec1f2fe0f97f40a4 eef3196b8ab3c6d1e3df1eeed6f857644e50f6a751843e308a86d72e945cc6b6 -465500 714cef624738d796efc3fb3fdae8f42478924d28a0644c225374b1e5f8707262 8d68d66be9f3952f46bcbe5df4829d93eff2f4501bf422582e8594bf3f03730e -466000 760869daabeae89da11828967600ecfc92ff38d5eb79326da9fc526ff88e3dc5 ff631213c2cd21307d635337ecefd200cc2b7767c171ba5913ecb785d6876aca -466500 9699ebe38cd6fed8bad4e96c18eeb8bbfce93fa6be86c0c364ac187c246d47e9 f18cb4eae80510bbccc360228942bbde0144f6c66f378e0b4bd0005ce35debe9 -467000 6de68cf541236c2b20da6bb789be6df085207919a94074f31975a54250c4d918 0c998a0b617d6dbe4454ad981478bc5903ace25595e5f868c6bbab61f80cab09 -467500 34aae978a356d729783acb130e2238fefadba1789ddf82d73b87c79d862d297f a90873e05bcc6a81932e4562242f7ca201a07707b505f5dddb46418cfc26c5dd -468000 96a959479e0159621c8660165d2053878cad8adccc1ea5a4020c4a1f63941b09 ad947d10fe2c2fb1f61572586b941c872bd958499342e2e44b545d4c0faaafc3 -468500 ef36c23495b3e062fd2a92e24164f80a01d74452d2d439a23a38e403e531ffb4 5790fe543b78423f088a1d53daf1692a7051169bbf1e469caaa7d3862d709b2d -469000 e32fb17dab672f159e97ac45ddb12dfe0dc0bf2a2abdc455beccdfaca5e2c69b 56f4d6e427a46b3467c26174b6a4b66e30f5d962450273ebaa598c06aa31975b -469500 3870050849e79e3243d3460ea594ef741a1d6327f5d336f8036fa5e97e0cfbb2 2e0823dd7f7a137a063f473cb6991510a112460ecacfe18aba39094d410c8930 -470000 2aeac4abdc914d4ac3fde31a5882b242aa26f1049c86f703fa5da279edad5a7f db8d47e66737aa4776e8cb857386d346d356ba91d0f6212d8aac34c9ac2e5906 -470500 fdab2f454e5102f44be86a36b7c2a54aea2f5681bcbe811942451827e8106734 cb60e3d4e6620535cbf57bf0f94c5055eabf0ca48052e9728fb28f5ec913e5c9 -471000 afd4b785fe4656f48ec1120a14136d133df7059eedf76f407dc2bddb91ab0ce4 0eca3c26dcc9bd50d78a8322c07b18d59c7609bc6ac97258b56b20ac73187f06 -471500 e633efdf19faa95b16be4cb94f7072dc1238342d624bb4d69609555a927f2522 570bc44f8e51f6dceddce363db3b87fc17d9c8ae51ab9266a3d9248b546df4cc -472000 d4aeba089eca88aca7c2b7cc89e10146158dac72fd7643e4c7dada43c8645757 e49b1d22916fa97893a9f31f31bce50f96d49f6a388ee1c8ec2216aa619d9101 -472500 a1c6bef24a340e81f3212db55e9db0bbe8135334e14f66839123c21fa393ea57 1b5318294e73812e157fd78c84b79a31d076bafd91aeda00fa49055003be7e91 -473000 c2f76403fbff7b3601c0b2bc71cc00963cf0b012e09d6be5d8fcc12a8f78c8e6 be2ae59d51ecc553798bcd9c82f4e747dfd1782ad18021dadc24e4838c2b0666 -473500 5f6ff7d98fff43942ec210bff0555d74768aff3e5fd5ab6e0b546d0bfea79921 b828dfae2a89c1199e2cad79165f815f8d858620d87aefe17630048ec05f0bbe -474000 2c191256f2a1ea617517c81c3133a47d2fa264586885b2ca6a7b782f9c78a8bf 7d0b4169707e36667345fa68284bb9eb0dbbb726b9391ec0b3018c71a343ce0b -474500 50b6c4f4c1da30ee2043c4a18b0dfa1da9aa33000be4525bb07b2462d8cabd2f 097a81a5771e9db71271cc6c0ce12a4053e89f2975e8523b6dde6556c170e5e8 -475000 2c38054fd7a02ffcac28fb8c53ad84b68d50ef30af030e597414e15b59bef269 6faee9c17b651d220534dc8c66c0345d162426661af23bd6be235d1c0eef73ab -475500 8d981411752ee6b44f12860a9975ef23df0c7dcb5b5c621368be19033de81de2 23fd87f81163c7f0580a7eaf5f74b7501a868508ba60f47836488f5b72716608 -476000 27aaae6fc04f000f25a467ff5c2fcf62a6872b3ea96a3ca445e0947bc912d050 061c4b35170cf452518590f1e96624dbc031e5eec8b9de1acc81a477bbaa18a0 -476500 84e8616d4259371a11abc9625c4f7d55ccaf949881e017b663f249d29aaabf70 6e6418118d4d34c06bf73284c95f2e3622c87c42ebd4a8e1380939e6abeca428 -477000 d459f75729583c8259ea66e8dcc7b8e1486b0a30e14864332dd014757bac1f5f 9316f02e5bffa72a4ea6c7809be57001db28415e75048320d33dbf23c3a39e86 -477500 329e7c98cde787901a05bbae8aea2a10fa244630640182eb9fcb80e83ff47cc8 04fabe2b506d1c811471d88cb7986d2a67a988e0e094936d398af0b20dafed91 -478000 8515a758d83284a93a354e91ca1389d0dae0914aabde4c7069180dac0f88ece2 0f9d14354952b22318f9909502aaf188e43c511ea6c627724bcb7f0d14550233 -478500 e0b6428a55906d115c2365630e7a748422b1309a75df0712730a018e138f8ae7 75327db1cbc6d65c203eea4cf697e0e8674ff0cf180ad7730c0f42fac2cb2259 -479000 acdd6bdcb3e05e00631aeac70db0beacb5ff7339f9efffe5d125a748e050cf0a 2f4a8780e4913da0886b73e399430b0a65b84e906eb7b47bb14ef6139699e222 -479500 173ac0f8bef2de4b544b42c3506aa887ddb348e6f719f2b4fe16beb569b6b9a9 550714098a237e5f2a2313711787f7037937081893315ca43450ca64c071c798 -480000 39a37003b75d37e0588e177d5d5566dbd2cf4f1ade343067de439e4e60d401e7 e90cf6f99b06ab2f396192723accafe62f0a7705a8795b39371238dc660881ff -480500 675b1ab9b45350f0db5814692844dedce30a416b0c5a6b04e3ec778de1c54476 0cb43e9d578692ced5b3c43a067a09dc8e582a12e46208e1a26841645ebbccf4 -481000 c49b18c02ab6cdbcbd1380535c394567b0fef261db605ae42584fcfc5657292a e45920a96e78f6ef20be3f24d9a8b1accb6ed9b0a9ace38694eba826aafe2bd5 -481500 e70588e89d0a3a15d7de9bc26e47768a94964a14edaa0355853f5629a500dffa f623feb088592f1cc01e94f8984e5bd7f5469ce71ff7645ed81648dcb25ecebe -482000 bdfa119169d8507d41720ba8fa40f5ecb75267570ad0ba58e342f4351fb74575 f28b44f2e70183e19deb6562a107d204531edc8b46d4f5aac76884d7d3a9e750 -482500 14e2be2612c4290229084f2c1edfefd0e432a91254abb83ef8ddbe8d7bf2e661 aa012dfb4ea0b0d0a565fd8f2f55692135969aeb6a9d3f34cb17b31e32ab22c6 -483000 8cc62d490274477579f93e8af507c07b3816d393200aafdbb6b68755b763c2f8 3bce0766356c52720491791bd9cc5a6584c48a39d620bb185f368eb7dd7db697 -483500 72c78ca3f93bde96a8afdc199714ae18e9c15b92526ff48845c050047343f548 f4c218fc750e8b31e2b4f56ea5bdd7f027227b58920c7d08946d193bd090a366 -484000 ad5719becb74523e16221adb2353a4786de357612d9e2ae86753be7035d1074c f040df388303fff9b7c97bfd38d55a94c1701b82ff4f2d594b1f4637fd8ba964 -484500 a143595d89e542b00901e959c20b1bee243c6b7f2a8bd930401a0a922586308e 1c50e70afe27a5026a6ae968118f5141448e69955b431f74c2b94af7bee31ffe -485000 ca0faa2c4b601116d3e03c898bb6fd6de955e9e083910fcbe93303702522fecb 98250685f5d2fc349e6088d617a7986ea28204843abf4e887ee121b3f89a2b36 -485500 1d2f98bacec2bc91b7ffcd9e760c49bc18183ddf1bfb4aac8145abcfe2f91adf c03ae99bd105f3c8154bed1630bbfc10d56a2aa4e36a85d4a9fb2e629920e285 -486000 3f9896825fb06766d9216cf1004aa6d2541642253b2980c59775fa720e1af9d4 e8ff26003f9db4ca25d4a5e8f22c615b6b376f2aba0b6e3d3ec1fc54bfd3e8c9 -486500 8387046d6d520535e933c40c8e7a9b253dea20d1d4fea49c53cca41d13f87b5e 29e01fc49acda9fd49203e03a86fd7fafff8dba947e907ca41db1b6e2802081c -487000 3ee4cfc2068bfe1472bb2345900fda4ce7d99aef724ce5c35e8dafc97472a163 84ee857e054c6f118f897926d53b546c4fbaa38576d66eee4560d88f90f2ac91 -487500 7802c03efcb4298fbff0c05c7c2a2670e2b5c5c0a912260fca95f5ee401f9fac 9c507f7adb01fdb9fe8edd09d969ea7b12474cd9f317e6e0c8d1047f720cfa01 -488000 6c0026aa2c04a1ab5ab59df72d9ac017f559889453749c95937e01230628ff22 89cd039f94be43a6d229425daa26daef3bee7688fd591dc954ee503ebe2f3573 -488500 ad7a33c68b62d181fe269bb58ad9f00b48b4b19f77cae3c68407ba81af9e29f5 e26367c609049d5cd867041787aac089a459ae2a39e420b791b778f49c4222e6 -489000 dce5e567c4502e3b3344804468bd48900df890568521360b198e5b7e48c4a7cf 497cd478db672eb3f6e975b722a162b26d5f0fffdfeabba6dc28664d4dc76bb2 -489500 326013c6ec37ad623eb9c5a35a51c154447c8e180d4efc381f02a791c8dff517 81c2d130a11e3caf98c5d4af0ae7c05bd5d79099d5c959efabe7766a211c87f6 -490000 b0ddbded4a9bad235b75d2dad597b8fd87b80cb721d2c322bde82e9bb3763d72 5abf2e1aa1273cc9de5eab070f0dcd5b082cf7459de699a96e7b12dae3311265 -490500 40f093e9a8e074fded5c67276c85a0261d15f3e418e492ab1452e340da3c0469 0d79b5359c16640713fd6b885d6327bf67971e99395eb633ec71edf9f67a0649 -491000 42ff56a78710f1d58f555a7f55001a1760c7090441dd2657f959a67b2d8a8289 7a167a1f0656c972aaaf079ba002f35ecb7d47aed4c72a7da645276ee21f9ae5 -491500 38a42670dbea9a526f90e8a824bb52398335afd259b0d89f287687810cb3a268 c4f01d0a2b59e7cedc7957ca4dd510eb692cb5ef4c257a76fce04c3e51487e20 -492000 1aedf52ef4f42d0e049cd6f2b564a1416ff737cf792eef860c4678cf4b1929f6 a6c9e1dee9d08b510553bee2acf0d1b8b2f0bcd202ae4d28110fff8dcedd85c8 -492500 d7c8c52fb1f9138293bdf0c28ac68aa8447efcb1246b8896a1777e5b20800ee5 0d6687cf95402d4df5a9115b6786b1fdd27493c88b0e1fba921bb7b722084a88 -493000 e4265d17c243d4e4dcbe12d216d7dfe7e4e3b7da161226203881b0c007f2936e a6f9daa6f9635dcf4a2cc894a4b459a8aa5dc2ed487d95d733bbfe827aebb0f2 -493500 9c3b415ad45f42001d88e2dd38748048ef9f40223e5c1c62caf5eb7912d78b42 e68eb0e1b1b95dea2fff359dc5444930588ef743a58da356b8d33d8e6a0ee1b7 -494000 e78ce6a76a928e878b6cb5a0ca25c6b9a8cd69d4e2db9a066e702635c11ebe17 ea5640b26510140f3abd04e611f124851c15338caa163bea3a5032fd0d16b160 -494500 cb62ce4407ef63b81d3afec33e7b57b31a6e7c8b3e0888b8db96f17e4d39756a 6600b14d7f4f7bbc0f680587684f9fa7d5a7acd26cf9d103ac31bbedf9d6afed -495000 0e8a7e8cc89426af75740fb8469fc9616a8e75401fc785a8e686d5ec0f4e5732 0a1ce34d16dece7d7bda04e5b9bcce126b08d7e514e0fb37c5c1b0871cff4cda -495500 ba423afca93230eb911c2f4dfbba40b893b938a7365cfc2068e1ecd3bc770b5f 5720feefb7971397896c9a270a6318f2adc667cb20f2cd218b2791778cd50680 -496000 352a1fd91dc52fe0cd78e2de4240e75a785420049e7b95e01adfa3d1ac4ad512 781da1ffa0ccbadf08f451c290221fbef9b440c52b5f7ef5bfa3dfe51562de47 -496500 d0743556e112656c069f2749baef59ef56225b6bbee44b2336ff106773fbe965 ebc3df7a34a4a4e9d8a60151f4a5bdce4f40cc8864851520f5161abf9b9e6d51 -497000 1887117917c8adb81cfbf85bd4950684145a964a12c81ca89a44fa107247c275 e48c07018555f1a8be3ad71f6ec7c31932eab7aedfb414c99bb793715ec36e4a -497500 2ffe736439e02d764f544aa4f86a125b1567ab7d24a9d944313877d2d7c39d14 a2b4732449a3ad1488478233895bd8ba26b72f14bf839a33d5fc0f2934bcdf2a -498000 0bc8b494b42efd68080fb3d3d83cc8156b56439c10fa789814d751d5c4f7d9dc ea1ad23e7f85ec30d138ecdf527a5ec5ac6d925eb888ab061b9ae24e48e60b2b -498500 5440fcfb2e8888508c4fd6920d0e6c7c1f3f1095813d45b691edc3a2a475722a 4c2c9c60a2a43f9786004a9b43275656b60a70c9643d6c676ede104b9f0cec12 -499000 d84c475656720900a0b3765c4ed57ae1f0ba17238d34ac17b1635c6c95064750 236f102f6f2350128916d138401344233a7483a0dcb1eb39730c6a5fa22fed3a -499500 8b9aabf8cb60c29c4b60a942812968ab80ec48cad4053de2624d42372a547756 4fdf0de2a22bbd66bcebdd844beeaa7d5caa353352275953936b6f7839497577 -500000 bb94f21cd879e992217888fa56f0cb57bf585f8a41f845fbb46872fd7ddd4a40 541ce9a7c0f8771a84281db66fba7cc2dc43fa636a39a840fee5bdf987a3348f -500500 d74c1f7510c4307c942906d4c66ce5fc542f2a1944659c1ad37a0eb82be11751 976e8ed703619833f8d78889bb8a3a71a06392e257b093a01f7a1b7036d22fb0 -501000 3383f0c0456774cc529b5b0633a947e0708156bc873180f56fe3c32008c8bdac 69c86425b5c47c2bc3a9fe3669b0a80aeeb72bad8179676a55dae6445b7bdd36 -501500 d076738e554cadcd99a14287f0d0af18fca6f893e6ab519fff1a9c987e3aa7c9 9ceace4059979133e529e2e33930ee2ceeb2058633e06c31efecc7d2112a2437 -502000 03b70f8f87fc995b1f25c5979cab284b112e66ebeec690dd93e6c1f238ab616a 5c4442bcce1ace2848f3bbff98abe5776b58af7da464ea4d8ce5c681ecb99261 -502500 99130d7f62752e1e0a7318ae3a933b638ae37528134af7b76590d477bee107b5 206bd50bea02399a5ad897c4e1190e96ba7c092f83cbad5e0bd65955cc253219 -503000 3eeca5fb5aa1f44a7a86e9c2756add708089ba817e4ebe983da92bd815fd51da fc3643c494c343939f26a8237b3df02c2b96235e034e92e199980834ed4a59b1 -503500 8034c879f7596a3d9846ce1ae028fa596b84c62313f9b43564ada16c3e2f547a fd766d22b34e5e391c7a3e8c1318ae469a763ba6c49b75d55b0f928c83e5f992 -504000 bbc5fdb678ff466da54e09ab29562e16a798ae2a05eaf776d97edfa35c839a85 b6dce69571860fa8d6db1cae19087b3232b06b8282f5b905a6ff462528a1fcc7 -504500 956aea829d066998cf96a8b8edb9a0323dfd018642692dd7daf59d0be1b31ef5 f90a6f0b96ed84327fe33e6edf930a439d1843046154fe1fdcd65c011aafde2b -505000 0a3445456f4807eb2f234e51acf42870aa7b6a2eb96749ac3cf764979d3aeb14 f6977bf4113ff5e28895c0f148fa0ae812a4dfed4ac0483419d08e3493c90e4d -505500 fdf15fb92600803d9d99b54b13c028ebe2a39d0681e7cb751496a155b11a9656 6fdd6b0729448d9a5dbd5b5ec1198c5f89d0a437c9019c94e0cc4b0cff9344f5 -506000 94533d7531d5ab46aa3ad4c03ad71b8a6f78574805a683be4021d3648a56b0b0 7c1f8200acab1aa87ce1ce548b727d3c47239045d9dcb6d80ba58d908af43c99 -506500 0f86a6ffdc4880c047c73dc16aa8d0bf27d1dde7700c2fd77e4cdd7e7d926cd8 e9c9a93746ec3a17feb362c2dce6e9a9c51a0d9f0d9700d21bd8aba906602e95 -507000 431e08381fac05624f905ca38d18e788204823803e0607106e147bbbe8bf688a 4ac228d8c9c41f4e3d3a3c4e320ed04c13be367680f9fdbe8f6e5a7ab2a23f36 -507500 a227a08c0b6d0818ac30280e4cc9f422bbb17cde711c371acb7fc19c8a642276 6dd10139c09a88ed1692aa137b788336a80ccd60753eb237e90687a15ec987cb -508000 ac9eed373dc35d2906cefc9e3ad2c8044253e75789f4d028b84a5acab33f8187 d4fcd4e62b88c4ef4e9609e8e5c85ba44b15b999dafa68a7cd45eea0b9fee193 -508500 82837e772818deb177c58056f9b8eb8c42b42c75053c206ce64d4cb0caa569a0 088031bb4d6c8d50690782746dae3a2894e04749cb8073703758bf84403f65e9 -509000 46d4c946d3305147e565ccd6bcf5049931048ab9fa78fe64a45fcd29df7edeee 0d2fb9af0d18a37f8bd0d90677391033552038c5d24a58db89420c355342bc33 -509500 dd8574ebf8743606a8b2692ca8fe7c406487b6ba9a0eb1194eba2631c7ce67c1 2ff727ddf8cb09ef0622821c1886cb8270d4401658d2249c402f48a6ffbbbcbe -510000 8b496633b233a6ff9deba1fc40f3e1ecff693d91d8abda762bb165b4f10933e9 3a409f0d90719857a525deb2038518acc44e2e710e3f51830c11f3a83c89ec22 -510500 1052dbabe3ecd64ab6a4b0b05f41c6c4131f5beee2028096f688af8da17151c9 0cdd930cbfb6e609de9a22d029c15c5106fbb5603222b8e470a43594d1ee1dd5 -511000 e1718d99ca8b8c0e1f84663aaa6ac9cd8c369e9118bd6ea5919856382019f5b7 8320100810a7678c08ef0003dd4f057369386278d95ac3d9b316a062b1cd119a -511500 df937a1ddd9ab676d6b958c03e97b7789fc0b486d52e1a518f4d4e46d22db830 e5b333e553b5a4bca5ee6f4a3ed9d83ba46d981a3ce30fe8fe0578788a400f42 -512000 38982a86cf02da0b76412cd5bc52aac39854cb1d000c7f24e6b66061c9552820 7b4b3c77c94a5b9de5a7ce479a1c15ae56663e655104b0f0efb5f3adb971cd4a -512500 c668fd92e5ab8abe4fa8c66022eaf0b8387408849349453ba8751194bc9ea391 aebb86a20afe467e4959eb4704849a076a8e02cbc51c2dfe07648562e42f9f5b -513000 fa2042f44dad2c0e4b243fc07a60172d057c7715b7d7f73e9cdab068df241dca 9bf87e1bf1a619c55107e28f3abdabc3bb3267a0b0225855695ccae2be2c8492 -513500 3ada907b4eb50e027c4dce815bc8464aab74eebaa02c3fff63e829fcbcc06790 1504730fea3476e4a5a65059e9e45acf9fde314062f93761273d0d47ef900b5d -514000 b690974d95cf519aa561d59afc9812bf23f8596633d4e43638aefd0a645cfd9a 53527239f3915f67eca6a1f57a5b82564ca7c4c5344668140b960adb23246528 -514500 4efdb833ed17ee35a5c830945a287adb464a23d60f16c1f1d6d3488d628df9cf f6990f581fe79ffb9d1bed01f84a338213c70bc996261e07507624df42c528a7 -515000 f902ef1df4acafde6dfad28852fa03b1961241be620aa057860c9a70a0fffafc f8f7c7f68536f87056eb0a199f0112974f80f4ca443721ec8c1d67c3cbb7fbfb -515500 df363417aed948a08fe0c6aa48dbc5764fd5cfffadbc7945f1a6ae310a9a1d50 d55f6e43fa28f97008367107abdef40ea271780e5d19a561db5f3af215e60ae3 -516000 6af0f998e7b95f5928801133f52c03133ca1d706f044f545812d0e64afa7eb56 79daefaf210fa29d3c633094944a6ea814f73589d3d477a38fb6d68f0380795c -516500 c7174fb637f35bc6822a651eddde06e842534badc1d7a4c2d61090e79510b970 ed427f81415ab5bfc57f4cfaf8461c18a23a2ca0a7ec9b48002d694c70137716 -517000 f4055907d0bc72d6e28eaa1b566ab77904495bcf286d0dd6d7bc297b8fef7a63 74104317e7c69033b643afb089ea06cafe18e13f125bb7a2f381ac88d362eb63 -517500 dfc6759e8ed2c1078dbf08a64b71ddc9ab2a04fff41fbe9a5c82a250cb3ef4a9 5a544c7180a99ca77684597ca3cfb1257ee0e3fccd468e3771c55e4fd9a1152f -518000 3f867c72bf194f1c257f1476aa4cfd18cbe3a5df52e374b1f705e496e06840c5 36fc1c6723e3e48773e1bd8ae04210fdf0a9d22cce523387250deb28c3793a8c -518500 941b4dd50e5124b756a381e83ef95106d15522461c348d5e032c1b61d838e50f ab5d00a5d8df0c54e297611a063ba4357b4686259473accba2b139ee69dc4d8e -519000 2136325d5351d77945e009193f054b04492a8d8f210eef016a51630313a17c3a ceaa807d0b581d95060026f8ff02c392db4fd0ab5007a86053f9e0b93049aae3 -519500 8740a71b16e0335054adba609b5df4dc066d157dcb0511442d8d413c2333d883 216da33354860bd3b2b44d9f217b89d2a203836e5f0c04de39381776c78d43f1 -520000 21557c530c9135898351f2625779248d5c5ad1fa473d8989e8795cd650f3b036 02327cfdef960f127b2a99811b52f651fd5f84d3064dc10b2b8c4c528a362c2b -520500 fdd0b3a9a08562ab9256162fdf1e8aebba6589b585f34ce26ff0ac20f3b35715 cb7b802cfb533b7191e892348f4076176e842e2a598e373e6653c92b62b4d5f9 -521000 4d45b8b34e350a098a5ec1575639465783982db7710d4ad07f7a299a19b860b1 587836bb3390bf2dc472a0b9e20a5e643cb270d85ed4286180f358cc8d0dfe88 -521500 8357476f03fda1bb1f346946484bfa6cc9d80a89b508255c3c4b583c71ead128 2c2d08c950c6437e2f9ff89d0c3b0d0467a7761a0f19d421e0c0846c2792bb62 -522000 a12936a6677badc6d2c8e83d2058abcbd2deb580e5147f1e742e379f0ffbee7d 322277c4d49c9c37e94b84c184e09dccd63cbf0154e61e36b497369c4c7f3fc4 -522500 f0770540ebe64a0de99c169cd1a7d9c8459eae0e67873510f1a8dcf4841131a3 25ae4d82a8a9089095bc4583c9842984d53bb4b0e6a162d369a70802b7f9476f -523000 72d57e281db8b4a79f566fb587e448883bc1d1325c9ffc2931f1100b63e5836c 00fcd8bff8a5e19824f0e98fca489d02ca2d27fa2b4fd9a73e410d935a1b93d1 -523500 97b2d54ba68ed4a14ca1fb4e4b697b2bf8f7d0332272af4531a72c94c35dc932 04d4f8ef5ff03931eb5c0eac18894a9a7ac8ac7f6bc0b34b43420ae9d7802a1b -524000 f5c96b25808ab9cbbcedecfe467e163e3bd9d771a8efbd3cc414c7adf1b7d380 c11e17455d687b0dbee864879ffb41fa6dfefffd54d339fff58dfa99790a78f9 -524500 cc5a17d877467df92ed0b3462d0031003c642f64896f4019da641d1572d693e9 471a8ebde906603f5c054eed0da8b69aee53c35133712be35b22e5b4a8a3435c -525000 1b009804fbb8489d23d5512262d7536375873ef933c154a7058ec1c934f61892 d583cc3f0f7f01c67294d2e98d28e83c81824cee30d1252816a7828c0461f350 -525500 63de360342a1abd256b2f4a3f1a74da8e5bfff409282c8d06cadfea596220f9e 124aca94373c78ba91a8f1c01d89d5bbeded60581199d3b12ac66b76c37c112f -526000 25464aef8a123b8bc5dc4b9f6b83149c84511a88da41f7b5f6ddf4cbd340dd30 ca911108aa51b78a806e58f876767baaf341c9844f31da71959ed4ea2f87d62e -526500 54cfed1a647b8513e845b57381456d983320e1f6dfc26bdcd4e97da73f31bd60 a5639a2ead728587161e02add9b047738a8534d0725a84c5532bdd054e715ee7 -527000 d601736c31be7964de7a76ee1fa2c4771d804dca1c1a268b608f3c77971893b2 1831200e768d735e9bf8b5ddddb9119ec19c43e22b966bd969346814cf454d55 -527500 dbfd9c8fe9edc773e210401cb7341166fda6e1153a1fb47f866b919dbef91d31 5f15be969fa28b64f5250f0787876b05adfcd2c64ee1c2c72eb9724403ed6dee -528000 92d74a8d4df0a8f7510fab8b5d02692442d1fb8bb9046cff981cecbef3353585 b67baa2dd73a4061188c5cbaf13ed1c063e29193fedcac0b5440e042d39a45e2 -528500 b4a034b57dac02980cec5830c0718b0ce4a89bd3ef3f5f36e8b4181c1f42ace7 de92eb4a468c264b4a9ad63eb75ca3702af7c023481c829041f328797d2e3636 -529000 a05c9409ae06d5bc48284e5c624f8d6f6b001cc6f887d459043f442367e5e1e3 dcb56fadb166de779d9d0e4e5e4d30dd558b0ef3fba4f9afc8023ae5715d30df -529500 f62867ba72013c202a9a61da49b6e4eabc05e6d247f2ffd98235b8e4d862e795 915588450e5ec1300605afdbd6dc47954df1fcb45a6a10953db21bb54bba5797 -530000 35c57a8e961f11ffe1cf6712861b43b4e7d3cc3107c28d6d8722de90506a5b54 1c060c7a921b2d8567acb70356957e7aa044d8e37abe1923ec1ccd3f0f7191b2 -530500 0aa4f3b5419e0844a7316ac4b76e00f3230781c8d320cdd62dc1dbe21875dbbd a3bf6f2508bcf7bf8a6fc19b2a75859a8c2d3a68858d6dedca2de5a5c687b94d -531000 b65e6fc5a87f8d30ac2203e13e9e9fa450ada17650d6c639fde4f71d2832062f 6c4e276f9cc20e4111c9c45b760cb529b12e6f6f9d984c6338e47ecf0d1fd5d5 -531500 4fc020cbe21507bbfef6eb1cb30c11359f8ba8ed0fabfd67181b596859a11fee 736ebd1d9d616f4132934784dc13c0ddd6382616a501f11f84071f39bb794a0c -532000 936bf25a71f4f427a32035e860b049c5e0ecf36b0dc007608b31fb9a496b058b 9c412485687232293357f94ea0cf8a76c84e8757046eae59406f5ee225651a55 -532500 51b5d1a338bf32a3273b45d2dcabcc8fde6bfb68f80624624b8a0ccecfacf751 81559753a06dfa90b7ed984962a88154310cefa89233d47edce8438601051981 -533000 d80bd2b8d148cc346bcc49974171c998a30bad85878c6e508d16c728098d5418 cd8c0e674768e8afa69fc6366c3e2aa66ee31b8a10cceba75d3148857442c30d -533500 06cddea66b25e0387bb678836918cca4be53f245e84c01fdd8194ff147377a1a cc77c89ce8bc38a702e21b00df5e4e65f2217fd7e3d330aeaea89e67b2906d7a -534000 0427f67b170428d1d33242707a2a8273c6447a2762ed42e49580526cee35bb3c 66b923b19b1dae626b62a5c76dc9710d396b9436cb8cc549b87a4878f457e561 -534500 de3c914cd38e7fee1888806ccd3d4cd5d39b81cdd22f869cc5c2d5335fa29533 77b2265b37eef1e316d0d480f28bbaeb8faaefee270991fba6bb5680a65f5298 -535000 b4c2ed2b12c9b6ee617058231e9099ceacfbb10e344c8060df631fc42cc276f8 1cef714d86e11d17fccfa377f5550acbdf781a19f272cc8917c3c9886b99414e -535500 9515324744b14c233fe0463842b81e99c1c7bb28d99234d0c2126ecea9a3250c c96091825c57b11639c7eb8ac6f6c76d48c4507af32c1fc95a93fad60e5b1a78 -536000 ba4a67d76d58f76b3cb47b9f89792153db68285c94062df446d924e59ccf7b87 6208b177efeaa145f365051fd3d5f9e82dba8c42f1d0d2b67635c4a908b7dd17 -536500 865528966307aa0504e45931d75610ae56b4c4490c763198c1570a66f75b1f1a 09c2e4d9405d693c07371d2eae527aa1c2311db979f6d2d0abfdc5467b81cb65 -537000 c3355c3c49454bb38156c96fb23c13fe9e5fb73129bfae6c61ba4e6d1e46ef00 29ce20cbec7687f75730f0e4be6c672d1fcf96baa9168eefe3030116e7f06b63 -537500 895be1cd157309627c65fc37e677a72fd82f27d0418e6b43998aba564d205369 d5e4a2bc8d014079e205050f18f390c776f5b45940c5835ed995817dbcfb9da3 -538000 99248aee8ec1681099e7018b3f27ff7d48023639c7a16f846ceba99bfb8b6794 51589b8c95d4c555e3e85904368362e86c1ca65ee73cf4b3a56348352d48187c -538500 8ed90c82d16b675f2e1616b4e6877fea7d223f4c6049c8abe24071ed0cf55cff 0952515dbe216e7f8705998796c926f16186b5d911466f31d36255852c2a1740 -539000 5eee066175978a2e04f8070ec0a1c5e215afe79e6342f882f272e3ab3e5088d3 a8fcd0b0db8bf7fa522a86757bc674077b64491860fe1e1c346d48b5056c3625 -539500 1fc7f87c388bd6e524b114ae6bd9654031d2cede075e50c5070d5f7492238b49 86203c750603c2b64073e488e635049afd299e58642bc90cfc7bd562fa1372db -540000 c7c3d0e72955da1daf3ed29a7f50e39bbc72a97a7a3b9657151e2180b297bfdf d8789c0edcb9150d9cf88b973a2fba35c0e8a13a79e9f5e6fe67eb527f100dda -540500 078244b881a7ea8079cee149a21afb1f3e12513eac743435b26fca944d1f8c0a b0d2681f5339e6747da87fbdc8eea0947f09458e9e121fe715050d97d5380b1c -541000 c1fc5936f601dbe88f86537a73e3082d817270cfc534f985e6aadf1e69017c62 c5025d93f22d3c16cf3f1be03756c8a04da4c330a8779bb156b6d6812b65db25 -541500 f06fc398ee363680986ea85bba8897ca25e7d7398defc7ae5dea8950e5e10b9a 6eb30b839ec9f6b85ba6a68be9a25f4ad0d72cddfcbcf5bd4346e61905e1ce37 -542000 f1133f6d4e5f03eee2ab13868e8a296ecb14fa9a0fb0074e5fc3cc46a1f7f2f9 b1827592124a51a20ae293f4e824c8030eee78ee82ea039c27e427fe4d2da5c6 -542500 7892e32548d849918dd9946be8adab0f8d0842afa1e9f62c066d27924a96153b 421009927f9b4183293a0e7a57882322f87b30137239b6db48168b25d1fc5ede -543000 656da82150e03b0f6920c13ae9f012c768ad1db9da51f3cb36cb08f597c944ef 3fdc935dccb715960e745f505147ea8508aa5ba7c7f2a657a14ee46eec52732e -543500 9c3e877261982dd30c2c1c7bf6604e64b22fcb0ac6f1f31d133ad853e8b2475c 058abb454a8f38b333a57e220049716ddcf596ca81ed33fa28772cbd87968bf2 -544000 1ecd239bf3296b13b04cd7aa240769324beb8a9de6e35f10c193ce60adfcd2b0 7321ab6022acecdd7ec7526d7fd560c768da79151c01e409de85f70e8d9d9bf3 -544500 ab6981fdb795d866908290b102477a670822935da8f8af9c6a32ee740d69bbe7 c1eb309bc65e67917e1c46e7d0f232900974267e048abd48a1b04e1d4a3172f8 -545000 00257b2829d7c11f95de86dee675a7edb80dff9715bd2ab64d7454182f213a0d bf13fcbf0b1247b11accd940ac8772789e081f0bf1cb70b1425d6288c69b1e76 -545500 ea64a39237ad3d242cb2db3a1faebecd3b20c682383b014227a3f230a3345dd2 09c175ccbaa02745d5f72bb6f68a9b32cac259ecc88aa1f49bb30d336d79bf59 -546000 efaebeda777c28c7e35347e84da7681aaa14c502d53698838eea8aba6e55c1a4 79194dc97f5c84f2a55ca245e93b69b5caa44c6bd5e581044e2e26580bcf561e -546500 bffd9b66e5207f5cb60bcdce5dda495ab78fa6206aed6981bfeb3ab4961ed56c 2e133bc3bb1e140288f0abd4ac9fa18fc4e30ba6fa672f75cdea8fedbcf093cf -547000 b7c08bd8cd06070b6b52aafb511d26a3e4dde18e15ef004576de6c06024f2a30 6aa7c21876ee2145c6b97d41d858abf162abee2f179e94e354799664f38be6b9 -547500 77b94303d50c7c640f68812f0dd13cde9cdc2b43c5f6e3fa4c99621be61279a9 31c6dfbadc919ec783b0bdada382c4c3e1204008b245b6455679b08aa7f2a6bc -548000 bf973366b8395a897b56bb1f9160f8144c40ba17934fb14b46d2bdbb32715fe5 a732ddef1fa97dee750cea03675a6eb9557af9ed6314a162f5ebd8ded9407698 -548500 c2f20ed6a252cc714238efd5531084bd5555ab8ec65169a86c9a0ba97b2a7eb5 d029d1bf6706c1b298d9f7ffdd53a26b17704433c42683bc02718ef33d2d70b7 -549000 7e07ebf8ad3697390d81f7381637048377f461e46030c8eb1feb17eea4c9d3dd 1f2183d7618eabf7356a08a0486675b0163aafe13e6b27bb6179fdaa59685fce -549500 7ce04ee7a21eaffbe862646c3a301460da80cecad0e9a66a157bc1d0c335a18c cc27c95b13f1ece38002d33c7f55f371076fc10dfe1b48754e3418a0222248c4 -550000 0b717011e4c14ba25388b6be779ec7a7fa2939c68a49ad5fc8cccb32a3fc96e6 d95f6b2500300308ce3f44e53c38e6f0eda793b3e1d96f698cdfd8d70888e277 -550500 b1388fa70e3a79143b985bbe2587a8a36a3ce7f90dbdf93c312bf375b04204d4 2f81d9add40226b4b3d3f2466a2330e412de80bc31cf3242e0f8e8c1f45f1a88 -551000 b0f768d89c0f0e5929e41afa3e9711a2f6dd04c71519c718ec5a4851f13ae4e4 2b1fb05c01f17b3eb7268d552a99acd306e4dc0107985d6020dfaf4443dadd73 -551500 891da4a1108be080247fbc0089c4cbc2922d25cf2285538261195b41bfb48747 e5f1700d6fa46e80db5586d1f3261b758d374d43adcfbfad70ed5112bb1bf603 -552000 8a4da9058e5aa3a483af0775ddb984048bec5a52dfefe711d620a0d179856ee3 333c9af8ca1f58b6185db26d60b4fbb955176320995ce208f18aaacd277b4f1e -552500 f290fd729e75722394720a4b82e34da44d640af62c995fe6867fdd9167ba8335 e85093bef089d344639461c61bd1ec7819d5105b4f984d423041d035335e24fc -553000 2558178ee645f229d1b39f11e8bc8e423e6665ce3e7491ca195fb72d8a13034f 0a823b23f9e2761e8f32e42f7bd569ebb56869af3a1093d7a170f792605be7dc -553500 001c1d53874f0032ac25fabae2f92deca9235bd409eaac1aebec39bd798830d2 d36b5ccec99827a8a5d775d707a82836c0a10d13bf9199e25a3c31bd17f66370 -554000 e2710db357675cd18df933733e23992517017ab0507fa218fb45bc9f5d812224 786326555bcb406ffe22d8dd499684db1b8b70df508572f1ada7dcd6eeae85d1 -554500 cd244e1a5feb9d4f3a6c51f92f1c9396b8871ac5a20cf587092abb68b4fe2eec e7a78e8e16dc73cdf9064f039df1a67996bb3eaa744f2fc0598bd07519078b24 -555000 1a6ebd86249e3a3837d8a1eff644e240333704c7f9c48515e849578016d8fc8f b5da194a23915c042e044b0d3e5e1856f7640ac8344a013d7a1c459d967d6eb0 -555500 978b357011addba581355b92d3faf71397a7c55689ac4fb0d4a6eebd8409f714 519677a9eca60cabdfcd5e888ecb570d09275bb7e2585e9226a9b664ad0d7fe4 -556000 edc28b6ce373cf5a5d13e86ffea09ac385d8d2bd251ea07617b10abade558e12 7b3f6c61707185443f2565ad2f228bcb006302a1bec5a203f143e730c681a9c2 -556500 95ae0bac1e11d4df7fcb554f665966b3bb2195010c0cddf48d07803743149578 1c9c7ca6f9c8b40134151daca7a7cd1b7cc24deac24aaf2f3a450b34b74730ba -557000 a1cbf8cd746fe3b27616f6515149cfb57408d82b8147c19510ad13806b7845b6 2287f21d56991d98d17edc545f93a85d01b7919fde25d726cc9cff6f62d97461 -557500 1cd1617ae1474529b7b4f322db9442763fcd418410a3c3e918e17f13966491d4 e71635aa05a9aee0ca857b41574d348954419959f8782b6aa3b7a3e0d3b6fb43 -558000 ecca0843b0d748735413e34ca513454ce2497271cf04a9d12455f0bf07c09f22 c3a7537c5ee0d6615a53e3e30cdcc6433a554a120756be6247f3c3b703f023c9 -558500 0bc0b2dc367328ad409219afddf852412ecedb43e048ee73449cdfa5e152159a 64f4cd8ebaf6f492c200b11b080c521f4efe87e777818f9012e969eb2dc0fb57 -559000 ac95a1595559d38fc68c9dc48d9af40b3e31d71c292a83998398af38f09b3fb8 a65b3a0e37cadbb31f367a83edbc4c70d0537633af498c9ece211c681fb9f671 -559500 06afcb286229def7721d7a5bfb22cb59f1b25c6aea819bd26456d5fe0baedf74 b871a3c694108b366de593c52d6a1b3c38af1849b0092e5474275258239e6088 -560000 538bfca7649306c7ad77eefd31a7cce9b81ee7ee9d20d97322e9f785cb555afc e08954b12673a8e87fc4db6f848c2129d39286fe856ab80f3a11480a82772963 -560500 05fe497d72e403e9753264fa5d4a7348843e07afbd260e21fdcb9898d9de63ca b538d81ebe3d0367d4820f155315debd0b078100fe17f3ec6a0c1b1d989fdf8d -561000 b80da09d4fc326223399fac5659ad647dcf37232eb63546212c7b951d429effa 014c43fc1995d966785af2772de5f8d4738b44785a2bd81145d32236931bc978 -561500 998927d54433d0ea4fe19a4ab0eb8e08ae656e8cac608e3a824bb084967a37e4 a7709319ad385d1345ee6171bb57bef2d0a648278e6cf763068496eca01d5315 -562000 a005e7c48077a108e353402f478f0f3cdbadeb95f360f6d4d056ec8aab302f7a ad678ad8a4b421f5211b5953c3080ffde18f2a395f5f77a467a6a3991e155b97 -562500 cf4a618bbd1d4eec4f6ca3993fb2b3ce901592c365c2b7526c9de2d0c98cb74f 05921bea10fcdc426b73459e8ea0ab421c1635c93b60ee8d950cfa0efa91a126 -563000 ffcd676fa825e67eb4832cc72b5767f50fa306f1dd251055ee3f623d9fbf4d6b f3fcba9c0dafd172664da1d0e692cb1f4e898f23eccce5a265104164a5ece2d4 -563500 5f96af414cb11afbbcf48a7fd1738fc1c8ae91dfe58ccfaaa7149264ce34c5d4 54756714dd75d4cbcf87b452238296c5acbece0f991ff2cf3b239d6af4b7f4ee -564000 0345b35925619ae8f774196dbc6ae52b2d065ee4ca6f9ab87aac366307e1512c 7ccabfabcd36f82cc3195d587e6b530f2e303525e253d84376f02b907e1bf611 -564500 478fd153799b8afd93360f4288321ae7e82aa7bb5474f13913274834bd4b1ba9 b73b7af475c03ffe2bd0e9b09f32a966126d650007f991cde96bc8ae208d2844 -565000 4bf82342209df889c321571400c9170621b17c9b88b60b609a7a9a31a4e6879d d33e0ac1f8f8614cfec0768dca67ba99561976ef142a62171bd596ca26265462 -565500 18ef43d2230a09c588644154757d4c3136a0dcebbd1e7169349f280be113ec99 d3cff22fd147792fef86c9d94f7b8553c555a925e7038e738bde608c83ceda53 -566000 178cd3b2773545e457ec933671f4b7e0cfa269454371789d79c4c73d879fa497 776636ace5ca4a51abb4f04c22d5a2a0c51d42368f43b8b776299b087d1bafff -566500 6e70ed03c1ade6968a6f18aed75a42130abe4674a9cb3d6715d5320474a310f0 9e51b370f5e5b6dd65ffe6fc854265dc071b7dddad6a68e25a6082d60a4573e8 -567000 6a0b1d677c5cc0ce3f890ae8495c70403ffae874414fec9e3ec8b3aa73bfbf12 44a2fd59a3f18b4d59d7bcabc842bc21681b3c82613c95038aec10315bfdc050 -567500 aaa507e4d8344e885c748389b8812c28ab49533b13fa635bb345a4495be34850 f0b2d2e0f7477c8703fb6c7ddaf4d22c17da14d6bb1be606d96b4fe23932ff61 -568000 058e126ea94bbb99030e2be4364db58bbe0703c0fb4c3155ee7c386e19efe976 e68dcd0c11aa8d9b09161d9fdb25196b0b02017743235c5e77c83314139abc6a -568500 369e444ff13a9ce379c2c98e70e2e50e18c823b4b43d51e57224f9d7bf7c2a82 e5755456750a9a92ffefb86ebd18fcb6d4f790bd51e47f1dd92d5d0db8c60b7c -569000 50685dcbbd12f30781fbb546d1a4cbc349244a2d6e14ccb1530059e4073fc0d4 5841f99c2648c1075709873b22b8bc25695c01fb146b0e82291b6a0f5cf16fbf -569500 452253574aa43c9f3ecd39f7122789bcb9c83e343843540860b950ff27d673cc 2ab70f1d2aa896e8a8495df628e675c983e45047d719a9e8fa0804f34a8f82e9 -570000 c1b6627d3100900dcf795d2b684e83d11a797d2302a3bc058dab61ba109e5d08 997761e1d03f77cee9256dcf268f308a14899d00386cf1cdcd9df39a57ade810 -570500 7cd59e7583d4c4878b1dc3171dcbab4832d2c4d61512d7f313ab88782a9d9336 0a439cac39577c5f0188a201ff1ed831ed2fbd5d819c6682d7aecb2e4b77b7d8 -571000 6aa099647512a9654c54e730e3f1d4a1fda25ac58387503932ded2817e5b446f a629a59a6420e7edf13f0a7dc05a918f86f9fb337459a1f85b65cdc71b301d92 -571500 a3d2f0b075cf3e735e586c69c3eeaf7a07cf0f391e1a6ecada1327abe8ab8c8e c97c75ac8bd884337edb7011ce4a68f31d1a06f477d821b9e473614f871e059c -572000 154d5a1e996a34d40d3aaaf2244d5df055de5902201bbefdff166b63d440090e 38fafdb36a68381be6d3a3f358ee61f1998c8647949eb6659f8794c5d84646f9 -572500 05d47c51813cee5f42bf7803a627ade017772b7f4e734fdce5a824edbf480359 ce6eeaba07d4a7d43ae137f3f66d7bd2c3ff0b55b973c0e87283011f58f94fc8 -573000 2cc24da51032f6db15842996a46a0f01e17e7c1fa178d34f4d520e57a1dec5f5 814f5511a95d2112e9d6f5ff9147e4af6d2d14c674008901888a59d77adc0127 -573500 5a412746451823e5fe7cf63b331c59b6b1808d176c1f3562631755a1aec62267 a8a55f440729934a987fa7bcc21e4bed9ae4cb4fdda5bba05f328d33c1c93dca -574000 4e71a21262bee73564eed3938de4c2a673ae763450fcb183bab52fc3739e9307 f5fd0fbd347c9146a3356914145926887833b394f0664b2e5d098660848e8b5c -574500 bee3161612969794e4cc7811c35fb9fd844623da6a5b5f2dc38f32d50728ab90 d97f6edfca11c6cdd984f126252ed5c39587feac95f4d412a947fb327ee9f4b9 -575000 0560ddebf2a1fefe36dfcbf14c0b9e2101445b34e79b4d2d2f7c329c1dc5c97a 58a5850806bdc8a70223873c23aa3a5975634c989d8ef4f4f78fc0b71c025a59 -575500 077c9db46dee33b8fed0edbe55dd09ced1c04eb22096d9a7f0a8238b764a9005 a527ce25eff18c724535306c76670e1a44b010183ad970d41e4168c7e47e8ef7 -576000 f9762a0e8b01efc84c09bf94e0eec3168852cac22bf5e0e657957ffbeb857c08 41b866640d3804e09ffd386d7f6b0cfcc5e95c65991fa0b753c875676eec7c37 -576500 fff9ba66ac3dd62ff0931e644ac522896b5e86c2a23e04bb4f2501145dd96b75 def321280e76f1a8aefd6607ded8cb73769de57f19c641b7c6356e60105d89a6 -577000 69c48c7908b7b71bde3ba3aaacc99951cccbbf4ca98fe699367cda9c2101efe1 da1cfb6020117eb45c262bdafdc11ef962f6156c0c95e68cee1bf1a2b7b9a1e5 -577500 9c563371fc767b2343d7f1cf6f23e4cc7b42aabb564e94a5cfa940cd84330cb2 33aaa085f7076d2841dbce57b42bb7c61739c76f041c130becc350efcbcb5138 -578000 e5b36705e126028107e070cd6b748d0ba1820ef3f0b7cdbd8c60a822011afbe3 b2797c8eec34eb94ad7b5de3c93144e6511d79ec389cd2b3037abf705da704c0 -578500 0bb4c3b62c096285827dd7079f91bb367f08fbf323f01cc27257c6ad1b6b09f2 2709c029d1cd3164ac618ca33d9453913f52247ca266755995eba29516fd6693 -579000 62ca69f749191230d6588250d41ff452312e141c30bdc253a4ba473d3736c8fd 9690b50bbb4fae4acf7114beebb9c8f012328638fbafd2f54c18db4983c019fd -579500 ef36ef78010479cc9664a2e7cbbeed19da7b60b990ae1d6ca1c62815b74e4ac7 dedc37c50f5ee81e9697c49243e55aa6ed5c5ba8d1d56305c5120b308600fb6c -580000 439f43597ce36aa161cc2c4cd7c25607edada72003a7fb681be2f6d8b714d14d be5636a23710b20c61b3aa181bd75a4e0992dbfc1d267be7c66a3bb459ad10cd -580500 c6b2c13db62622a7c3ac9e8072840de5d24c34f6337fc3d8f826933501245deb 25eba3116b640e04a77b843ad79a25847d31c2c5eef7da98952ebbb526440eba -581000 4dcd0d20d94245063d630bcf6d8079cbc52dfc522c0e320e39c16ca18853cd6c ee3c988f0ea99a39c2cf69e88ba22aedaa2710f49bbaccd1ea0b2c1ee65648d9 -581500 44b084102871018a5db5f990085f3177856a38a8b727a36b29837c34e4a8ce59 6d6899031aab90e68c34f4bc3c1458960c7debc0e5e88de13bc0d29d9a4f1406 -582000 4fc26f1bccf775fbc7314ca86532fffb93b9be94bc6f1bd75fbcbe688eb9dc1f 07296b68ecad02d38df4dfc0c927b430ce4c978fd42772740cfb185d1f73cf08 -582500 fcdd7ac7dbd7a3ec5bffcf498ca341ea6f45eec4f07fcf5d838805979c154e75 1fdcf21608195ac2f0076e8203f72e8468099613e8edd350440efb4fa495de35 -583000 d32c77f1ee2542c91734ccfbbba36b35dc4b76db17374b52d514ab45e03031bd d7414a5f1b9e801ffdd889f95d91b381486c2b7bfd718907df3e4f3c16f831aa -583500 bf8b25a2a0b19d293bc739d63786a6e5be7cf111d60d6cfea462dc2cc7cab22d c03d273bfa3ebeff31d43a7a1fe34b51a5c968676dab85910f61691ea66cd879 -584000 b3ec434425ed197a317fe360d7f2bdd065a7f167e5c57bc9623cd150df2aa5bf 42bd629da8bdfeaa2aff0cbd4092f1db54db6da4e4487a7460ca7081849b1d01 -584500 f09dc804f47fc9fbd5a391883d0be1d3ccf5b71a69e9c2571ce1ff55b83422df 28cec5b73ebea11f29daf62db2ac9a594a7497ede4087e0932881d39343d15d1 -585000 5874d180e9c48959e292587310dd81134eb03197f0257be1516c7c50248fc3b5 c5e42637b4e90535090b09f2d90d7ab90ce46eb3255ce6abad941ff07ab5e0cf -585500 a6dd4e58143b11d190e168b1dd20fd7da47ba2af0d089f70bdb5ab423c8f47fd 134ef498a9bf87099abd879d68ad7d67ef4dc45b63bc16438aa0f95092e34c8d -586000 5fc5f5de827b01b620304dc74ea53a0fea4f814bb51ec5fe3b6c74ef560a5917 e1d0845de83160f08be85d114882976278106adf7a3c16ce16ff6f08caeeba7b -586500 2d1270ba120a5cf1427736d7f89cb05c42af508e0a0038833c9445dfa9c66fd7 be7998a06e1fa3910cf77a7cb385cbc6933abee919664bc52a52afa5388c5b0f -587000 47ae47f30d7d51e5b874e5ae103aa38208203f2a380b624cbe1ba122d222f9e5 81558ea382a62cc93ccc002e8ba9d88058ebfe683b05be16fac0d84612ad2152 -587500 a558bd54422bc5d0a90c20310f81d9901a9d3956f5d5505a5dc50b6459ecaffe a8994820ef7c6f2fd8d9b6d710a0f83b537ff6fa1368060418cb00ddf642f357 -588000 fe5749f9e8ce47f885f4335cf2b24a6659913ed62e7d5af026ef0470004d4983 87e2b4277260305d5bfbd921b2d4592e180837e092f2acd3896621cffa5228d4 -588500 4c798283eb8cbfca17647b16a919d49b77a999d0bd319fa624ed665b30172e21 a4c43d466e6429ac399cba93e1a594703176f7d1d7f86990936973120554c72e -589000 f8c9ccb89cd751d66c9e2b053cdfa670556f6dafac1e67a12f8bf06790c9fb93 ef76c7bdbce08ea6dc8dfbefec9d64b2bbf3180dc4304ee7e39d8c098ce3602d -589500 0971e83e6a813fcc290f352ada5422a0f48b12e15628f9522d1ce40b2fd01e85 cd5ac7829f9c4de5b606b3a5406383ab2634f09661977f867c47d58f89f16081 -590000 cc8a0c71618970a1cd40ecd78572568e8522faf1c6cdf597def52feaabd15eed ede2c72e45aef2c244f56183b127ef08f9137effd46386eb8013f1435de42f08 -590500 6c876707aa719eef0d5a9534f9961ffceadfdfa16e75a4a8c7f5c7822f8d9945 44d6b98fec0842acf25460f93ac90ce132d3600c752bcfb18d3e4bea90b9e052 -591000 5c5a7be46768f7b29d8912feb8eacabb2c592fac374fd8b1c9d74124a5bde94a b725f0ce70d650d386e7fae730da1d44a308d2517c91e0f6d6fc659316647202 -591500 4df0cd912fb5772a508f9ab6fc5dc26ebcfc8e5fda9026d682cdeee3350f7f99 1a9e6cf241740c2f4f615bf2017473e6eccf52ce14ca3c244609c83411749374 -592000 5a9465ba2bf3034272ebb1a8b742abe5b66607193dd04f838bd9a2e9525081c3 c36756b7c0b4f7577f33bb7a6a2cb06d444e5bfac823242a2208a74dfa4a5264 -592500 8e712cb434a6086e1068c5a36a70ac8382f8bd2df8f3328e869b5f74c4d3e268 1f6f8f8c7b6abb35e1bcc30443a2112a1cf6711f020c6474ea2b987e122e2710 -593000 5d4b59deb55edff702d98ceafe7e74fb2c27a9e82b3b8f38a747c0013210125a 397321c39e0255bbf2f345d8c410a3a75f0cddf11f90b04e1fed22d57313f436 -593500 efab77d82b76d1ba1f130c61a5146828ef22808cabae00e8aaca746c9701756d 5ae3383c918a2d0de41ef7e68ecc81a14448ae6265fec8146377b88c14678583 -594000 2eddcbffecddf8dd19c6183606ed678b8d3c80b3d18a03d1f6c98de436465bbc 313ed4476687d320b09ed8f775c84f848b315ec7051a819b7b5db928b06b10bc -594500 17c2823062fbd036efda8d7a6cf9f02177470df9ab03a1ca6a49a4feceaa813e 967817ffd15c1eb09ae18be9c89af301d4faca27bd1435a4c1b016328efd7452 -595000 0b2d83d89d4bfcf2ba0bb0d6f4f002f83b33532a9c72d204b84c3624b82d1d12 ac1ae8086c27ae5dcb5491883fd2c00dd1936ce5ebb753bb9721795b51ac427e -595500 94e93ae2421b77bdb8eebc5a889e0dbf64bf0af3a9d7d718b92c626186186adc 58b3debd63420f3503c3f813e1fec6e2dc9de31eabbfe6a5517eda797c5a1381 -596000 e556867900ceab6ad0fb7923aaad1331b8a44fb432ed5479bc8255a9f9889db7 5608f70ec745d7dd10b0d6650661ee7db9d15ead665ce8062892cdb60c51b81e -596500 e07b8c8db8312393c02cfe1bc00a1a5ee6166083702d2db0fd24297095202f77 3df091b27bde63d70fc8d0feb4da1e97ee21915b24f6be2a60bf702051c243d7 -597000 8e07ad6645a83dc63b311fb7d39bb583980164e40032a0821d0acb50953b8ef5 96c796666a2f4c215410baa022874914fd9c04a430313d38e98f6c5b743b969d -597500 6681cd271934d16f89af3d71bdd886f5d3d50f6ef9fbe17c4d95eefb6c770974 e7909149c034c8ea84b92f77b39a9331560661cb4c158edda770306a4ed7cc9b -598000 92b359d658152c31b8c2f32c4509f3ccb1cc18b4544745608da9a230327c109e 3f75a2b9ea70de0fdc330ebbc5f83301dd507c4e0fe536200402cdf30fd28a12 -598500 be474d552a4f17ec673478af48534ad3c65eef1752223ed3012534dcc4274db4 9c304d0d24348fa013c7223f1e05fc9092a773e6da14920e628baf05669a0f08 -599000 275ca25666031af015670734cd4fa02ea0e0b099921240991498e684bc234940 83b44eaabc822a3d26f168dabcbb175357e1a37a025813fe30d5e6560418dc4a -599500 f20a2a85028e0a3c65f118e50296794ae25821fb5dc0a59f415305d826a827cb 3dbc1d013d4559da355fea928c27fb17e921124893b7052f2aced8c8ef9c9085 -600000 fde9cb0677887e2f966c3be87d1780db88353977fa2e426249d9b26b01be1db1 74fc8f58d336eaafad2f515f0b5a5eaa679c82160f2dc54f35fed44bb845c395 -600500 ed2fdfc9d3b07cd7e4d4fb46b5cde484b7ea5cbd436608698ba0be6407928d45 78eebaf2d54a3f5ef9c98b58e75325a263d7040a85d2757eaa6fcd9edefa8bfa -601000 3a7b3e53a5c38bb7d0600352a71701c8c7b961a9936d319ec1f39eacbfa317ea ae8e3de2cdfe471244ac6698534f60a82a93e59b36ff22135ad57f5ffa9eddde -601500 9ac84b004712eedc9cb82e4eb4f459e92634ae20ded19ce2a01b5039bc9be041 b1800a6430feb20276c6d1f65b1042d5da3d547a575d7aa8f8515985e793cc8c -602000 e584426ba4821ce97899bedc37ebdc5667d94f796853b5dbfc8597123f61cd93 670512bb3eb55350a01e55a614addd9a1936e220c349b5fdf83ff85d36ee4762 -602500 98c1693b6c94cebd5e17bed36779a7c1498f43d83c3fb9f833ac42eb3b1f148a 4335ab6f363d6556b820a8527702f5b224789aae810a9799c40289f088d876cb -603000 cc90f10fadd0c325018a7f5b2819ef126eeeceb29cfb1abac3aa4d918dec8ce6 c323abc97d8ddde6d935f4c4a3748fd5df141948b855062c0d557814b6c57582 -603500 88a282051002196bd7e47c2d4d05acccc49be9e0a1958c608bc8857b0752d805 4a129ae3447c19b8a4ca1812fe819cc571bae08dcee26b2f312bdb2292e7567c -604000 8423befd6cbd718339237b9fd01a9bbc7de101525a01e45777cecc593795e76d 10125b30e2a5762ca8991b3ee699bc69e552b65457759c8b0a85468f52575c2f -604500 5f07bfc38f07c663a551462ef3fffbbe9a1f01d54e4987727649b2cea7ea3716 f17db8519ba7ab7e3cd0442a008bd05dd5354ddbfc696dc9e2aeb07385929acc -605000 691b12ae780daabc6228123ba85e5d4ce2c48d1f6084a428ed5d310d644ae101 15ecf51f40220aff461a2662902a91b0ff974c6b5dfc6853a37d492ad0e7c507 -605500 52537e09d147a2eaf5a3e843ce45824f3a0db686f36cbbe72f69fca61a2b1c01 ab643490828905c7be3f1c8afe6f7755a27c4cdfaa5c8488fe2441aa6afaa70b -606000 945062759b3b417205cfff5d9b2e1c29d29fdc235efc71971a5c930ef5fac2a6 5cf40892ca34be01dfa549d94b8784051375b2949ba916931a8addf7eb3a9216 -606500 284cfde9bc92fc8a9a75636ed0bb98a68a7d26fa82acfdba09391939c2e9acdf e0d8d1c85bb390ccf48b59af60483c919c08df0f8830de5befe65a43a53a99fb -607000 fabf1c22a50594542dd8cc8e0aeb6ce78992e1fb97dd46f25b1f766392b8c466 c42f95954963685fb338b1ebf0f0de3c8fcbada7fa53dbd4c0472b7cabb75eee -607500 a2af7276cb9398592a0f0d137875baf3d9291a606f583b269540f9ac44a17ce4 b5170fbaafdd9059ecc043f1c4ca714de50133bee7054f8c119e0eed79e20ef1 -608000 6a78949783e00a8ac3d832c24e69a2c6fe028f110e8f1a7d87d652acfd5b6b63 01ef19adaaf1a1d75900879f2c7bd5366ec4a6811ee539db16e81a2b981c192b -608500 1941dfc27e96aee1848d5fc8ba94bad2507ee14f8a24235e4b35af5dc0559f05 559954098665a3b7a698445445daeee8967c092ce38be59cf1fe78ce354d221c -609000 ddb824a17fcc47e7312cbc0b80838b8f4fdc077d1f8cad5b08008aad8a25afdf 528daaece3c6a912cf0859f93018845f781575fa67f27479ccd56480f40b8c10 -609500 3f80a004163aa45d2c9d2a1c8bb238a15b9db4214c8b0ca08effb0f37697c40c e6a2eb1304a43261fa54127676cdee58792115ca1b400c4a08261f1e170f19fc -610000 0362121a825d39875de7eb528be247603e5d93922f21f738f255ad44171f5edf 3b57b352f45dde9c233dae766260ea380cf6114c7682dca95566e656e9be1511 -610500 d39319109dfd619800add37b85ab545fe8832c50036eaf1aea5489348e749f18 14c16bbd895be10be482c66ae8444f39cfd67f9c3c244f86bb3f309f3f38ea3d -611000 274d0b2789a39a2808a69e9c7d4fa6b2b34b7be5ad55d541785f6230103a6110 610d4811e3da6b704ea224ce3cef798b3fb9495609971c09971691d88b714885 -611500 c25930007a1325f971285a32257362f90f6b5da474225d3cdd19b9053a55e6b2 c052c3e6c7b866d2212ecc66d4956d8b3c0a9b97381a822ed203ea796ba58581 -612000 8dc46e21fcf1b95e59d6be6454adf1db9d141d9e78d583c0f4efa47e0b2e38a8 538c9ffcee5485b309bce281d6913a254331647ab43d492250c66318503ada14 -612500 48c70c688ae362b4ce2e19325b0bf5335301f45cd6f0f562ff263d5d57324a2c 06f90f226b98bf0fff455478d39513800ed400dc9dbf41c3a6e498730c883e42 -613000 a05ec2324bead1349845a8000c76ff7705e0ed1f958dfb46c92eaf3180f301f7 4d6d1eefb176cf04b6cc0e9554cd81bcfb00e1f737ffe5e25e752f9eacfb20bd -613500 6d0183915fa23fbe61d2cfa7dc9ba9c54c164b246d9f3ea2bf28c675203896b5 e233a4490b16a593a62853877efc01bff2e03b4e5017027fda754056171236ee -614000 dc4d72e154553d04502271aeea36609af31e967faec981fdb7aa7686b194ef72 a20198e44d09d5a45d18b1b2e20911f6d8840ae7618e39f1805dead4136ff220 -614500 401187c2be8053257741c3c78fd751d5aa80b74239ac1a5fd7c2008623b8056e b3d69a8f679aa779dcfd6b03d44da4318c10241e1a87c8de46dc2067879e7561 -615000 a7edfae28117b555c502b1b0866e70c2e45b2b53095b0b3ec0518f76a3250e96 180c90afe2385b2149b5622d702e1ae33e1908e03fc9ac457f18cc86e3453813 -615500 247cbe6b3a28a410c816bbf3e344fd707f5b98c9fc7ea74a653e55daae43aa7a 675ffec485147855367994e9f3ab4ac5ad7bedfb39a35959ced78034e9a04318 -616000 091e39d1de4719fafc22075635a0ed10d1d8b5636a21927557b2baee8bc453a3 5cd5dc9688dfccc2024c771720a75202758606c6c2b62b3317eaca215338eb9e -616500 245d68d439cb7cc9d17d41d8748be112448c1c3d757746c28c32e3531a23a66c dddbe95e870b48d8e1d3be72da7976def8a5f96e20846bee2ec8d3644de876bf -617000 9a08546acd2859279fbf0a140d792be72040b3b5deccfdfcc3a40d640c60f35c 3fa1b0094367169cfe3c3047b01a8bbe5bd1179ea5252153da7113477dda7bb6 -617500 ec4c7a99f349f9b610a1c2c94f01fd8e37bf98d8feb6a68874517a47b27a199f ada5742a01ae9d78a4aaa0fefcc2542633e90bdd178f540e802a4e5bf96368e8 -618000 30bf0bf59fc693f06b630ff38f55f5788f24b27fec1c171fd5f63b6a75729f83 a4d0bec878322f07128ea1f7318a28c492a27649b4e216332589628ddd9053ae -618500 095af87395d73d93df9f2531ad54c6a486b0c98fff5e59a75d9f468e2317b989 c98bdb9ed3f618281b60f496fad0753ed0610f95899058a5662a45bdc30f2c2c -619000 53c7aaacaaf469764119760051cbb7be6806f80d51f75099d8096831443712aa 8e52bf819476612fc0943a9b56d5027935ca897f9a5dfb686cbedb8dcdd83bc5 -619500 7e55322d59a65d0ff1be11ba083fccc9800550a273a52a77926d5a67c383f429 1cde548b5fd12717415c6f8ab191b0a73aa77acfb6c8db2ab9ef1f374bb8fccb -620000 ce46ee172a243c059752e237dab267c4c95b111745b808bb9ad1f8e99dbe84cd e14873bf1154683503d0b3a1d0180742f3eb790efe5a968845a337a4877f9cc8 -620500 31fca5e075086e3ce312c78e4e67a24a245c48db04b7d07688a46be3efd12560 d5c066fadd66b4053f35e728308e8e1e9594693f9afe8f930e342f89014e1435 -621000 c27deb337c86fa6c1a9c967c1c0e967d66ca91c3a605ee42ca9ecaa3c7801715 4bf8d5ac8c9c275f434ce687e9aa2e5bb0e1c1a8634ad7dc0380ad74e9f2a471 -621500 6d6de5c0c183af66e09203c1f851e005b11ffc3e65821a0b0c53ddcf0577a86b f8e09ce62f6793636184630998b1cdd6e513174a268fedfa3c23d1beedd6f127 -622000 3bb4c331c1c410066bfc9c84fa96f35f008d7ebbb8630f35616b07d3a8f6bf09 2625b34fe7f2c205449f2ff67a4bfe036ef5f479b520c16f0fc16ffc43e5e713 -622500 b69c590df86c64c53eec4355ff7e4525ab0ede7c40da8cb6304556c465708619 ea025a51dbfa831f98ebb1597cb43dc29f34d18f5522b57ac06d7e19bca1ed39 -623000 248e12a541844945c6b91e45f24d7f63db3dfb41016952e628c647bb82562c91 d2dcaa98eed5db5e34581c8bc52808819c5cf98bd564661252e24fb7f98218d4 -623500 0f6332963afce6ea94d654d103c3604c724a5a6bcdf6e32bdf9a708d10de519f 80f5b0685f010693bff7453273d0cbef3d878e9753b19e05a5d2fdb4984f8a0a -624000 3a250bcfa462ff8b750d0a725962879d47832f0c77b46dfcd27e3eb4bf352257 f75082779f75cba11e26f60eb9556caf48daa15221abc2b4a83a1cdfff9368f0 -624500 6a0ceb40f1277b4289334b6cbd593aa5bf593160ea960b4887e40afd2b06d767 54386a3f312db13d8151cdb5ff628ac2e9e13d897287b553d581a6c74cdad388 -625000 c28164fd18e1087787d2e3c7d67b8349aafcadfbf815fd7547fd7ae8da9e7937 319cabe08b33898fc3421e1cfe329711de03a92bdf21828a59594e813e71393f -625500 00c9e51e1237a00f30562f40f8d7696876a62523a7888f3019103f97d27c2afb cc7d1fd4e2d9a95e3a9a7e23f44a96f6840036265a29cac5b4a364ae1ee1b806 -626000 452cd22905dce67c27114fdc0b6ca64f4127abcbaff999b7aed68be214fc9313 c969541e23ade41ed8ab864eb6fba11ab9ba5c6f29374e666af4912c2c076de9 -626500 7a3f9fe36cb72b3529747754309d2fec46a8155a6f297bf5d9998336ca26ed2f 9184cefba7d61de4482fb57cafe1420eaaf58e3f2fe370e9c22f2dc235c26763 -627000 d8f9b2f906265aa50c5eefed906e89c06856dd2c25bfa2df52f402fa029b6c6a 1c5dfbc7bb572903d6eb6a400fa50df3c18c87cedade5b4ac63be7037f050a7a -627500 711651d2f7440f20927ed66e680d833755ffecaa905c0712ed31e1e06a81a4f1 6de06425cf412c7d272841f1b3de2652b15d3300902c0da6b7c1b08bf4e14112 -628000 1f04acc62ae096325174e8ae11579d88e65ab4f435e3bb8c41896a1cdee6e231 c87dd969f7dc7a3a356d7935a69e4c8a4487c72e7c623f49cf0f60cbc438aded -628500 f55649153110900f0fa6b7d2f9dd6c293bc44ed7911a6e4d52ebe5563eb3a4e5 de1bf3695afd590e9ede9881a431abee861f4cac9ab8b42cfdb8c37f0e02e19c -629000 8e7208c5c406f95dae4ffd540aeb30a111696ed10374f03cdc186db66295f054 5a8b55bcbfe3fed8453499ed4c4a51233f65626132aa23ff6acae30dd5cb3800 -629500 30b5177f1554053efca360e8acc003ef0cc4ae26820331715fdfeeb2003daea6 f7e5d1c5ed411c3afd3a51d63abc4f29fed49ee8bc2f810481491c138cf09183 -630000 9bbdcad95ee5cacc45ff51ca8d627ec7a971b1040368ac62a4616f873623cc79 306b7845856f157aa25e14e34165e75ee5abdef7337cfbfb9611f628287b83b2 -630500 cf2b412c6c992847944b1fb396cacf61bcd03aaa460cd810e3f42a2866e8d729 8d2c8d7be61fe16d9f5c0f5ea155eaae7f926fd8011209de27e41cc67055f5a9 -631000 ea5e4b4acfeba1f4a69c63647cbb45147ba1dd101b9fe58843dbc6fb09f7c12a 2ef37567bfb65be1417d9b5914570c55bd88da0bc07f7ef7389e6324cb0b528d -631500 539334450cd6eca49473d63e4917725250afbb6a546a025b57b40e4ced8ce63d 865fdec23689d881dac49ab8fe9a20c5984f42b4be7cdf3e94118a4baf4fdec1 -632000 dfdc58aa41d2ebe7751fe2b3ff90f0496e602cfaef1fa0f1c25181a3be4cebf5 8e3f86b2b753e8f342046b61d84ed4d2e9ce107d7f30a47361e983aac874f448 -632500 54f71b9330b758d881d325e8f3ac9e0f042d8ea1222e52b580a0337a3b4f3fde cc0ff7cff02212ef316bb6fc2a131b018fef8b6dbfac01b9e2eb275c9008c613 -633000 67de40386baf1179b74ea2a750bd20d6de8f6ec3cffe5100aa3307ec81bf3a4c 7d69bc05bf967c291b2156c18c0851caa853110a8ee527bb9872001cd8179b34 -633500 4414265aed7c038b6f7ce24cc86619b0596162ced270a87c70a59ee3089165a5 09970b09ad4958924d24703ec56fcf49a7526a0916cc7f0f841ed9796bff86f0 -634000 a55d577e338fdde481a3cadfea26ee6c1777ddd6e35e66040a4d99455626d9c7 5da3e590cd7190a473f7d61027754e5bc50545fceb8867db96006d3773a2b746 -634500 571d3172a3095d0a34747c18c2e2cbaa4173a09ae3a351736b2b4802752cd9b7 6799dc3c2b9fe39f72a22e6fe27ebf46308c887e31245a5cbcc2a55f1060ab44 -635000 6786a43fee0f379b103bd594943f26eee0f0ab3af9dadd36d6afee547d7ff8b1 60794659a5de639280735ce3ece1864a66e5754bb1608b2aaedb9874a6c34d51 -635500 bc5896373cd6ab14f28a690a7d59366ee57a625cd6291c502d64a3a9a5969a96 cf6d7eb9c0306f24bd7a47fa0660804b633f29fbfb647e79d03a545518d5ba17 -636000 1aec8a1d1f6f5abb68d49597795c24102bfb767822705205486829ba50940cb7 348625a773758822cae41638d27628bed89a118fdff13dbb773ba28471ec914e -636500 cd844ea294ba265e14ea515b603d35c2dd13c9c402a4a1a13628925634e81f23 2c881b78d84e98a3a6dffa6d4e55c347947053f184c22f2a75bf62cd779febe6 -637000 7f0393f05b3ebfd7838740f3030dd915d2125e9546e39f503e288a20b14d29d0 ffcda35e368f4784c75aa0e6a98485a2b84fa1ccba37f7fb5a6b4d4e187a5033 -637500 7453182caa6345472aebc820d839d70e916b8e01527e69d2451e68df9f5fff94 df9418647903ff269234df3583ba76f054c7fefb3237b47206f7e25d9ac118ac -638000 2917816bff7d73f4b4f03a31fdbef162ab7b2bc38e2539952648f7e9b66dfdff c7367a49d181f9e332613c76cba3371c16cff94c10a6bacf504c8ac404358b74 -638500 e10674d6c53842c520040ea608584860418908244a9203ea9e726544ef6dcc6e b67a32293808e06725a391d616889dc4a438c8681893c17646896d19411e1cba -639000 a4629de92adb7ee055af0b7a55a0690efde637a84e9c19fd423aa74389c7ca4c 95ccb5ef5e2720ec5ce9635d8eaec7d000b16b3abe24936fb8daea2def31b681 -639500 dffba976bf5db95ba5845ee2863a8f60f855391a80d3a59cff38762f0992b38a 589744adb3b63b274b63d7c83913c65d121c13dbd8399aa7e0f317d4b37b5155 -640000 d5c3942c19dfae03595dbc0683dc712467c00e5307bfd96609c4a728eff4f586 33aee46df3a2c807e3fb8961929402532d1f1061a5e1df2f28335ab40002096c -640500 2efd0a03b8098ebfb96870e4235206b8bb428b5aa568aab56db36e3124c98c04 e67d6fe1642bd591df2f838f07190f8477622358706dce1a631819c828dc4980 -641000 91beaca7dba7afc17cc193cabc2fa7c34be665d2d367c9f0d17a8385903c5299 b90b505393575a5869ad32b498b2fe7ae026db5e3be2ae066ee4c8a4e50ccd0d -641500 52a2ed25b8afbf07e9bcbee8bab225af6bb0834b500ec30114697924951b9db4 0d30d77943438dfd2b1d85adbfe26de36a3f821303c50717d3a7e55abc59cfd5 -642000 24cc44ed0510958b23b614206b702fab53cb7681905d1aeb12fb532fa850a415 05e56dc42c34c44ae0c67c45985004c753588fe4588a4060444532194840e5a7 -642500 2cacb3c0be5a18667d5972d99182b87eaf485c724ce81cb59f3417691a920977 1d5689874267933eb1b72a5696935202699416f5f064b689e7221d6dd4a2c3c5 -643000 94ce4d9dcf18b532dd9f8a490fe270dab5697c14f49b7326efb3e3f82ddbe7b9 f8466520f91a0a9b5136c8ba589bf7fa7a5ddb292516ea1dcf7820d3ee7c0cbd -643500 e3c751b8fb071c5ef4fd1e7ebc9e902d365b88c3dd5a90ca5386d7cc42813b39 fb799e659716a37ba6e9982fd09e8848d637ef1d85555c61af74dc996e1c6908 -644000 2873489104d5b817e24659b1c91e0b4ed350c388563670846658b452e279a44b bc4bee8a1c8a2b98d32ec490a31632852f7935737bcad951d741e789ef99d15b -644500 2996cff77ae12636ed2da94137e2dbda45f5db09c968e13d9002d9d5e8d1bc8f 1482ea5ca89d761a9b99c8e0a5791d430478b289ecd506b3b1ee803d90be7f94 -645000 db1d293ab843d88849874e33883a8236a8bc4bff1d93b7d9922cf1f7dd3d0803 b13760cc8ccad388e7a35b3fa743b2c07b1e40cd5604c3d4162695d02bf601dc -645500 0c98834ca2fbd0b1f4b7e708c5f9bc9e820370fdc2b1126aa50eca16a46813cf 95b1ca36aee7f85aa247e91eed0bfd17f8ea675c5d9db342d9087017117d73c3 -646000 dea1a9883f1c3af496fd37570580c5c9a1e1ff7e8822d70188737f7aa45df488 ebab9f3327181450b58a388214d86b56c395f2e90be9f7d595ad7ec863e6c1c0 -646500 5cf92252a010e2d62030e5d74d6371e873f7fe6353a010791c21307d8236a3a3 392318738e04bc641e4375f47820bb59664b62c88a0f62a3f1bcc75be023b3d9 -647000 b0a00219234dbf1942eeceb7a31565ed117dd8a8152f1d343277433fb3a19233 8cd4d156025aee385a9cfd46d38594d1c4825f52555a703031c99c005adb1513 -647500 8cff85fb1e3b4a7218a58b6fb2e7d0168fb5a4ce4171bf3f0b7f1e7a5f214d0d 50dd61b46e224a437159c8faa7d18cd9c100d1e3ff75eccd770d8debd7723410 -648000 133d2255f56a3c2737eb94f337c9fac97214a7e1f54e8ca9b4bbfc6e056443cf d10ca77595aabc294483ef2fd07975ec43cd2e0764d0df38786d3ecb5cdb810d -648500 37691423db6098cce3ac61dd2e0ad5202cd08d37e2a810a4b7e259742b50f561 4fc55c6790346c316db4b0f1a35d067052bbaed3932cb8a369f8263791b9e749 -649000 e8f43ecdb6979574c66b478a2d3ad028145349c43ac18f67e089f6948a48812d 7609d55e10c1b40d62adbb39792b58b5c075f1c34c6f8676cbbe39e91a7e504e -649500 18f631309a2acc38dbd4d08322998f0d4fac526eadbb1aa2ef1ccf75173adbdd 83794a76b25f0ee49153d50f9bf6d196d1b78bac25dca55b9d3eece5c8c1c3dd -650000 fffaaa151d0634fdd830e104f884bc05d30160640eefd126e0e01b43bd5db5ef 7ef1c36f637320886b505c0ad5847bf0a345c6abbf4e92432d863b0ff517bb91 -650500 bae09e49248acd64fdbc94cefd831ecb2a957c0d5aed72644a3607a198c77740 f1ca4b8b2e74774fc3d86ff3f2b5e6ea8d59e40a683b993fa638c6770aad547a -651000 5d9f45be4e7d558b3133ab3a7d01a96db73f6a16604f4e348fe04aedab48fc1d 38c0484fb001d8039ac07895bf04765ad79babecb93040f8b45e18629c1fe566 -651500 7e12af704c44d001d842767b49709eba23ffc53c8a20bf96b0cbda7955168521 3e563eb1f016f0b9a83caf023067785be15032588fb1ed9d6dc2e7d47d7df8d9 -652000 6577afda5b1a2535cf30f91faff821b56dc9f969e590d406f644518ae4dff6ab a6aa3534f3f962041d6c88a5c413edb0860aad04ae8068ee31070716e552c03d -652500 f60863237c82f26f35682a510882c8c8b3ddf302e479fd201a5532fe02993d3a 623ee7add095d1a51ccbeacebe34fde662c727a14ec2ce8c856d2da57ebd1537 -653000 6d2f869d3cc7314a06868edf43473c3eb2a4ffc902b6866b2b6d9ed8254aca15 ddd54a91243a02e778e23135881e1a17a5829d6a698410cbc91c9c70047f5463 -653500 32d04fcd783380025ac2f7776d0868e44808c446df33e7790b9eb06edf1a13c2 9dce2c2f0200948be45127d74dfcce50bfe2787f01a1f62cb304cc7644754999 -654000 ad3da7c147ea7020a8854d4768937b46b2e9ddca13d786a2dbcda5fd691aa264 15baaddcb66534aaa738d7370796b82234bd7d1a183081ebd7f452a33254bb3c -654500 b38fc7f77f763e12c55c816230cb83453e513d7ffbc2f71cb18a4b970a30b6dc 8b8acdaea52986089352c0b17b8479def4e4e01d8f797609fce1c737e36f4314 -655000 58642d4240fc44829a1c5fb427e034890ca40c5097aaff77eadcce464be04701 11f24474492b2851fa79a42ff8d8685162e2b4dd1099722f3ce9ec4d5686cbfe -655500 d71e2ed94bdc78741559fb4c58bb944dde0adedc05e7558d7de6ab254c332fbe 7bbb488685c2ca7c84d98149d2383b157d88304c5b34aa7679ac24ad5c85b006 -656000 c1d7426dcfe8733c72b8fae49fbbd127a6e257ccbe4120600f8454287ad26105 2f8f7af5f2ec8a3e0333cfafc069bdfca90b0ad6b99ca970b0f458bafb0dbc3b -656500 c4f911e6a72381235e92a8c58ebf6fc654e35c3f5f4b2851f7f8a9ed3949e047 3d157f3d2c8158bf886bf994e549a6da2db2c092266c7050b831c8888d62b205 -657000 da224ea959041cf5d98fa040a10ddd7a1904725a649ec84f2ca403a8117c7f5b 9b9b9bbc0221a24b8642fadd26c1157ce903d7be532aff91519f431e886f9ebf -657500 61cdb241ff295b25fa6a478eaa78f111e8d7ada328853b0af54bb1b20a2a427a 482b2e9a549491f90026f8e50ca10016dcc78e4c3d2064e9f730b23ca9520a2f -658000 1c4498c323201e26bfb8a8955f29cdeb66cd43d6a2b2befb1da4a6c0647d1c53 931ef1f4868a3c5b54ef4354bfa791c3ffe15c02b3c704a6a281154e2f5be98f -658500 33dce694605303583aeadcaa80db0d8569ff712b588875d48edb395520a43981 6247bcba2c8883551a85e364e30b4104edb0318eee718e0317dc42f2a26c7451 -659000 339aa922137edb48aa37b841e956adee6c9222ae9bec106ed49ce5843b179681 ded7991d424229bf67cbf220dc2a5a5b223b571374f52d14bc9e83df72ea4753 -659500 38dddb9b6e5dad4ec1f95be3a83a156be12c5dd9d5e74a20bedee990b3f511fa 7815a077c5c8a265fd122b282139e3a13ef5951482f6d550a566ad74ec2db369 -660000 5562a936684fa4976fade44cd5eaf6531bcc844027c9ca01e33516c0c87be6e6 0af9d5b94d513c095d2883a381746ff79e47d5179cc95165708ad37dd0615764 -660500 de362a2665571bb51834a5e8cf65cc0b436097d1a640ccb9666fb41ee1694713 b7b39581644d06d7672965e189c645b4396f4d50b223eed99080a122b22c2f1b -661000 7df5c95f34efbe842ac26e4252440f4f315b342bd66e74a3d1bc3c48ca0f3844 0a4f81f5017d079725470dd800ffe7e955bd82df18b6e8abc325165537ead1f7 -661500 dfa40eda9296e76deebe46ab09b9d581445d20814c44c42090766c0015162e53 88b577c05b1a5f27b2aec225732da967a44e30dbb463455bc7ed223bfdc76025 -662000 7cd8f5daa828803f06d2ad8e7899d4993999d0ec37e8a37ec52555d1c64acd8b d0a6e4b8cc44620fbb80e061a949a8fcc371fd1f2a0b05138978d234a99fbc26 -662500 057c9dcdeb7375f51cdedc28740c881bf6ae644ff17c0aeb77ed796e89db8672 c749272ba9509a09bdb7697c6197f132c1de0c58de5130e8c3257288be94da8e -663000 d9ceb13692d03610ff6e97eeb643407840e27d32c389404cd3cdd14733756dcd 05b1659e97dd91ccffdf180d8da3a35f6b2fceb9676091bd997ad363210e2f5b -663500 cfe8d9435ad14423479546bd4d6d1e8dbdcd62a8214ab922402a86838a8fb3f0 cf68cef0e01bc5856468753c4df42bd16f3d33dd68783e012c1b012a3cfddc48 -664000 e18e31c640bf36f6cce981521fd55f42761fda24538dac34285fb02e69c427f2 f237c6c072f16f524d90aae138ec3a9176c2fa8f3049ac9ec009ecbb678e4f77 -664500 2cc31198ec6c3fe6e286f01d98f097e19a5c23d3f478916414e83f201e724e19 1805da29e7f7e8dbb2b5aff1e712b3a447106db48671120732111884e0783b5c -665000 4b332fdeb19f5d2fc8108c233679e861bd40df746262d5412b8a6800f50ec073 b2119ba9b25aa2a5921c7aeba1759395795989824a5d6d204592d0ab6ee8ca12 -665500 3f0705d552dc4294997339d7015a4897e55790353236540c775e330c78cbb34a 9595abcff6a155b8b995057dc725cffc3b283086ca65a6213368073f7f5d2b34 -666000 df535e0c312494f9f1a288cc54b72779ec7ba745bac09f7b952191c5a904c56a a545eb072527dc053c0630dbd820c51a2c3a22510f31a389abf75294dfb34911 -666500 ce6966c65ae25a88bac2a35c95d1943c482febdf7f9c28efb57eacf2dfb9544e 4d6fbf4b0b9c493ac96d63f97dee48afd60c2c847f9aba07110791514b0f4e21 -667000 e7a271b35d3fb008b6938cb618fc6f57032c92aa1e09fc50363cb181ca53e2cd 0f496a3a120f9644e6e3c5d371e6e01de4afc4a85f010306919bbef0aa323942 -667500 783bafc58044919edecb6e3938f0ac69dcc75bfc220bfd8717d419091bd680d2 b22cef79cae030286f2fd4b62c409c6d9a801f65e377d66d455fd814628d5ac0 -668000 beaea7bcbb6c4c3a18e0c9bcf6cee525f9036796157c8b4ce5748819c13c2967 a81cfb88c97c1489d9193801faacea720e98d21981856d121ffd5e75f7ab393b -668500 393c647b49312eece8839452c0874a2e82aff7169a3a7e1e5326b1993a5d1af8 212bf73b67feff4a971dde4a00c12b32fe82859167687a3cfeeb03a93ccdc14e -669000 f24c2d105f11f385c356455d460f8b74d466885118dc0e1ece8bddf624cd5246 d91bbe1649788ea71e0574f15865868289b28651ab7e28455d823a515492ce0a -669500 3dcf0b942af949fb37bdc61645d89efd6f72b13c02fac02a96ccf1375cf3cc21 81fdc3a3d66e72026b4bc01320881275584a05be5b0a5f8edbb2a6f334126024 -670000 e6d5cc2dd441d4b9f08b05a582c291a01927bd1a945f1a43557e3bc70cac59be c82d3be4f90e23836110348e66a9224cfe135ca4408363489f3296dcb8c33f2b -670500 c420986426267474054b56073135491ad4381376c64dbba0c57deab84ef61846 b0c138c7e5b8bf286b3f5b6ad0a83fafa7ba68d499fea78553241e741a05d183 -671000 d21e66d96e08adbb61bbdb75a7e8971ca9bd45a4906f3ce23dbd84c2e5e8d161 ba60c1936b7c35369e31e9fb6be2739cf60fc4685d210a209c4fbcf341d5c9f8 -671500 f7bb538d49e99ee06136105edfbd282e2f370d3f4f4c6d2f20b75938aca43040 9c1b787f1413f483e72003c0ca97831ef1e616b86fc3165423cc84e878d487b0 -672000 8c85db8531cb0e6bde769d488b6c6a639f4839a819abe23ccf88f3756caa6089 598752609771c022cecd036a0b8aab8caf8fa3e64724dc20815a827b750daaa1 -672500 efd3aacdf98aa1fc4fea20a2f4cdd9ea3eba6dbe03a63a149610d842793bc85e 93df0fed7bd2dfd8ca6293601d799ea9a54af7b0d45997c821e4a8a7ab7d1f9d -673000 3109a32670b3c1a796f9c6cdf5f3744848e8ac3ef0ee2ea891fac0eb69223ae2 baa8971d22821acd1fee4649f702edc70cf1b072517f4b69d6bf4060cefa34cc -673500 8064bdf0c36a535d5d7788f901ac0713b627e2f8b80c4b20d26cee0daf02ee6c 5548c9d616e98ed4fcccb300d3e35a78d66e61aa95c6465fc66a98c1e40405c2 -674000 b409ec86b27b1a828acc7f056dcece326a7892314cc5b0d6682d21c06d4e4cc5 a25e0ee6404f9db371913c15348e3aa8a9ad4b3cd99cca3fbf1e8f95b6e152dd -674500 0c8142e02a8e0cc1667a81f4c4d08ab7577102481f73d31b9d8c67589874e970 e615eda6aec462572a43acadcbde8bccd88e07fd0029bd953e04d7022dfeb355 -675000 f200a64f03ed78fdfb3a35be9133cc144cb7621be76f0a470a6cc451d31de7d6 2dec2d8e6cbe5d122786b9c571751d54ba1d597e23dd4aa03ebc50212c68cf8b -675500 44927533602536ec6857a62ddd2e7ca31a05c733cd0699a078c5106620da51f3 989564e602ccbd682fcf993e4ca7691f049bb6adcb099860f9577a83cbe436bf -676000 1349301af96fd291f3f6cac4d6a6a94779a2015ee9d63989d79c813e7bf3ec81 c196991fb4a511513fcdd4300dad73d556daf8eaaea1411a5c4b0d0382e96d45 -676500 7a7071dae50a8ee6f25b289f3e9d15d53661469e5379b56278f391381f2b5ce3 918295a1444f694e137f7f9653f87f1863884241462386fffd0037927c3779c1 -677000 a816938aabe21e8efc9c41ccbe0e7de2188e0bdb3635541e05b9cc8e61ed3dec d59c6134dc9539b3cc6aaff9870b30ba12676fadafe95167bf90bda3f074bdde -677500 d06ed31f2f1a7dee027e76fd419c93a2c80824f31e5b0bf09e85e10362cdfa8e 30baa2fa7e5834e442e8445c81d124018eec1ecaaeea695d4278263ae60ef134 -678000 356bc1b553016f0a17399fc531e9d5a86bb273ef944843e8aca16d16480f1e1c 74c26fdb3397f25f794bb15595b8807b7d4a4500ddc941e7461bb106a69daa62 -678500 e7f83fbb9fef902caa5ad499746100c3422842f793424bb2b17f9431b0a3b6ce 5177927957f3b258bec01be88d817c262ee5a64cee44e04b6d78b5f227e44442 -679000 1ced7af5a996a7028c63fe45238dda8c540295b48d082cc278614f68dae0e249 cbc8a6d5c9ec62bd0d50ddb90e7e1efc4b62dfef8d7aede6279ad95186497f7c -679500 a00fef7924aae620536c387899d8628d4eac6fb45bb1954447e2de6a4fdb2ab9 69b47a27d041a54b0be2406df7be07f3fbecfafc0d58407a7946bbfb0f65cec9 -680000 76831117aae716df313e1e7af8c4c8076e2b7d37bd7239c827962cf903afdb55 0ba660526d75f5b1765967a87119f6bb67d33a496e23b13e58335e960610b38e -680500 17835aef913aa41dfe7a49e91fa7bdd85411356233f5cdda375771706b5a4e5a b88eeb3ef96d4ce4adf49b87f88a5c835bdf4ff88aa3a45bc46d2970a14533fd -681000 86ca3bca8de152e4ddd4ac3171ed463466dc040afc5e2f38eafb7fd0ce49dbdf 55a9a5b5ed90ef00ce658b5fe52373ec23b37e7ae1c477decf0e8a41326cad7f -681500 5b31112aa2d9b190844d109c44f8a4845bcb0f75e567055bc1368bfbae9bd427 9b695ac5b41310d05f09d0e5265f53b4ff475b10d2b0e27928d81543857a1f0b -682000 0f036f94ee9dccdbb0ccfd4dc10663890af3c2b7da67321baf4919f8da0ef388 a9d70e8df288e875c0361d7273ff846b54dbdae0d6d6459831e71ea4a41397fa -682500 18658069c688414684b22ffe62a7e4d9b84b3f27c28351b57c8c5763aee40ac8 c4ec9845b905ddf71c374d400faeaa649ba8b08751f0a5c6b9780d4c7d497fee -683000 ab2a4002ccfc546d80417f9c1c66dca34d8de7df714fbcd4eee134659c6b4261 5bccf1dbe0d677d06768a02a5bb6fadf5deb0075582a97e4524e2128a4fa4363 -683500 5b302ac27ba940456860fa752bdeb27a3c8494c1fec08578c6d204588ae18420 ae3de94a6481c28aca678f115b73c830ecbd163fd2e11a9d85b2c3132911c3cd -684000 15fc8d38546017ea2ae0e0b4387d74bf702a396b52cccfa879bec7c415a164b0 9a6e35b63f814b6837bf67d897103f320a25e5cb15dee8e5524d9961f53368d8 -684500 e40472171e3915e9518f1646a3ca09a46154b226443848605a4d8c78803c90d3 2c7e33f27973f6345dac95862d63006b4b1506d5979f60d8c52fec12b74a1b78 -685000 742e161c4d772ed9ab9b2aa95ab7dd4646e7fa71a7b71d0062120791fff3d538 7854ab499956e6893c2679a3393fb30e450f2cda76cfbf08bb3e77b586b10599 -685500 697224d799e123de9da2b93aaf6a3f00ddd507080eca2357c7cde1ed1ae8f189 1b02e1bbb85f1e71e1a1bd1e58e4eca588997cddc1f545ee293b17267fe5fa50 -686000 7a7fffd9aa90d0d9e7309ccc0e450c7544dde058085bf4bfc9efde0cf8fc7b3c fd10b3c2c0539bc586cda1dbdc454a1597f4acbfc1d9e7e7b472e2d3547c76a3 -686500 3dc10029047449d4411fbefe15a7f25864007511102972f14697dadfb914d5d0 8064a285a9ebb460f864525434c5bfd94ea7c437f67c9eb6268c3f3e4737b798 -687000 2e2c774dfd40cd18616a82d3e5769d4f447a2eb5214bd8783a5084cb8ab38e20 52379664d91e53a60d1b1a4d64ae2005e6549972c45af11ef2ecf2f2faf82ba3 -687500 295e12eaca70c7eaafb7cd25efb6b461f5aca68665832ab9eb652e6fe476d809 43763991b8beebed72f3b7215ee72a2f074daa83a27c8db1decca52bbfca7b15 -688000 88efc791202d8e4a0266dc8114487847252ff2497c022ff4ac237aabc6602406 560346aa44e4afaf2fa9a4e1506534bce8c0e113efe4b19c6aa26804b405bb11 -688500 8bde3d0d7f23d76ffb10e59c43a9a2cd4121c3f5033204c4689fe77b860d616e fbc4d97609351dc9fcc8f4e08b5a0c79624c9e81989b684e219245878ec2fed1 -689000 01a706323f362664abca40cfecb4c6efa65aece3270fb1240e238f1e93ea3ca1 e4672adb018af124ae848405442ca5e255ff9af3909d258bba12d29f3aecfae8 -689500 3d25b5834362be1296b92448e3d2ece79f8017708479f56d7e28d602817c82f8 643b9f9b0a754b768ff504c9941c627627b49aecbe170a72590179536840b843 -690000 0e622f16da74d548cc9e49c20d072a9a8a6bf45dfd793830fd25369adca29bc9 fcc1d77406d58f3e1e5630871011b389449597e41f1df035518c1e25affcdc9c -690500 d96ee19654c250c20011f56dff3850e61b9b01a8c3be009b93c0f53c79d6ad5e d3b6058792062983ed59720fa58ca7cafc890e475e2411a01331a4e3e8ddc580 -691000 0e02a80970060ff139ed4ce0a83bf5221895d80de69da89bccfd720da52793a0 20279d4dcc8aaf7a83a59d70cbfdc4c51e8d034467a956cf012349dc01d875ea -691500 6bbc975ee40102521ac8b041e481797c83174c5f2b5fceaf3090895a6301f42a 4ba322db9723202338d5c0e46427fdcf24c8631f53f3db590489cf5cd74311bf -692000 a36c0ce45bdbfbcd02fe25ec7c199be6e01f6edd8e5095dd745b136e1a1956ed 65fb3e0023b45c838637825b0e95f461b02f90134e875d85ca8f084bd30d3eda -692500 2f8577c57b15cf8c176873a546e1451b379f4e09967643452a37b037b538a0e6 b15ca73e362e6394166b6e104ac474d1f73d4fe671117a77ad3f9786ee35488d -693000 634e96cae2b7253783b3ba6dc65bbf79ad87782a46f07a11ca8c3b2325e2d2aa 08db37defef7bf06dd75f2d8e4f8d1be0f2004d24e816a71ffa4fee43fb5153d -693500 c472b7da4a1d6e9a9728e58dbabfdea31af58c18a17e79e3dcade6d96efdb689 021ef6717375d52d4e02c36bd8757c6c73b77c97bf3bb4d6292cec23afc3c8ec -694000 8d5000ca461da1bf1687fc3ee92e3a1b414a92737d82e301895d6cf41e0e4cf9 e2e6ad6d2a58ee8538e7dd8136587a612c39ac281fc3e6bf609b1c497d9e331e -694500 daf014e18bd15e7a19ac859acd668aa28bae8fac71079e0b8285c25fd28a46d4 9a671a25ba774c600b2f967a1632561ab4ebbfc4b4016979aa9288af8be93065 -695000 f0d64ffc15600b2a53e5b9f09f1a0f981273e1cff39f01bb69a3c27fbe679c71 d5adc8baacd5fc0635fe0ac739a16893fe0c4215655ba111f49e3c709f0d1faa -695500 d784ac30db59c0e5e8906f2211b6405356158cf57af758b047445926e8dc140d 7d0c9248ce3387940358e82c01b7accebe7d3445fe97f6569b0a99a1a4822b61 -696000 16e6034f4089c38e9eb2a11669e4d5b896b4e36e767626bb4c2cb852031099ae 5f54a918561ebc4c21c27b793cee698c347e8dbfa49ce72f4580ad7d3e464a91 -696500 bde4528da57c22025db1123e7fdf3e58f020015b1b500be5d2ea13be8f4f50fd 954600e88d55d507e82333a0b9b36f5bfd5da128e5dfe721ea486a117f196e51 -697000 eea7b9418887e6bfe3a460b03f30f800672d8df94217fab7d1e7a74f437ebd50 a210a2e4efac6617e3df43fd4219eee8e4a9dbf05e4cf103cdc9f39e162d61dd -697500 af96502823fad0e9693d94bc707b04d59d3f42fb27a12134f1aa0a863ca616cd 8cc57e73164f446606d37223429ba5a37d92d1ab52265fef43c81d8f5d9756ff -698000 8a0878bcd828268633df687a5405b2b86051640a122f616231d8d6146d4c2ab2 27a9f143cdcb85bc01f31868f92a964337c451cd1a546f93c29361f245aff07c -698500 afbb603de0da6476915e14cf182c6c785ec6514b17d9ba7bfa74e5a228f6d8e6 f730e6ed2ef1334071ce63f9ac851de557383c98b40a72f8bdfb29c49bb7d571 -699000 4e3bcab244d1ec2528890ed24340027a9add680ccac038c42e9a5b4880368a57 1b7062e806e70df560b7dd19713440125dbf814412ff713c5bafc8776c443a60 -699500 69c03ffa655f439caaa38a36031f45c27f6afa345fd8d380064ac4106a47b9d6 9835287f527b8d7075cb42cd361e6048b9defe40cd855bf186641ac16a40cfa2 -700000 19c87f86c5d859f1d4ba642097f626a5c6cc8420f1b438ef0ddfc52d77b5a7ce e7cef1ed642d40f49563c66d9428c699a66241a86d05aba5cb6fc6d6218317a6 -700500 c22be0aa764d1e0d90432e726ecb95a769d691a7de81ea480c1bb9e74f43bd8b b0c38cfcda8312393e4906e1068c7a323defc33624e99c8c8f918771010a417f -701000 b2505b0ce33e22fc06044bc95bcf1bcea363d91c541451ba7ebbb07079c9b8e6 36066185fdc8a919096d36245786b921b24ea4b9ad0949d3685c7d54fd3faeed -701500 11c69ac149f239f122c309f5c7c8c08ae9ed95e563e6e5ebc0db4d49628972d2 52282de896ddb2f1cc56c22ec74637395d1c2ff49508e903cf4ef1f5c01a1da1 -702000 73e7769b7982c2e9be15c6d3b0156680f7705c802452205d64a5d66187de5008 623290f47a7ec8b202b95f45d5c6408072766e49439c1aed29f023bd79a8e1d0 -702500 cd7f69f08cba82026873f72e8709cffc89a4bfe3c5300231a180fe4e7335e87a 4f1bd226f6b1bc4313e7618f03e4522da41509937f596a3728da2310deecf49c -703000 6253ae1e6bcfdba8257a18760dbd8f42bdfedce3257b9cff76660667e29e5e20 05134bea7f58be79fbc3942bff929fef977a42b5bce28e787bdf2bbc1bc70764 -703500 affc08445fc42e60d11152790408c66118b2a815647640a3eabc3006e0f58f8f 34c74888ee86d1759127612373b099f56c53bdba1b0fbabb0a7ec61eb0f24ef7 -704000 5298b2ba05735ba586e9f6aeaad350fe88b762d00c4551d6b02f6c0b706b0f34 9a36354d1266eb50f84338359401e91aad336d97cbfc39d574a83fbb4aa11d67 -704500 f674bfadd8d412cffe1c8d6fedeb91e9c8914c3280414896f97e1c08e05b53b5 6e593d4f49588dc6a68b5adbf870674cd17037cf7431f34253eb6cde06364421 -705000 d288536328fe3b3301de1ba97c0237dcd740f225f4df07e923bb570f68716604 b918a47fe346fbb9958ebff0e557b9febde26c435ff6320858bdeaa09ed0eb60 -705500 bffd8b226418632ef3a9f71f473093e5592f446776db14fec222f85de068c840 e889bcd01a761d5208221642a51bb1d0afb1f324f74914590242204164287740 -706000 2547d907a333fdebec0140593814d90a1d806ee539598cf0672cc30a1d5c31d6 77323ead475140b2224eb35de6da439d3832a091f1ca17e53a885d0b4d469105 -706500 5625e44c5204f1d9d3cb4b5b55aaa18f13be66ec9f76988159a172713f141fa2 31a50d4821509dd711e9a541a3c54e28aad4bd6c6314526ba82e64857f52f4aa -707000 e15531acfd422b5932479ecfe5dbec51af4e824298c73658bd43c143958a70b6 e9af02a4dbfa950c0a45fe96162bf991f65df101072db521b4631ba7e64ad248 -707500 904129b3e99e06b3a75bb2b903b65b1176d82601355b13c92dfd2551edeea6e3 4e5bdefe9ac9916fa5ba321a6056ec1bc8fa32ce3370587f13bed12c32976b71 -708000 23cd48d83d0bc7e5b80c8a337389801ef9bd5584097667310342d92beafbabe7 e916d2f42c77692bf97058ded798c541ce883f69786596ad94a22108adc17694 -708500 2f58264be757741e695394b348381a9ae8fd583341791a84d68d338cd811ae39 dafed9faf74c750eedfc2e65491b75d4bae7d13b9e082e6fa91376c2d6034da9 -709000 e55588bd39fc8e754f2b272f80ac86b5515bad37eeeac6fc3dc0d1179fd53423 69815269b65b334aa89cfca70ebf71dce7de046cc84b68f0f9c462da718cc469 -709500 e30d4db49a196e4ae4502c992118f37ddd6da696f296413500ce20b4b9838497 4cdf69b6c9515176894db3bb5ead92d5ea1772d53717224656242e8007552228 -710000 6f141473cc79d5def23f888471ff143ab546b5b1d1d5fd1fe51c996674e3018d 5af180a3caf0ca42e0ba20e959495120693f273201de65aec15993cca37cbd2b -710500 10d11c0d1dc7316a7bc8a99b685c0b12c9e2bbec941d3c33781059c7048ab022 541f760b8b3ed77398d5b5193220799c84f36e5cf342256921661f6d6fee0316 -711000 dd068ba9611f623d9e761f5e6a10b0298130c8b25317f047b6a4e79a3360909e 920987e93062ef5eebcfeb0a98ff5b108649f1a092f76cad1c7d09b276469f80 -711500 96778f4ce3094a1c3323e3afd658b20cff90b2aa7f23d886a5f5629704f5726d 9f4d8c3657fbcdf2375c92f6f7e700f8f108a1a5df22468685782c897b15865a -712000 f4414c743e2b4f89177f92e0e11d61e9f3b1669d3ddd6148b3915862dd2b87b0 df705fe65a056478cc8c914ead67c0a9b6023fcecb68dc7d9ec56a8c6ea1b865 -712500 fba950fc02bb67da1c4de9b6805b7bcfc0cf7e2bfff478568be99a70596267ac dc357d74f8f524808f3f41d6604d74a8a96c6bb87f695a15ad835abcc6669be0 -713000 ff4dd851417240d00e594ee5fb5408372e4fd5585bb5ebf3d73a97dce1f4c41f b54673e8a2bd6d75e2218fecd8d20c0bff1b231b80fedc53b3f1deefc7fe4747 -713500 92e49d6caa2cdfde8ec7d8c37ae12d995b9552c76f7c7ba0abacb77b02bdb5c8 4c7b0f7d4f28c7c4d35a29c0a74310b38789decd628308c72a5a270a66ae55ba -714000 dc8dfa5b910afe73d3558be9d077fa57f1b6ac42e058227cd73b1b1cc0c70231 9ccbffeff96630cd9248b3001d7ec7ccc83c9daa5351bafbdefd8a88c03f3224 -714500 e172274b228f5e4f49167f7d36076f71db89acf666b9e519da3a33c548515826 14e35bb2ffc296d0d1f30be89e8a66f0bc7ade63250bd68043acf98dc625c91e -715000 a9b83db90d65b2e1db885b5b708f1d7203019a7073ca3e5310ed4dfe19bb9d61 1e2fea7d862a4b98f558f07e35d23b1d229dcbe2047a58f7bcec840147dae863 -715500 969fa24302ef22b2bea25b3f981fbb756f3de84f841d6f73ad9d6a6bbf463fc0 31872cd93e38c92acd7b1af2ca83b7ddbc9319dd8606725fe0aa2b50026d98aa -716000 e33babb3b3269852ab03a5044a595312e1828dc11169020fa2a05f4ab329ac15 129a208db82ccf3418d94c00f39f3eb81bb7ebbe901f2a698362be4fa1f6e7cc -716500 9c0cd626f57ca90c771b00015658c387466c2f3d462d36d9fd3622abec903b1b 044c3a4459440fa9078eb26f15d114c6ef9d63bc5b8640f84289a1f376b4b85c -717000 77a31d517bfcc769f64d0de88617d62d4d433c1d1a3136962eb07baa5f227a86 e1f060643884a9ede876b52b38690ccca9c9d94140470024d2f825f4307dc918 -717500 546d0c517b9b0c5910d4d7337c366d76c7d99be4b875f673cf3876ca5458cddb 814a3c25d78419214f5645a68ca361b0199b58ba3fd3109817b585cde74503d1 -718000 7e44714aea5af5ac9195904d29c9d53d03fca15e00e0f2c1a071611b6fd03011 38d5d155e5a9992a6e9c1423f0ee621f19173c533e6954a46258e02982b89a02 -718500 dabb2702316c8e8043539190a1581ecb881dfdb7502a517fa183815a012eb344 268c57e30e191d41a2793ad6b70796829bfe2726aacb3864283e82e384eea0df -719000 9db785b29f04f274688856f0858c7c63961a6aec5788a94bc1aeaf483dcbbfa7 8addd23f1cf6b051fc6bcd5558893366fa7a54ed89deba74d79f7a307c5224bc -719500 4615a7726a6b3b00fe5a9cc53fc916af6402871508fdc9b9f6e5799083edf0db 3d3702be96cdabe826e24dd724ecfc426024a693c161889d0b41275cd6130d19 -720000 6b70419e1023a8dd272910d32c30aa0617bef67234063aa6e7447aae5356fe34 55f7d559d3733e4d3d6b5c3c68265e088eeb6d2892671e88e9567f238268925c -720500 473da49304fdf70d4b5adadf6fcab3f0c332ab5ffe82972dffac6b14aa20f23c 3de3c3ceb92f8a7f45fc19ccf72f79f2fb8d3bc61654c534f81df978e905a3a5 -721000 c293a009462b561ea37ba8614559acaa63cb6291673c68082a6e4691ab0eea86 ea34bdfab3e2a7087605df85d858866b54b4ab1acd86619e99f6283a99f7ad67 -721500 a15ef2603cf7a7b0ebec81fe4abbc6035183755a08fa11604e40c95477d61812 6aeba98a3c5083b997eca56cd003e7f0285963bcb8502f73f2994dc04492c35d -722000 39271600011dc5e938c1308fc8f467fa44145f8bbc5335f24719d125dc92f664 bb0387e362d72388584708287f86c92ae50f7ba4330c9857b308837d150906fa -722500 d7f846f9e439702e48044fe02c689990aa0a56613fced844d989816e0317be80 f9308f9c0bb63c44b443473a8a25777e34d9a0e903edcd33598b270f0d7e9036 -723000 6fafd8c865b3d0bb05f18cac70fb93007cff223789fb46958b55a205ffbbc959 cdc9d13b0b9a5fa827d2572e9c3232f498e8b06ed8627199c61db9525469fcdf -723500 6ed55084a271a39809b6f3455a08d082fb7c56ad97427307ec207135c7c16ef3 cd4a3d7e1dc9e293cecbcf14b969480c0c2f277819e9eb2286d1761df7320694 -724000 c1b649d3101d61bfe8b949f443e1035a3d5944310f83e94785592c4cc91552c7 452655726058f019fcf400a89e464688ba4bd0fcf267493e54748b146c7dbe1a -724500 21f5f4bc2fbfbfff183a3eaa110c1e3f826eae2f58d32242919026a8d1ea6206 d15908ddef7626667600c5eedca9119d82e0da5f4cf56bf6616edce895b38d9f -725000 5db006a94bfe731764372f332c2b23f9863f7741c0aacc4d92769f353cb4a4d3 db57165deffffe98c3cfe7b95e119d0253a6e984d11fc2b1894ba4bb3010301b -725500 f313538888a7b2cbf72adfff7c6aac1583c44b477c27810920835e1f36104ec8 c811a4d09b2afb0e9e70bc9416e58aa2c3dfa4955ec4ecf03b3db9b65450e858 -726000 f9f289b08641492431e4ff87acb944092bb1fd4ae405569e0f3f14e433aecc79 5c10e47957ac47afc2bd4fc6daa0c7e30f127f0ebdeb1b52149756d9f996eb76 -726500 769de3f5c47b72bb76aabcd88f8c84595015f6f3f8d78b4d4a0df2be171faf31 12f1f3f363f1cfe762d972b988ba7e0943520065bcafadfeda1cd73aad8c2aec -727000 2d757e0b21cd7f64dc962c5ef6a7268d0e0223814f74e6fff9c81f849e496ded 3ef2c4f48504f065f4efc06814674b635ff6d31e9b667f9b1ad864819804f446 -727500 5b2875cc1b107110464a44d7d9a1835e8c19246cc4d646402fd3bfacd53b7201 48695a64b57a8523e285989dc5bca5360df44847a66d926c154c6929e92608a3 -728000 35fb3c9e4fb0a40ebced7b7d2e9bae928790bac78a8460c311b99e70cb109c9b 758fc72831974d7f37e9307b34f80de04f3ceebebfc97c79eae5e1dabcf2374d -728500 156a06f3bbea42cebe61c148aa7ac4cdfebf95edde5d021c03a90ddaabffd20d 6b170063e91dfa3d05c9d6edf71577d85a9e3f0ef734b7376f757d1bd5a42705 -729000 e8771ec45982e5e9928539d0f4f398b3a35f02b92f44ff6937e6a6a50fdf4100 bba9a535cc36db2ca8af73b8707635e3c12b3125b320df91257a944ea3a6af8d -729500 e17e17e50ead400f5dcb3f3ffec5a1ff95da211a7f6d30f87399cb034b2fed00 0263cf2e76899d4424125c726396ca7c8c3f1830eef290b084bc67aa3dff7ea3 -730000 06ee01124cc2d7e6ef4f764638700ae11ca26a457317564df6e5e7f0d881ba4c f20e5e74a5a07e05fbea7bdbc73ad393bc83a144a7e15d03a096f052d7065eff -730500 2692d795f114318940b89b8aba8a910b6360170048ac824590c5d814f8b01973 9aad48ed4e603ebd7c79c8535c24ec7d2ddf7db6eed92b9d1e83846e9e139a1e -731000 e167080479d38ecc4cbcd16e4fae05c1f87e09d33e4947b6a9813ca63e147d5d ae82cde68df2aab3ef79112d4080a285b806bed3e457aa4215c6ee35a6d73e33 -731500 d8c7e6903152f5f559f108449eead76f647a5c9991f2815eef0d0058c25b6bb0 f786151a72adafd6930fe59a04cad481a49770c191a3f5444eb9b4d49b000779 -732000 7371a17e1393bde477a0beb136f98e89dd30f49ebb28cf59a265dea0f82deb70 67d98bd80facaa69bcac4ddff46661d1dced445c622bc90bbdbe1e7de9a8f768 -732500 921701199569749e2d13f7940e6347ded7a3f1dfee26b7f7bb744d5d3db586dc 41fd3e2f31c4d732326d13c5f31cd850e864c43f1f179d8631ec1aa69c506d88 -733000 d452ca29f9949b714f175c7ca45841a6519857541c44df4e52caa73b4c9b347a 616e3b11378287c338d03dc5e2395c5500915fff6340d6fb48c0123e33f92d51 -733500 4ecb0e1b2273ed4df5bb7db47988c3271e81cb9933d7cf50120e9730db47c82a 6dbe9a6615825d26d58bc5a2c068e9068dc5b4a1402dda75c43ad3810cc55a80 -734000 6ef7723b332f6d1a4791f14a1cf2811870cbb08c2484ece5cededa3f69fb920e de8e532d9596a92249adbea9833ff2022f96bdd3f82b7c734fc3580b4b3cc946 -734500 01d19d29a83d79e38c274b76943e9d5769932a6a7812e3f297620a40a0bc922c ff43eec3f821cef199133f7c5282c9892c1b1546a77f6fac3e9021037481fdb0 -735000 544a5f6ce7a71e13db7335cd2a4e02fb7b5ff98253016f9d7f26956dec908470 662695548e437e31e7687cd4aa3a463d2dbd1b0579df23c6f5daa7e9b3788e66 -735500 997d9b45e87e6f1f1b76c7c212527bef213f348c51d806200bf6541da07b76d1 68e5ed2790eb489379491eeb583227ffaa09afd5b62b9073117e540505058b8d -736000 b371ea1a60567133d86757ae1b12faa8832166726b9c2eb67a643e6878b0f64c f5308b0f2fe00d7b1e1bde602e6028ba5f2ce8849da22ecf2cc07edb069a540a -736500 ce6bfc2ae42b6e0893e4abf6edeab04ee36cae259415004f71811cac250e2abf cf5273f67e35b1bea345758b059f5b4b05ad705469c64e85cd90f392f03db171 -737000 79e359fb34759ed805e4ba17b22b3f64f4e05bff59b0929d5a996038e3e2684a 06fd8eed2bedf16f590dbe5210c4657f8f14142fbd12b823b4972a4062c46476 -737500 3d69d33e4b40ef18a677394e025c74f1ff03807f1cc1a9924301da4af97d40b9 8d5cdd08a8a4db368da7ab6be4a68085fc9b2a156fc5e89b69ed661267bd9d05 -738000 de67c044daf5e82856c70c57c05e0963d2767f721c9a2a3095052d271ff77a21 3f6cace03de90c0a7093e549aaa5862b4d0d4304d20e548c1b77a7022a39722d -738500 9857746dacb79d61819a9a7bed47d4f3f8a8ef2f0a4241e4a26e84eecc388178 b324b1e1ec98f23aad98bd643e12396cb0e6db5b6679f5f197b8c82a74912869 -739000 e760e2ba3fbf67764d9ebb7a9b5684b71d079174bbabdf7de315b7814e6a6d74 74cb6e148688d11254c235898692018c699071730431d7e9f7438c6859e1b140 -739500 f066444b8192b7bb857f79443308595802f67e277d85efca22432c5dd095ca02 91fdef383bf939a8e230f32a00ad0c58452c3bb0847a257a136297dcfd476a6e -740000 8d11e7b07aad1f84d0976806645f5d508acb6aa563e1905bdbfd49f88a83f561 d1fa7be0afdec09bdc631fb8d5a35bdf26f47b479aeee287cee3557ddcc412e2 -740500 54b44786a4b53f25a1ff7dcbe85ba288f6108cafb0abaf193c6fa9fd1bbec690 511fae7de79f3e6aed0645375673168bba00a2d39563ea2596e09e3a0e609840 -741000 6e98421219a255828fe8067f68097ce9d08c9f33886b8a29a22d2ebe6ba1f3e0 ad33286ebbf08385412b7a732c551354dead015e466163e74e7fb5f94f6b1cda -741500 81eb9f3b0f352e0ed1c5935647d526ac71e0b775d8715732e262f50ab6a55963 fa8c84206d369ea634fb6668aff771d4c9d3ca7e687a6f2aabf1b2c80563b955 -742000 540e29303471cd64e05ae80fbd19847c61476ca202848595583e1432e45b6a12 01c47d0edde8e38dbef982a21b7b95e6049dfd3ecdb75763b3ade1cb8b804ac5 -742500 6bdd578f687b5b04d2492b7bebe989d618b7d55802b977c9f1362c022d37b5e0 abaccce8aa24b8424fe18df7490c67e36999e1f44dbcc68ad557c59717da560f -743000 1a56cced54e09d3e03f267054909c5800b30e571a81e21cb8e1960c32fb615ce fceaa34349bdb34a4bd0125a9d5a0d73ac8eabd0da333a665f71613075268854 -743500 2b102f1ce482314a2ffc09c26320f241ed197ef0ad1b0b1b05884d95e98b4832 0d514c31a22d865f9480fb408373139aeb312d750df0441dbba91f6dd74b7c34 -744000 9eb6d3d3bb45887dccff04f8555b7b6ee5c16af80cfc8fd132f2f5d64ef32d85 18c336ab05bde704336b82417e0f8a33d6d70df4bcf3fd3277dbdbac7d285313 -744500 2c894cc985ba39b9d41d6cdffd9225d1137285bb2a9faa355fc04e1c3a503783 fafb7464d1745969dd5edbe08aa6400acd05dcfaaf6d09a135b206eadb2d7a5b -745000 0d3d86df05886717a850b573d540f01159dc4aeb9715260e19da107d8a5768d3 273a426515f6fbbc4d1f505ac48c2be61e47dfddeef2e0725d1d287da3706876 -745500 b614d96445616a551d2ef219bec80a8b104035ae75230819c08c1bb5d40d3eb3 e8a90e0d452a4db19b7703651fd04988b45763240ec6e769e681cff12a9713c4 -746000 32fd2569cffbaa373077a1d958628f5bb59edb4f1123ea22d827e59b58e6128d f0023c390d625e1286ba9aecfc80f28d96109289f7c438379a75c7b08c915f24 -746500 51f9b04af9044618552cc030e88269c4c8b6f6285653003ea31fa0596b3be8ca 21e1a38a259322e17a4fcfc9d45cbfb75c345d2475f7081373a9e8b791e3d906 -747000 ea7dec43ccd90255b703203200c0b71d3aa7332a2bb43549c5b713bb03b77f9c 9cf126abdc8e883dd428ae846e7fa5d694e87f40d1de07f772f916de45db3de2 -747500 1b651b29875be11fbb4fa8ed4c857b030122b7facdc75ec31ddaed88e3623566 66c676aae65eae30d876db4035a19e8e00bdf9a9331361e72f57af17a3da4dcc -748000 55f61b3e6a5434428b1a062ee86523b68f5459e7615c29d83f01eee310ec66bb 4927588d5f0600d0a418298312581aab6d41144ee3bb87a6875d7b11c676704d -748500 cc910d9ef1a087c0c9aadfb77da9051aed5124b7d072b976f4d34dc74f842f14 f1b10cb29bf15f5280b2506a480c07a610de4dd63212ac5fb1a33894c2fc0353 -749000 70c48f09a23f35a244e22e7d43f245a20d1d171bd3958ffe261363536f92a087 5cf7c04ef74572576b5debed4c20f3446db017a0360142b325a330909c904b09 -749500 33d54681aff8149655455f3331792f7a4582c0f0a436b9d3ec0fced7a525ecb6 382f51b24f05dcc78ee7b0e02e1389d1247a30489fbc317e6588238d78cbe478 -750000 8e0b562cbf9f5d9e0539f9964745265261cce019e73e22cd0db86f0dc7049110 03a1b08260d16527973210066d867267be1f3d4692f3bc680afadd2b1653f995 -750500 a85d11029aa82c4dfcad63d3e6e32c4525f9d192fe8ed223ab9f05a3fc4a5d11 1e1aaa3b0c05e04b991026c5a9b6a56228b007a6f936902f7a80f1b8f48eacf7 -751000 bc48dc5090db1a9a8016b89fcef45999f9d6c87c8982dc4ed52e4b583ac2f7bf 94ffd27371d8ad63511d87f728731b0513ca8d8b948d8b777d852ea9aab4804e -751500 c45fd98831ad0acd126e9fc658da6851a2a14a1cb037ffa596da1f2da2fc47cb 82be3962eb66aa5c0fbbababddc65c99ac5c70b372b32aff94aa47392ce6b802 -752000 373e8654d6a04c16dc7ef938fa6db6abc8672283a0f027cc34eecb1ec872ab7d bc163b7e20ee438640c02e74d48ecd1f65a4bd4b16d21248663a48e63eb02616 -752500 5f217d14da39d80fabcaa06ee56ddb41ee0dfef892576c2e100793f03818145d 91a33cc31ca938ce0b222ee141bb4edc500263a0689d0aed50660f8e4581a960 -753000 3e4aa8b1ce5cd84238df7ad4558f411a41a674ebee9fbe087bb41e880936a7c5 7b8530bc78bb832d51460962af3cca2f534cfdc28760d7f5363534e68a72ec9b -753500 23a5236d81db31cd3e174f58fc2f9c1263365c35dcde4a20f315cdb01fc29d65 042dfcbd5f30011ff7476e398e4c4b90f890a9fa4eac0da6b809410c3a9cbba2 -754000 5b4879ebfac928244d38117df31bb10c9d7c9e8e8d2a35c5c2f8a230b4593434 c57c3095308f688759285e35312da7e6da208cba0f9db64180d551affaf107ab -754500 96cc5bb1028f5ad1cd8a33800d9832d85700d037d5746d6cb4e58c1eadc8b119 df2a0abff85d391ea42eda8fb0a1d7a750eefe9d5fe25efa10a9f46fb6110f8b -755000 e7129e48fecdac55aa3944a4bbd19eb16f0d8a73cfadd44a79d641aaa46dfbde 385cb4dea3040a9b4d475877dd9d3cb61e23091f492fc5ad741a5cad2268c6a8 -755500 93174ce679911cf73dee7fb12bc26b02889deb145dbc92d69637a85407812272 5f000b1a76187f1c309f9495dbdabd5001f69bee3f9498316d0277383d861388 -756000 d2cad51c4c7f604a86bd42e5fa0855488394561fd8b8e403c968676dcecf2f9a d24b9c50230b5c1aac5e5937e488ef65f19cc11fd4cb6b97497cea46061d7e44 -756500 2e24a5dff5e90a2bddd7343297d9e1cc5f1e8555a19606314e46c09962ead770 dcd2285a17c2b37a17fa6cd27899af70be173d7a3d5c28c7f3ba6cf4d835c716 -757000 d11e6ed1c335b9cbb3db5e79e9ac728fe2377ec42de299a318dcf31ffc545ae5 748036b1271dd158b39d7de65e91a95fc4e51fc0e9eb3445cf7306f15c0974e7 -757500 0b5f20e382095632dec99c72f66fa419e1ce638a80671b8ba91b9a6d24f51e29 d6181cc28a4fd461f6de97bb298ef188941d1765a5bf650e95d418fa8b7fbd4c -758000 5a2a205c4c51fd035a4f57e79f2d92ca5e3c9af3c8c2beba21a442fb02b2c705 e019ca24e6b67025cf564537c25fc2e6e241b44730988c316eb32aa8afbb6804 -758500 e33c965b4ebb8b924a1fb73c65017199c806b762d4441854b79661f4de03b427 313706df2d3cde7074b2f6849c1f134ede50bb46a297da3884d21a1828ce8072 -759000 31928e69c1bdd6c727eda5662bce3f72e36496d538d9fc1cff1424bfcc24d0b8 98b76d0e9682ac933b75419da77ebdf7ba10f016d35d26638915a5ba5be4db94 -759500 2d322b637e8d92f51372101bf714ba726396d413b0a8e9ba573018ee1023b0c1 caea6763d02b49152bce73655908d1bf489b2918b8514982a2fbfcb1099011e9 -760000 1cd9bc900f95c2e15a802f7eceb33ff51dd12a71718cb4220e466bfaa0f5ffaa 0243b603adce50f296920262a13469d2ac1d0c42c2ecd633feaabea80a4c6100 -760500 4de4cae653ec7611cf7079c4deecd470afc39ac6a083a7b5ebfacd9d789c4394 d3a390c8ac0a632c7565327db3e9a4fcc30aacc43e2ba57377a1477235124baf -761000 6aee8513d50a19fdaf21e0ad49ffd92cea289ed0fae844cb3afa16ad3e60b934 045c6ba4c62d4ae995dced0633d85b8e120542be2533abd9fd1fc8c651f47563 -761500 b1917f5b3a3f1acd43c09e2d975abdf63f4a2c6d0b8ab429b47f467020e5b31f c7f69fc7d9f169a97f9ce25956c25668cb780205eb59dbee76f592718d74503c -762000 5f11eb707b887cdd88dfd5f98203a949824d1fe960c4c85525995a377a39a79d 6a3963332b853b978afeaf71fdf868b0d36ab203773c958a5fe5a427013ad02d -762500 8c3d3c496b6ab6a1e56cd5fceb131d8a9dd8c4fdc938d15e6ed090dab25889c2 e6eb9f858bb451d57926036c80c3c7ac4617b7897b19f67e2cb1952ecab6a24b -763000 6fcef4afba243507e7d54aeeeba6cc7de011b43df9d90f364794e3c59621b980 47461602514b2ae53177fa064e5abfc46da728227988a9388120901fb2dc9a94 -763500 41ed18026f39928e570601d40419b18758312017a7c9568d73d12d4b828a121f c04c199a5b9d12441ed489dcdff90453791925fa29ab6eb6c62b0c4d648e28b8 -764000 67e928458125fe2e3c6970092328b48497a4d26c6b04b01e53cac4de70fea64b 9270bc1fbd0aeda1572f2c2ef56dc700086652533d70be2fc6d13e5bde70f8e3 -764500 015f8999e9b59d173970ac6f7b5b6b460879a56fb254c55fc64c79c2f1ceb2af 0fb0da763fc466bcda98bdb2d28195935e5ed9c8d35fdc877160aacf553a4a3e -765000 9e706cdbb0b6dd01e5fed36ab646fc0a80a850e08f2088de2136388d4db8a219 f307dd0ce42f0f743054ed8236b6e8c44e4370634d9382ba439ef593210f14ca -765500 76b996f89bf12e2d725e1df6b6e1f9fb71a0e4741add4657f8233fa6b1a9cc0d 1c1d390e6e339f40129dd63bf89b9dd34574b6c0e16739449ed1936b023f73a3 -766000 46b8674f0faf71bdc7bf0a656e0e02660d90388ec7c3df894b0b3562d8541ba3 ed993dfee8eda538ad156e46f49e73c96e6abeb40c4e2ce1b34751bcdf4e7bbd -766500 719246e48b8d681ea5869953004219e8e9ad1ae095d9f7005b39316010542a79 7d760e07389497315c4c3b10c43d939fa4e1d43dc29fd4e898911ab78a6943c4 -767000 281b1c63ced6e6a9e548f01039e79b341b4c75980548acc70b0c52d71feb8e6d fc8bd623900af0aecc3fdec5de0a55fc7889c6b3005c4aa8fc3973a221702eaa -767500 d9a20cb9dfca54abe3534dbcf69a04b8f6b43afbe3703e7aebb2bee8cb81f73d 899b241bdd3264be250d3f665e9930a6b2f302e1eb87ef65845be021d856c35f -768000 8360e09883922bda97c55167146f583896798f25e12baf10cbdb39254ab11ba8 fa86336cef4c01ff1afee67169e0f4a3810546750ff4c38cec86e37c27444bb8 -768500 ffb03996ae3de8c5bf73eeb51ca0527f6ebee4b20dd059828efad08e7e6601c2 df22eef90381eb583a9e93e90e0722e0a6210c72da28deed40c27499c7a5ef21 -769000 2103acd9679638073a79876db195d494213d9d6e749faaeaddd6c672cc7e177a cc3a63870c9ff71fe67008397b61d975a8147d03a0d8d35a3565538ed514b4c9 -769500 9336bf1ee4de809e164e98a29bddd7a448333f2e25de891b4ac528d1bd7af785 605f77b3340dd29717f7ba780e9f4ce15fd0fa43f2ed916b9e54cf23aab2863f -770000 6182eaec959caf801de20f3000efc3b9431aa1af594a05d704bf2c53d810fd83 1ff43d1f6b27ee4063f01fd16f49110f0db50d58ee4937c28fef346f0777335b -770500 5405e7303c38724438e124b5e518c9af26a0076596be02cc57348e91a89abb6e a64f6256dfe425b8fb3b98b45dae59bac34213b85fd777b91d08d15a62a25623 -771000 07874de328fb41f73e1aadae9e57705d7679e8e186b8b6a2ac50ed5d1455d1a0 38084368706c2b4c84de621b821faec1466db4cd8334bbb13e4eb6960dda4b5b -771500 caf1cde2dfee0a11872272140e8043b92a33ab604f0b8a8c34d7a7006a11381f eb96afea84eba379a82e30b8366611d133f219dbbc728f99d55419e5494c5b6c -772000 3f8fb7f8de518b519eb102a29f372ffb4627dca2bbe06dc035bf7ebd4e6b733a b6de44e3b4a2a16494b4d6d7e5423e1ca66faf4ec0916a8ac97e4a3a656fde81 -772500 2fe560018de02c9be5e9cb02c0d2abcf8d6efd94390f10d8eb84d9dd3964d53c 631496990ae92715067442cef87711925361593696c1ac62ed053618951f9d76 -773000 53c1e8e472ee4d6bad6411fdc74d9fe4fe2564d0baf1bc5107b9dc4ec6262afe 8d48f77bfb9b49f20dfdb2168f0abb988b8ddcd8e9e62ac35ab0a2968b912986 -773500 2836b1c2239c528ef1ca59823417c6ae51c93040e1a5e3ca11742dd10350d3e6 16f14274772f96d6d2072a33cafd5c8f9cf4bbe37111b3f620e04bfc42392829 -774000 69a397d817d7155b644d650da51d5413ed2c133a3cbe2b54bbab7ae7e5a82914 c50ff677b8441b9a940984cf5ddb46f4b690ffbc9703ced2b163d89b929830b4 -774500 e7569a38cfb85227d2d2189a89c59518b64da01e2fdc89bca8e4759269fad47d 3bc601776ed5afb50fc51058a988d114287afa8fc4ce04c8d09215ad8ee3e9a4 -775000 d62bff072790320b532267e13d16eaa2b6124b12e9dc9704ea8b3472c33a7584 2ccb3c701d5d6730cb7fea0a703c1228f75c58b95dd167e135689d020e686cdc -775500 69206115fd6be6c73b95c85875329472d8550ea98bbcdad27b1fff5f13f1a383 1044c0b51ee23082e8268ea9f57e614ead985939009b2d6595f866bfd407c543 -776000 acae9ada07a40fbcd1abe244a88eea4497d892f56bc6c47c9a3256960c48a674 fa6f6390e5912cac9e116a1dc8ce23ea3acd3a45ab8c372f265c2a813a1d43c6 -776500 c7800bf474c58aeae4052c7de8a9a5be9ec371403659d6ce87f478083814cc61 5801468504c422c927e64b555cbde135e90690036800af540e0a515cde84a6ec -777000 60999146dcce1a4d7c57777fd14c438aa74620575ee304da40f3139145be094e 761c802120daf7dc3d71945a83698a8ec2813efe961ad3ddd5f0e8b05d88824e -777500 55464b5c24a72ca78e577947e5e31095625d4a5453d4ae8e1a628586173696cb 7198361fa24cc1510d0eed076fab9402f8d312924dad53b2cffe4a2634450753 -778000 a96e3ae7c78171f4839888370b8ab6a75527c35181a76170fb0c0048a340efa9 40f745faad08e9ec7fb07610cee6fb0bfdc4b221bfe568e692928cbd556fd0d1 -778500 dd54a9dab8dfd4362d396a50863007b96b150c454397a2b4cc486f8b4436acc4 45f3cb013e25a9a12e1998baf79504649e32d0405bda1b8d6cecb7f51597dac4 -779000 04bc1cac32dcf0121905e3b0f8bf15938de5a5470e130dad3d5e9478e5c04ded dfbf8b41e5cb2498ab9f6c772c18ae3af36f693115fd0b7ca12fc18fe8dc9d6e -779500 acdc4b3a573253149261bf7b8483f07e26febfa36a79b0f85663d0418bf89a87 c4e9858c10b84a43f0d48b59f2aabbb978411667e1e740d26cd90e824e60bbcc -780000 70e69b1c46b39329196e880591e35915ed2ff68cb83f2899e1c8a09885462ddd eddb55e0d58a9e963cc6bd8e74cdea45af4a42783f9b070eac50fd00b10933e8 -780500 44f6b73dd235490b827c83c949f8116d3e794d139ff88688db18a6b45e1473b1 011d86e2b32e548d2143b273ff895d85f132b7ad91a6ada40d29517155de88e7 -781000 afa04315bad0a73e082c417351c846b882f070fb89fbb62f94bf6627355eaba9 83f5ee23a34675c501aaeafbd8589c2173bed116beef5a6c05da3652da34eb4a -781500 daab9fd8e2a04d026d3dc748d775734b92ba9d42af448b88c4e54313458f8e55 edfa9dc118b24ca0b01976fa94551d0e78fb276ab38af92581b336d08ad979eb -782000 71ac38f6202666bef6bd02261cdf9590ddc79b15b1f0fd74a0991f32d7076cd6 d02102ec38f004cd966d4e8d53db021475903f0630404bac02af92fc1ba0f055 -782500 7065d66fe20e800ec4e007a0cd3301a98985fa7f755f0fd904b2a999c45f16fd c68d77bdcd1b1080ab776a210493e4371a1d30e3c73d7fe871e04b9345a0661a -783000 d494fe23c434284aa32d3043e1cc6443fd7bf9b36fe12410f7d2e35f5360b5e5 4ef3f9328e1d2d96c19ca549d1147c2063430601ec62870fc66c5b6e68aab6bc -783500 568a8df7d5669899b02e916c28755a8d1fc4a111f3af3dfd4195298ab257a847 7f752afdb474b41347fb14da6be44561bbd5dc034ad25035718d57ba0e326165 -784000 98aa97184148b247fa71460e2ac43389d0d04b6265546ce0eba7c2be328b6bbe cbb9d6529647174626503265092201bc8ed564798e1244839a9a2f022c5774ad -784500 db38f59e0843aca6f105b25581ed990384b8b6fa6c340cd21be37799ac892e8c bdf27aceb99b7e0386f937d7c1b8a5a8cc92ceb95cb3191e5502b41245ba3465 -785000 ddb1f819bd3e7a89588081208e3dc87ebca46dd381593d402bc80aeede0cd724 814c34edf844fbebab1739243a0a664de608eab49ef2d91c57ef7195bbee80f6 -785500 92f3c145e77f1f518c1decb6e99b826ce6d778c24634b3d6d3340897cb670c63 6d607478b75d072ff0a14c4c23454a04b9a08d3f9c196ebc0b817fc7b9efbd30 -786000 07a5df141fe4feb999505fef56d930e19c684e5e452ca352f0fc49c2d9eea76f 192297c49f950aee2578f0ee3249bdebdbf6955714b4a4e05edb3e8f24aae8c6 -786500 d9b454e9c5a5a6f9d16d22acadb61cf1ce231ca4dae12878d868598425eae775 d47d551d3fde80fb8fc6886f235fb6164cd99133fe9dedc2bdfeaeb10bd45308 -787000 1d5ad94333c42f9cd396bd5a2772973ec2440f1d9f3cedade83af2e4951cbb32 0cddc7f86a6714a3e3d2d2b004d1d3869d5226992f0bdf0f0d3bba94177b6a49 -787500 b454323565de62c5e27b717877037c918e5c046dea15404d0817ed066267fa1a e428f7829407e31e1079ddcac80dab9b56743be59912ddbc0e0691178991b568 -788000 28c337da150a017aca9d5619b15d605cfe5c41838893650f9a8108c4844dc5b8 0d7ed84426c912c0a3d3320009e66302ea92039ebfa4eeed9bce380b2b2df8fd -788500 5f6ec263add108aa8bae692f8381bf9e71a615ff5d4dbbe3785167a10465dfdd 3171b907ce8071d79c40b61ab802f51d8f1ecff22c4cfcf618065e8bdefa3910 -789000 1a1a8318353d2997eb996843165ce0a2879e058d6cc2498ac43fc495f3010874 0832a6b246a8221f36b8cfc3c15c743878842545a3ef3b5ffc0f1cde8246b72b -789500 88387f881fec667c0a2943deb34f9e508a994383c3ac8884d24b1dfc400344e2 866305720d60de682a074333f7b1512e45c63ab0f9090d8791f315e199222519 -790000 1659d12734baca5dc87174dd4ea3020c907031df843af6bdf22cc2ec8dea611e 63e7e3f379c2e361085770ef24c82f250cb47056045bae37c92cd369aff4984c -790500 a01132497c3c4a8622f3c0039f319e7bee99942268a0ef323cda3fddfa11f1f8 aebda06ea6afc6b95cd31185250686bdd815e89025a1b067f47db36dec1fb8c2 -791000 9209e4bff9f2c45a6bf3d2dd4f8960b050fef2a600c1dbafd65dda57bcd909b8 e005838fe0d4d7128702bd61e7be6be96340f3d4538aac8ec8adf6955bfefa94 -791500 facd9b684bce4af3ed32b93fde842ee8d30775ca97b1b3a691ac0f267301b280 df48a7e529861e94604eaff33a4ecdd7e35be502a78ce16aaebc413f4f4ba59e -792000 8439d367ef216677cf50d64e35abd6a55d555260d8a4f53af86560221aa48b07 6b7959d457444a0e8c085d2f366d54460a8e8ea5691d8d0f198275ef79b72ed4 -792500 2200f9ce62b2fbb1b25ba5e05a09301f576ca7606c2eebeab05a7188ff5d714c 2b7504213f6fa99dda613f8e7bca2fc6310930eb40c405a06df793406d146b8d -793000 3c520432d9a47e6e272dcdd99e656b04a1bcabdaafeca135cdb61b105b31d413 6f6b8a462b2d883580b1e2acacb9ce051016c06a12a87219097e5327c39d84b4 -793500 a9ede0aed7bc7639d97fbf8c81203349b1aed926ab534ffd055199c047c427aa 6b6e849eb0227f85c0faf658c06e5b4b75e15431263bc587a0417b801910ed72 -794000 8173afb6ef69b30acaed892e2cb93eb9186a55ec63a8730cf5f23909c13cfa9a 4f340c5f5665cf08ec366e0ffe561908c19c646b9567ab3078ddc99ce216fd32 -794500 debb2e81b7e22fe9f49c42c5d747837344567a5d301f900731c7ec427bc671b7 79a735251474e25bff8fd23b469f0d79eae7b941b45b181f475d7bf8ac2fb842 -795000 a83507c3c3bd71dec9a8b3f471cddb67361e6401767c8c8ad348926ce4830d89 e626138e04de566aa065b5a7106daa670c614de2ab4d326523bfe5d1a4ad4899 -795500 0558ab8c1e1ddaa709688f0fbdbc1413bd8f80362f6e053f20479e9aeeedb4a3 13a40efafdbd6358d9ef9f1b9307a88b458e999100a93b8f4611542996eaebf4 -796000 a141fbfbd754e10fd7e956c10d459834261d3571affa49b8fd90c0c804d0fed0 00fc2ab3f76f3b577f97c348313e9256331ea81a5cfb7d8466fdf144c8e9fbcc -796500 7351e53a275444b95005213efb4a5a1397a7a01d58b750323bd37ac47326c704 57ea2db92ddb3e36ad171b3bacb48f883fb7e8ef74466fb769f7d5553be66c0a -797000 80fcb6e51160ba191312939b815fab48de5a56f4121a3d2cd7b6925918a07af9 96242babb7769751d636828f5fdc2d1a44ca57e399fbe5b0683d09fd66b83da2 -797500 57bf7c33a40e1813c1947efd7412a3977b0d74ebfb6e846097aa45d03eb1fe47 e1250b6f44746881c59360dd6144bf4d2e86f8e31e68b0b820732b2a8bd69d5b -798000 f3370335ede3598caea04a87041fa7c1b51e5c9e1c5e0d50bf2bb136a64cd167 e6e1d946fc72e48f0399f980e5a4f7e544b4eb2997739223c355e3b15af48fed -798500 8f2f93e0248a8d8ded2c5106fe5034916127161f1a554e2ce307c5b6afc3e00c 2db41c24fb6ddfebf0b3bb5d74fbc1cbff4185082e7c22ef66c336467c652180 -799000 5c376ff3e907391741b0ce9601a65e616d6183cff6bf744bdd6597c455b306eb 9b86110172b3879f17995b766972b505bf547f40e1113cdb52533357eecc4ef7 -799500 bd143703c66bf324a5cbf67f9da778755b4f7a598450c328fbb011d1eba4d96c a4c63a77ffa25dcbb59ef8e829106f61ad3875ad2b9485ee6653a83691bc9ef2 -800000 e951054363c21bdb8e2c65154dc8453a7ed6908ecb10ed72fab814899d3cd345 9a0b2888559918507acbb704a78888f3293e34ec18cbc9961ac7842ca297984c -800500 956b9c5b3c055d3ff4ca81de618186166629076e317b2bc429faab8ed5a9bea2 9a80628c0558276ab328fbbff05e76501ccc20593000dc13d57eb3ac4b618838 -801000 3abcc1a5f4b6411fad8b518e4e0266bebf4d74ec36400e0b242e299aab5d8d43 6e72ab4aef323f82c48dcd697cff16bb1f0ecb039a1a892a74c57abaed498d92 -801500 c49350d66b895f226052f92ec5d5f35b70596d37a64fc2f36e386c21cdc224a2 1e1eab3a1d14c473a254babba1a8c9f342cf97b0ef0f60c2946149c72cae6423 -802000 f739f9b985ba0ee82823c7c03d7ef8788d23c01ffa5ab040ab23682d5e1f27f7 45786b2936278a79a8d856f96f53f0d4b09a04056b96a10d5bf71f5ff849cb58 -802500 1bc5ec3d7f952e5f27e9de2f21a30fe9333fb4a53b9627d78567d789cd578098 11b12b1784bf7f779aa53e67753bb6eb9d1fadae56dffeb1b9efb5f1b1ddbebf -803000 06fe520cf2eb81478bc9548d5802a7ca815743a5e541ad64b995af5b177ed245 f2401149fd3855cb680fdbacdb22b368edb2a34f73c59af55099c2d44e79adf4 -803500 2bc1768fa981d73fe4eef0174018988fcc0aaf5316c8597cc1c1eae8618eb055 b1a09ed639e05848794994217faf96d9b66a9e5ea926a08efa7bdfcef312b107 -804000 9d0ce3d35c935bd67f2970d8d3d5b098f99f936e880f9ec87cc5e0b1f837a0d1 4eb8648f841497a4bf8388158844361e138eebcde30aca295e530b9d97bbed6b -804500 87f582951ccb498931e71f194f2bacc2aa593bfd236519e4abd2336136333283 9ba93a57335f44c4bfb962c33fc0698f6846755d94ab393b23a81fa9acf72603 -805000 efa84f401e0f8a68ac402f09bc3988192fd6c85f22fdf239e5b76ce100e3a2df a4a5b65c94cf7ce1d1cfe3c087f63037ba522ee4916dc20051d5953f6d42e067 -805500 c0aa476e7e6452f41dbf4cb5bca05893a93782716c3299f44cf31670079f3190 349733cacd77e399f52831dd1f33884319cabf7934c3705e798fd8add0d90247 -806000 8459d195b63e53f3495da811539f2c883361bbcdd4b0097d0ba214fdc55a8219 9fd38c1f19472a144ec9b8cf57d8d9a85966dbc99cfb05628f5683dbe75501eb -806500 8ca60c34843a452a19d05b38dd13aaaddf0cf602601ab66769801c5443380904 f1a31e6d1b4cf5387c7def82294d179a656a10f438585a643e49dd6372982193 -807000 ca98242c7ff34cee593fe6dad4393698bf5875e9a980928363fb0f2bfc01e0cf 040fc4bf74790e2218abe48b6e53fbc6103ccaded8f389a0957e9008f96c9e2d -807500 39be5b7e38795922ba3653d1310f1579b152e493ea3c8bd6630e0a561465fd7e a88ca5c9790cb9542ef0a64dee1b5c001d56bee7636c09105a95abc859ca5335 -808000 8e9c44d713b7bb2ad9d8cbb9ba3d9aed199b4a70ea1f7288795ca86c966e323d 2c9dbc0b472b7ae26418b1def60df7a4869a35cf9bbf74b9a323d08035aa13aa -808500 dfd89eee02bd3dd16482828c743927801121f67cab61a4335d4eead749876a21 549d7b6c5b66bd74331c6cb6f937c8cbc605dee884796067f42fa1bd04bc6a86 -809000 676d2d9df28b1d4bcc68bbb1606033349d3e3a4c11790eef43f689d5e8d3ba7a 18d4addc8cc3174723f9ce263cf632f3817d015245ef3fb6ecae87aed807b0bd -809500 001261eaa38a49c58facc31b6c7245af90f5ccae8d120be1aa3b23f80e68513e 1489cbc34c82aa22a7de85e615f2039703a23da1494aaf7b9d1c425e4839849a -810000 051b563ee0050d2539bb0f57e3a5b5edc759af06e4dca9ecc9b651122354d828 84359c9f7e1bd44948c4df3a1affb6a4ee05c2761f3b22a192faf696c1c8cfe2 -810500 9ca81889bc6223d0195bb98eaae9b2b81771b202153dbcd4aedeba781063e4e0 9ee6f32bb1bcd2ac2787662019ca595b8a2569bb90a38be9dbdc77fd30e0f541 -811000 e24027de80e7e3cc2e2fb95439a4bc88541b10316eb1b111d107119a154ce444 373b8d3021db012bcd4b8558235d625a2d8eebec48f5c9c8784ce80be7ea459d -811500 2188003a3ac1f51c3147082a9737895235c62f579500ab7207e04c3db272300e 5d5c778748335e1c6a4d7b72e799a84b1128150bc5b782238c222d234b6e916f -812000 8edc7d32936aead671b293ca3c35a4f2cd8da3da8d0a911eab810aae919c671a 67921067e57ccb2692bfb932c9fadfd695208ae63e41c58cbaa2d1ead989b572 -812500 f93429e089b8304c72beec28ab2589d33557ec36f12f1e5c21acf96a1eccbbca bceb1b621ade4000a2e9855c387f4575dc2599df96fff5fbb43a4e934612010d -813000 c50b28d6a65438104f28a3518afc71932e5acfc9cbd3dbb0870dbdf8e175e159 b43d73d2203a216818e42d28b5108016335c606dceac6f6706641e240b065929 -813500 9ea262207c1743a9666200b8f174328d53875437ef4238ac0f7f9f1e841d52cd e915810eb721a46d939812114e3017db4a2fcee9c0d3b6701f070d61260706a7 -814000 7fc202882e511a8dc8b76ba9fd0e5d24578c5c45f51998f83d22e5c54eb72c5b 69feb5f7c9e1eae4dcb884df1bed34f628846110480539f3ad02db9e49c87f59 -814500 946dd535ac1806a838ff7af300006a3b019926e3caef42f04e77cc50453fb597 91645835f2dfa4f7bcd0818c145f349fc912335d0c28bb21f5a6c88833531ef2 -815000 32f06e0d2112aa022953d25a663a77c34fb1f0089091be64755920e082588a50 09503cf3aa4c5c2dcdfed49412a77bea1120ed6741f024f25384f9a2f6865f4d -815500 ac758032ea15073a6e7063dc49bac109b04e84245383dfe4a57d8a2d68e74c5c e8796fee578d7b8c3a1282cdd6106eb5be84df03f16f290b1042788e3cad77a0 -816000 4b0a8e17626d583d00af2d1e0d3d5aaa733b2637c0e7daecdc9ca7d32ef78b16 5513bb0e272bc3c35af92c733ac8e3f54a4f9280dd6305eb3f521c0a798864d8 -816500 7883f443a30cbe6777c45da4c70e650bdbdf7f2296d0eef9580b412d304dd1d0 83b8b3ed3caa544c6827b267919896ad0df9b50b416b4092a81c4a16cac4a2e1 -817000 d13df124f351e01764c49f28bd7bd9d94ec697abb36970435ede31462e245b78 3668760c6bac61282ad6173be88f0ac74108aab7e6b2d5b89bb05be5f7450139 -817500 cd9bec7288443f2289c3e350aa1e2f133d13377ef45051c8ef68f588f0ebfb9b a6dcda37fb4542b47d6358e6f4990494b3889031b7d57270d4581c3c5f5c834a -818000 db2426a8e3f0260a1385c6514a424c1db30e077cd18f25affc301b857899672c 1e887aa787c16fd0a14425d7699a20ce4a184468a4e8ddda982637cd60dd684e -818500 475ceb331fef75bf43194e6ad78493ee5a3132b1366764166bea3f98214c5e02 67e95130d865ef6b96c3c3594993525b0ed740d94de1322bdbdee1ca44c52be8 -819000 8bb061140f8217d2d20fc59542169fd7afa823a911f74040d58b3c86dd366481 226b79c0b56a187130199fa71bb43f0c0c17986b38be4bc953aae9035b3b137f -819500 9fa10df35922528bf712983310840e630f4293f91e9e81ea9a6f416107b4b385 23400d8d0d4f2eca02b0a320b012d9c3874250e3703defd32a742ff3a14161f2 -820000 0b83d657248250c7e9d96015875066e2e5d59b7a0696af84d83b246abf9355ae c7575028b8e2df600f1ba0acc5a101952b47e9660a8a912940a2b548172a05f4 -820500 e0176c1631f2909dcccd2e56971085cc4a435398a3a967945666e2d7b3232d1b 86cbb6afeb7fa1e6ac902b3d28f2aff25971d24b6cff228da7e4c8046b397ad6 -821000 be0584aaa7571f33c631f75d7881d80e2a19f6eaddb91f311547687ab8b6127f f8edec8d65127f3eaefc274cfce29f29c4cd339739f2903ec60759367f283f67 -821500 fd2e812d81cc2da106beaca8ac8e7ec4ef854416f30d7428c83dc72944e01ed4 9bccbcaf94c587dafd152fa579fe7bc4e87734d1840e0f939f494d1d60dcd499 -822000 9054e0ed1b7621397499863a4dfee073b379cbab6d211118e0daba86ec09b239 0f78238858465e4308062dd44ccca1a81e3b1aa830378d63ba37cf340272f04c -822500 c50dafdd9aa14cb0fb01b2d54da426cb862dffeb6369c1ff1f27b86bec6ea28e d7d020758a8d3fd93ce7a603dc710b085d16c3c232f389f2518b96b88d903a68 -823000 6631367fed6a7ca98d2ca58e0ccb8060e9e0309df1bbb5d76ea337c386f3066d 4ef109d1b5fc3ec978f34d66b8d93cd3ba0b278d7ba9c6ddf4fc3d56039e0fec -823500 b924862a40ef19454769b776643bafafdf407500c16dd73a70a61ff7d033519c dc8d2c04b3dc1785a7a76698674830e8aa8371dcb815083d849851ecb47f1805 -824000 d9ff8b7426f57da2db3d9f855572b493eba90e61b0ff3b40beec0b46578679cb 95e502ccf5b34258f239d7a5aa86f16c643e189873979210e0cee9c5acda128d -824500 b668014cbc4e38dbe8870d15c7ece604e8a698dead63136af5954cc403a13921 b634009a41de61587a78dc3ab8aeea26b6d107f5e59df2e927321f31c2751347 -825000 ab26157df7834e458aacbb394f8f6f34fd489cce3c7a1e6251289401acc59062 73352b8b59b8fdbe1d83e82c2da9ed6282c5788802e2eaf3db7e7647e04d83c6 -825500 4447fc4bfa77499510c1f033998de510174732f103eccea27ffe544577472f5b f15ba38703c021fa9419af02b8210ad9a9658b8866f70cfd734e282daf996169 -826000 8b30104ee7551d9d564a9142e2334aade0c93f1fe7846f2d2d21380096a5a1c0 dafdfa617b0bb3f7980b4df7dd4d0159144b7973976db5e60a28308c0e9a2216 -826500 0e2e09768e2c0cf1f39eaab0b5182b1616b40b9a6d931946bfae09c246bff35e 417a26d05c6fe49e0800213efe648fc7fa29040f0f16b4e0f3814ac4087fba79 -827000 9539816f7acbfb9151d30dbd91509b104a83bc0564050ab5f3c3a180d1659bbd b8d3ddccffd24ee4f56c161acf6a739668f48a10fc703233bae30108e8b23f04 -827500 735c35ab86f85b3d7c430b126cda4a4c8e55479a414be9b344ef0749bb2381dd 526c10694250f563eb1f7e7be275d89c14893a95118bb5caa0fa3757d2f1b08c -828000 846213c0f91cc5f47286bda5e74a48dc86d91bed3d5549f2130211dff2210540 195e0a72d1b5934d7b37d8678c6ee6da4713fcfad761e397921573f0c727dcae -828500 033da5a6c02d67fd91df3e6d357de891ba0a8352546be1e4c3c47d6d7a0b8916 3d55e3405532f51149ebf67cc1367c225ffcbe2832a37814c37dbbb324fe8c6d -829000 b64d6b04a7eeb8513608c60f52b3a54a2758808beecc359cf23e5a1c9991e1eb ccd618e28a3217ca7d14e462c4d2df34473438c0e89e68a498b9d236507003bd -829500 31cc80619db75aad85974e5c52755375dba0dc8ce67a17e6e6e4cb29f60dad24 41145f9a5566c0d919937386229a00f302067d3d0dfdc369d866f164c4edce40 -830000 ba6ae9853c6f5efc64e12f9982df9f199587f43ac41c49c56c52a217c42d31fa db3584bd7127b287f20a097fefea21aafe602b6d36287248e5b878d8f59a55c0 -830500 881ba4b6afba166f55baadba4ff7b98076398db48b53f05058e4fcef5931803b f2d61ffdc8eb96d572eeb829ebe227489c2748aabb4e7ae8dd2d4ff04db6135a -831000 a49b5343b0e4fa384c6cdd8a9b79713ddefccf1cf1b9a9b8340a55ec56330684 d5d6f8ddaa5631cc30932ced1cd5151825bedbff4f7c454fcbccc0dedd8822c4 -831500 2325e3f54a404e7bc60ccd0acd9ea77d90a31b18f8368ba2797d9a2f7388b482 09565fb72aad572d7b2fbbf1b0662da7687c7d98db22f55063d753d0e59a9663 -832000 79353ddf61d1fd1c8930b19c8e2abf92382f86b7ec5d3de61a766952b465144d 2cfcfc5a17e8042417128b3e60f6c2f4acb4f980508c3d172e0530ef1322f55e -832500 15c4c20b6d16377134e683d2eb7d561d4276a32d61f2179b1ec4f6461ec4954b 8d2364c10cb39a2c74360fda5585ead678c0325656ee7e2803383cf5c9e94862 -833000 771fb7f8e60a4065f3977ce3397d58a58102e11111312bb8d61399be0774809a bb06d1ca6e8e92d34fa9f31c9e3332ee8b3b31e0a4bc3a1deacc6a9e0a24079b -833500 b9d939f1ccd4ee8a2b769a4b014dd932f2d51d765eb4a4cb45844e726ba26f7e 77a9c4bdc03d8413b3600eece8b0593804b58afc41204063c3ab92b4c70d2478 -834000 c7bf6a274ef1f46d5faec1bb73cea0d5873fd15340b0ed103b0551213bd0b168 89deddbe651ce60767e84fcaf8419a7146cd8128f439436cd9c5edeea0c0262b -834500 614d3beaadffc9dd3765a68108e9f2e01c33a9c440438163970be6883f71b68f b8cc0eca95d7f827ab45bcba1eb5640f883f803c6635d09eefae1ab30558872a -835000 9a9f3c4367e50c24b3210a0650dbcab4ca0762018f41110fd7d45e70a0270e7e d827e1af0280be63e64f467a81e39404d3798234593ed89f03619354cd4dd7a5 -835500 cbbc70202da7cdb4cde6059eda7529609c9781e534661c44a1f61e5fab4de31f 9640b254c6bf22f95f94b10ee1263d475d76ec7ffc8d8813c2a7f73a7ca77a28 -836000 63d55fcaa4b84b7278dc98564a5955756f3ecf915b231cd6f2399ec836537a34 be4ab8603457a5c080f6d4f451702426b19f87ade3869565c41aa9aa1cdb6b16 -836500 a0a1ad507cecde4069df4dcd3ff6b0e44b917e732cded5fb86d50acbae0009eb 09c9ddd16cdd8ee68faa85a59b8547b9d07b19ef08ad42fc9d98f9d85ae7f54a -837000 4236b2466078279f38a8df0df56bbdf71da7a184f750d439aae1b7b9b6a0e217 1b7b95d0f01cc0dda255ea389572d8d66be622054e9913e6471347d83070da7f -837500 975034c8d678099a6afeff9e8e37d1ee524f64a851ce07def65676c0ee189b4b 2dbd86bbab192ae7e44609388bd9036e20d6496962b2ced1b23eb764d4eeb3b4 -838000 05228288f4e87f9283efa2e6547316fb61f8a6c9a1c4b3dd1b919d02c4beff88 8bb8421d901f05fcb5b476b8d5aa66f4c380fb7b00f65833f6b0bdd6ca93f62e -838500 f165d6b92e8b15b8a276e7aa3682e61c44e6729a39111e1883cc8bcc78cf9b30 55e669d31736fed4be07280a142594c8f283e7a427f0630f9ee7f0b06411b948 -839000 e7b73701d281fab70e7279cc3406b961db9c7d89643139882ccc269515bfb8ce 44e7b9087a0f031995a963ba2c3d4d59a2856ddf3e822d0944fa472768990ddf -839500 a0e9976acd9fc6b93cedeaac38938156409b74d9192f1eb4d614d4af4072d67d 774aeb086be488987a9ff3d9d80fe11d7815c1061754431fe3ec2ff387a4e2bd -840000 85f4bef924671af404c377269d655812da734608007a1e43c7e2c974ff1a7f26 a7c27c2f0b37677d61314ca1a510aef72e2a7149c0dfb3e314c47ff151a7589f -840500 9a3f8a90c257352934919ba5678d710e02abeb3f8c9b609f00827147d2f7cf81 c9234118875f5ff26dd4c37d0f498911d1caba96dee4d33a50c7ce378a9a0749 -841000 51b45385204a2bec9cfb32ccd8677bb9fce49c7c5fcb6a53c452e9b36cdb0bde 07ed169f164ef448a9a828d17a6c3455f3a11dd6c2bda1eb38a5100b8817e04c -841500 92f53759b018613ada40999270e66657ae1026e4997862ed0d5e5560b917d6d2 37b8239afbb1d59bb35fd5696404860f47dd31163981e62738867af4d1d13c85 -842000 a1202ffaaa1bef1c9c95e11f9b2f1e1b03e69f535628130df12635ed9a3fc297 ff3835e7e4cb8e4514adddc8fdcce0466170f3062e57d9abd9599da0fd0ae1dc -842500 fcaf836bba0923b8d887f619a0ecd298a94f04a1127f82773a531d8951326582 7fd60c91ddf7611c5d0200f3f5adffda13a651c5bc71929b0724a3ef0c178463 -843000 37827f08056c92edc0a941127d96f9f4f481d70cf2cb6c8c0212bbca042ea04d 863b61ceff5d6d3314fb420c17bb16c00b220833a634f53d24f7fb6c9ec7f7eb -843500 5dae3f790ecdfda5bd46aa1005cdf1170b25daa976dfe3f83f07cddd47747f86 3d352565915c9634066580e57621f6682cc147cc92fa1e7f0112af699a2a09fe -844000 b3b067a2be410c5b04cbc3088bcff2678204f31c734440fa5ce28a43e61f6e20 dd379efdd80ed38f855dc2fed11db6947ffecca2c6d78c3b13d9e42de618eb95 -844500 d8ec90a7f602aa58fe31112ed0917f4597352ffbfb186524253bd4a88a283efe b8684b9b13ead86b6620d8c6cb1b4e3ae9891ad53c74a5ed93bb547b05d1a8df -845000 66ca29da4d604a893f7a56ebd96f365b3853ac2de6b38b71db898ed7226fb49c 2a671d1a790cf390618793e3a9e2995de070c431014e9b1c88c9c587cc12708a -845500 b735fe850f31101901fe04a4207e15ccae72039895ae0f149593dee3e6cf8a47 fde7269beb8e5c3ea60f2b30d1d43ed52319787b1d9363aa67c53e6beb187d6d -846000 b526a9a73f37f20c6ae046ec9b131f6354e90a4596cec60cce1414285c838df4 fd42d265ac2d194a94732500fcdaa7f4f2e629793fb220a871459880c0cd000f -846500 761bbfd7f554b81cd153149a73641b567685b60914402dba0ee171d8dd0237e1 2d9ea683992b346008f860b330b15ba6ea707338daba431103b2a444542f9870 -847000 375dd44f3bb80150df686ae8f3813999d60507c6e9ac4750686b5d182adcec3d e4ad131095150cdc0a23d0d7948bf3c870e01ed0b4a6f9950457ecfbb254b342 -847500 0539f76c06c311da93887c10f65904de31c72a00a2c0ee1bc66a46c50433c0b7 2ce4000e6e36145f7c0711f53a8b20144a69599490a7da79726938926685c5dd -848000 c6e8ae1f92209bde14bb652bc8478d5592d0f6741c3d2f2f232c037494d81f70 b7c0aedb71b645f0501319a9842e1fac4873184f50a0c5b758fd9f2cc2547a1e -848500 d302c73e4d2ce3e318afb5cc773b089956501f00f64de08073bde92b2f3a99f3 0a8901df9a3d00b66ed1bd0b117645237b61fd34c63fc45a0604daf2ac932bea -849000 0ad8844c1a45d6846464c00e9c6853719f80056b6f0fb70821536a133432ba1b 6478dd9c136dd28bbc4a49eacb7909c179abfef94618dc6da67adb4ffe69c6dd -849500 8ddd724ab7ab24e5ce2f5355c2c4bea780fe7a2b4a01fd04d6a0be5bbcf6059f a8ac1fba940445cb8dc5f6eec18d1546f36bc441db187b088b1054ce8236d17b -850000 b5e0c35c2d33ac37932b6d187a8839f1bf846817dbf5f4c58b73418e9a93941e e9f2c9230ca20ec14c17a35fa24d9eecf9119c5a38809c420ef099d9cd4ac61c -850500 7c1ea7bb106ee4a55d64930589f44b2e9fe63ab9846eb3caa545fd3b5597ac0b 9b2b304003bc1746f27de0d9a7cadc9dca7d6c87b6cd5c88da09f45282298480 -851000 78c3131d573b6a70a648b111fa904b99707c622bc56f842297953968e50bb804 9dcd68f3d2c985c324ae53f03582ffce484a70724e2c13602f84099737641cd8 -851500 e470491ea5d0631653c6200effed322f6696614bd98109f9f1c90c2cfc72f211 5dfdf81aae36a8b8aada229a8ddfba138552fb9e101f4faa56bc76d3860e7738 -852000 528590bfc01e4b7f567aa786f0de29c2b7aeb8dc3042114b087f761a5e6b161c a96175b5107c4129f6512d54adc38ebe2f236ed6c3f362f885cd4a96c6651e0d -852500 a286a106373a8e32cbc0b3df7ac65b0720c04cae34a07cf070bbf652474d8c56 205a7977e413da822705095027abd2edbe7c5e34c9afb7225721dd18b700454c -853000 a2d7a0b916cf5aff1d6cd5150b034448c58dbd104c5f88e9b18a692d4a8e98e3 d91fce318de2b273cbff6891c8ab29c769d7dd2f09b302937493a38488ce1446 -853500 794d93de5f3d5c39ad05ee77658de33f094880b037da8d2c124f4257f7360164 3f94598f08e53b436df3517458172624b710f4f9c108c463a39b2b816e511a0b -854000 886b8b0cae2d1c914ab6748d636d5553dde505c655102ccb384a5c9a2b864516 308dae1dc6e58335096c15c90fc276e9cfc6639289c25a9a748ebe226f37604d -854500 78d0ac66bbe4ed7830eb9025fb934514035d9440e2dfa75d4046410185235755 e2976153d1e9c4253528b84741fbf9d8bc73e85089d63a59b29d5c847e336c02 -855000 be6a06e20a33be8f7e0c96318ffc3ad202215dcc9124c06ec678a6a775c8f67c 4ce675eafc85e0f8d54f8281fecef780e98677534b3dbc3b1e9e7f7a529aa3dc -855500 ac409e08616a1e06ddc3e14a2b1f6bd947840932fc6e8b007246de280a6b66bc ebb67251598e38254f9327ff1dc2336da5269cfc209a5476260da523cdfee0ab -856000 62a624ad49bb1908d25d7190f363019b1cb5f1a1dfb849bb50226561b3c60218 ba4fef7924ee2e26f271a49319726894894497685b1c81ea84e0bb62246c24c5 -856500 f02dd187e61db50768a596177bf62878130d15910ced1f4bed2d5aaebcf4960e 8e9e38e2a88d1a24151ea08cd82c2debc7034d5fa21e75f926d9a6c0df18d6ab -857000 b2ea7f0e6a51ea74155d6964d732dcc4fc8a0b71c4e6837d1f17030d026da89c 8ceccd983eb05888198163e6a0ea44261e44876289a9effdcf3d377ccf62ef67 -857500 f99e644cfa949f806ea938b97d5232d9430ca11a51ecb0ed30ded90e6d4f120d fd26d9ef2f463304bb2839e8bdb3b5b0f48592e2cdfd043ad809292e22391623 -858000 9dfed199b5f19ad984111f21fdaad2d5d1779a317ba5982a93e14e37e21a2eb0 3da6db23d0fbcdc02c440eb755828b4a5c02fe77c75b153055eb25362399216d -858500 daf47ce2ce33b9db10011f6bd963bca3abe9b8b27e6101394d5516555e8e7bc2 4fecbb4ea28d764bd3dfdcb6571a7c6400c76c1e7f21a1c1407d057fbc6feb62 -859000 f6cbc9c86ebcd2832f2d0db57e47b611d187189a37f33f7588c7c24e2f2174fe e85af2f0bf8bae60e417cc65de17bcdac486348b40eb55da41a51e98b5c148e9 -859500 11102fd852576a361c4c9a3050eb8d605f317f82ee78200d2a2820d8a3ff76ae e70ce2ca1c2e9b818d276254f46f0d6156003a8421ffa99fa8499a09a982e1dc -860000 b0689ff799ad43c8123c38f815e8a5dfcb4fa2b2cc1d59dd08f6d6e6f260ccbe 60815a438a372d41ec3439f8b21cd8cbea71b090758260b1920dfdba4558f235 -860500 6298a42b99734a2702bcc358dcf100321fca31a1cc547ef0c168fa83a50eb132 2881b992eca478a15c1d505d3b021e2f589d536832e98cbb90831b4d0daff767 -861000 9f8f6446a6df4ac6674a0639bc616fbf8955fbd7c5a6ae8743ae009340acc6cd b9c2b8a675ec2a9f1323f5391a81d5a2bcb83ff02fbfb94e1960eebb50033bfc -861500 c53640e61534d7de4001cc4f6547133d225ebaf607937c6ea99b3a92e0f1b445 7befef633b3eb72ac1897e3628b20540cb0cb51bc447fd69877d178705b165b7 -862000 1bb40c878bbe264e2fad6a6e523345390091bef9bf689f6860bd30fbd27ccece 66bf4703cd800c13edc3e67d0889df0c4694e2f6545c5f71bb0d43d80adaaaf3 -862500 464bf61e9afcf7f9418661d069ebb015bed143a3c53449e9ca98013c624c0d01 b858f8d0afefa1f199f3434b656587228c659429a9b29876139cbcde4a66d36a -863000 0dee780a99a58bfd60c05f95db7ecf49c8ca8380b7a5b8ccb4c7c26229966441 4555335383dd8dc416b36cfdd110d6da87faee63fd0461dbacdb6cf9dc61fd1e -863500 98a57cc44810adfffccb2f42f93455e1124e3297a8dd4e176b6367bcf864fa6c b16bc478ec16263bc8995541eeb0cfc6640074c65853989f7619f1094b48f17e -864000 516c8212c055b610d7295dd1dd14e797a2b4ac025f1fd2aa7b3d26488f260a60 e221eacebb459d180c743666d691c11997995f6f4d75dd21613b75eed2be2425 -864500 2e8ffca67b4cf71272e42d524e1427b794a8e663b437c156cce8f9ad39d28b58 7237d3868b25d2fb9801de887b7c2071cf24952719c6170a6e550773a61a2170 -865000 995bc313381ad5d7799cccbcfbc18876582f5a82e25dc4a6bfd299facb83adba 3ea758c944b2f0be32fa7fb541e18f683734df6197ba711285bedad4f17d1c8f -865500 dc2fb63083a52596b814426dc2577b6eca27f5e80b08b83776c93adb0b913324 007ae746a4a5b901f91e51014eefab59c84dbec3a3e784711d1a16df0aa04ac5 -866000 a1a4a61f9e30b4ac585c2777dcb066e543a3ff03ddc20b67aadb9fe8842080b8 953ff29441259817927e36e3a89db69fafe11d253509c36a2bd00805563ec4a5 -866500 44fff17033fa5e2f48afd1313484e62ecb1bfaeaa0b19b1973514abe18381d2a 1bee0d01001a576776d0e6113954449de228bd3f69feea67a11769f2626176cb -867000 77d6f737b4c7b493657ef08c7f28b5dc43e3a7194b2e3193a37d1a931daca9a9 a9f847fa150f5881ffade66584ad6b5a741f8dcf9310eb808181c9c3e4724a8b -867500 98da2413dbd1bf3e2d3d6254f849e3a971ff9579e78a4bb1ba192f61a1ca1bf7 55a4bc913aa643d798a0d9d29b5c31bd38db0051ccedef30bf4bfb2ae6210159 -868000 1e33271126faa909e8b77bfe4431587ac68d50716e3ddee70f18f4ba56509c98 6b3ceb03adfc3ed05acb7ca6a2c9822e0b183c1359826f2714d26fedcc8b779a -868500 b4bc5ab2d0f52588e8e154a831e92f9bb249bb30c4b6a4e379d529d9c916508f e1810b871f581727fa81164f7ba37242a0376aa7870f897547fa032efef248a1 -869000 9db0fa91a26eb2c05272e50cfff46c7c9faa4d72938f14f03736c7084c4b2d20 e80a050a8dfd6c5d2ecf765f43222b8aec1a85232641c32583487753ab3107ae -869500 ca4ed5b1069fe42bcf42af8fb065aaa98db119b2e98c23c8ee9dc823c46a0bc1 1f45046c69978e3a13a013d995a469a2a6583b18cabe3e48c5735a1bbe88f1f0 -870000 02da00fc2fa6bfb0027e8c85a1b92e919495b84e763dd57afe758df11635956c 8ff1ef73ea14756b421192b3f936ed06cc5a8f016c33a4bb8c3eb94a0a4afb6b -870500 04cc97d0004ba00a8211986f0fa13bad1cb0e7cd17e302242128ba5bc923bbeb d4dce041cd8b2c51cfb7a50864de5d72a627a93ea5f5cc4d837004e9fac80691 -871000 8c46f91d61fa06dc47ef2715dd66a510f1eb909b275c85c0f8f914e8ef0e2ce8 a04657d974398377996f4584c23bf29a55085fd914b88fcc85bcfdee46c1f4cf -871500 285a13a25bf27fd974c9bd32ffda2796ba46e57044b4c282331cdf94ad55ce0a c701e8a240d4dce38b98c91b01c0b306ea6c8e72c345a2fcec704f4af6f880a9 -872000 0f474790eec84e0216b27a41df528a1037767792657a3aa79122dc31caf1e1bb 0774199988a33ae42d91de34cf2c1450aabd65b62e4792acdd67ee92c9d617fe -872500 4192751ee0a2c7b7bebe5e6a7c60dfb98f1527eb6dab97071b5ea89fb851215c 9e36875819fc969d8b5f971bce6d1610be7a012a520b317ce574c1e24f26c0dc -873000 34692e36b62fdc785dd9468d43a0a637aae66ea75c592d5c92e3b79245efe449 e97152bec752a6cda91c4153cf191e6a04135a2d824a6ef8ce6d64f640a97fab -873500 af2ef369df933f912140c7a4ba01d3e33ae803b7b2f4939f8a98405fa4127b90 3e30270cf39cf279ffcf99ad4b0cd55c85872bbf82654d03f6a9a40867ceaead -874000 7f1cd90d997b5a1da4daac3691082770bc7bad48acca998746980f0b57ccf21c d7cba24bf85848378fbc0f655a1795b9baea22b97a29b3bb1b74fcbdc25baec1 -874500 c15fe484c8c031d1327d24f1b563bae0c6ceb1f81b8c0b37c1a3a6d3ea9c12a4 532b3b617b128a1da69a7390fa37d292771bfbe039436bc7f34cc60d51ba1289 -875000 6d606825c8c4902999704cd9839f60f072743c33ef3cc8fe5b075e15ad6f521d 0f98e7eb858a741ea9b7f9260142cd07d98f3ef2fd0f5897f0dd1196506f28af -875500 8102b25248d5cc9fc5e8780fa7782a5f37113d5797ec544bcb6164d922d91ddc 5331a1c3f2f1e95e9acc0acb83ef4cbe04785dc7a319ce069d252cccaaa748b8 -876000 2a6d640eb47cbc93033640e4eece162640b36cf256a1cafb406e2c22f0c10fb0 34f34e19ede327aa5be14240436f18ead4abe6f226c1571429937380247402d4 -876500 61e5fae25c4f18e92e7adf64242dcbf6507a7ce4f1b0de6f2e614b8f1f5b33c9 3f421f95de7e2129353ef06a9f9a206639e0f5be018937dd02e4c39907b75702 -877000 46d077012ece5a31c29ba761425e6ef9d42501740db45016c8c5b7da1d216c7d d06c5c6aa3c05475f8a8649b9b6134e0c92301d47186f2c379e7b159bab2388b -877500 610a50c20c1661286355fad8c8d067e794b5ed61c14087d04976cf0f378e37fe 18141f4f7bed0308bddc68a7b897a035293fa9fdb074b6af3b271c2365a3d1a1 -878000 1742b73fe7c2d014484b21a1604b0a70dc7f12540d52b21ccfdc9f9ea72dc53a 90831e43dd3912ceefc00d3d544c3f26dbf358ff3b5d24041ba1f322be13d9f2 -878500 749fec5fbed9d5446533f22f0aa36c20b63b35116e6005ca519f7fe1ddc76b93 a13ee98f76ebaece600b0723a6ae7f7ebcabbb86e6beb5c4b9e5cf3e8170dd76 -879000 8c578dac00d2b6db2e1972886194a4be70dddbceeb457150cf1b74ff19022532 627f0854e663c40920d22d252b41ecb60a4bff1de055d1789727ff33eee14455 -879500 b31016513fc56e8df0eaa71197462492482734a9dacbb0d85838bf4253b70b30 854e8e0aca0625eda1261e56697d87244c1e386be8d6aa78f15de8de50a76169 -880000 e0764e8169753f7f532973ad4706e5f6a07e64b7ec10f64240c91f0d319f485c 4e1ebede695c7ee95e4442814a5d98539df2ba46757b95d8ba4f0e0e437bb535 -880500 b72623a454e91149046f522d60935871a1e5f098389d9cad4086119732b5e3f6 580082c91f04822d21265dcbbf8c3d3a0866171acf5564e982c8386ae5a3a40d -881000 b94687f79df272c2c5e85e21bff01136c5e99576571bbb8a635353aa9b331c81 8f383eea1f9a3014c27cc3c0a6196b0764c269a1f2f3effd31f4f6b76d2a33a7 -881500 5ed1eceeaeebe16a0c746f796507f6b0dde6da8c53f4e3502cf5a49f4ecdff18 901bbb467df17a499475e767cf7886763681deebd4bbb537a4bfc7f3dfb89774 -882000 bf12ffa015864c59f04c80d0141643c9de99f79b79c2b26ddf9bc398b9d8bf32 2b7b77da53ad2a19f61e3aa54ab5833bef79cb88700e51189ce7b1ecf001a2bc -882500 c8e8deff1d81c65f2b607cde0312982b03523aa76c6562c666c1dddf223e7432 ee0cfaf5a0a284a4e324c4725bc6ed5499cec94d170baff0b955ad6b2a2eb487 -883000 b12011d25c4c08da00b5acef266ab9e451d06c2fe9c65e4f149f7f0bc32b9c44 9b06de94a84c8e550c49947303d058d4a93d898970d50b8be9cea965ca656575 -883500 77b6c306c2410ce6e03c825d016aafeeaea3daa7172111085ebcc5806dcd3bd9 01d7719a498afa8051f872a3e8fc32cda3eba0e4151fc16722c0944d8715a6ee -884000 1fe3f4911ede2f37d7587640a80408092c044904f44900ce1bc41df2e0f887fa 8e9b706cdcdc53e77915c281b532f0589c649a80fb563bcedfa8fea8493d4a67 -884500 22d008aa6022144cf5b7070e91a056b437f105ee9ee3d343c2e1eb485afc55e5 90404898817c93e64a98b4919df62ae8a21e4dcc9bff13fb563a33d544b9a09b -885000 0d39372bb9bdadcd80ce022e52792bd5097a8235cc9a571cffa92805b0d875b5 92306cc62db985c495b43e84e2c4ee4c6310035952d4d52e4a13cbd1af0311b0 +1039011 +0 0000044966f40703b516c5af180582d53f783bfd319bb045e2dc3e05ea695d46 a5d211145f8e6ba0920b2893d307c5d7c207ae0800a80955299678d1706ea8ac 000000000c4682089c916de89eb080a877566494d4009c0089baf35fe94de22f +500 000000000680a9a697eb71155b18a5827e0889fca28afb81fcbb46469ed7877e 79f80a8f54c6762d6408347c6dd7dfd2f8b8c191077c1d7881dfc5b7ec6a408e 0000000002b868fe717dc60b8d146de4d9aecf779b7314224908566e01847769 +1000 0000000000000cf908c887020f8970b7fe952f8b81164d83a87621dfdb581d08 3356ec4296ff2f04281492b0dedbaed80edeb6dd9170b87230ff79f6b0daade7 0000000000001e7c6d28962a03b3d75ffa1355ecc6d3021893b2727a1ccfc669 +1500 00000000000010e39eaa987e695caed67aa0f3c33576fd2621422c7c09152ca2 e9d31ec9f5dd4dc2688791edd4cd1abc964a7f843c59b948903c3492940e459a 00000000000008c67c2e1a3dd564c1effa5ac4edb11b8326e790b01d215b10a9 +2000 000000000000029e318c44be8a5e1d5bc8f7823907bad160aa63fd6121dd0ba0 15e2439021c4563c7eab5b91c916a0c9c24c3fb374b49ea24a4e2aec241ab099 0000000000000477e2b3fe268246df89cc66d4df5ded6eb1339f46fc3d41e637 +2500 0000000000000b813b136f623f85155cad3069031cde918b4079e907e1a9fd58 76ef339392ae45dbfeb2c6263e4e88b4cf888264d7ce8d0361258a81061fadb6 000000000000219c3f912aedf5899b545ad237a1bdc16fc4111e092dba394e00 +3000 00000000000000e5ac27d3bb729f5c8a4312f69b28c9cefbb18b8fb55ee42c87 dee1d4ef373897e52847416837485706f5c0fe29245eccb0819ea5d32f594051 0000000000000858c1d9330cbe0318d79ec09d00d8b020245f4ebf7e304cc2d4 +3500 000000000000123b4e50db3f3706974f7e3593c2897bb545177d5c8a5a11fd35 75c65538d4fd33e5a77d5b9e5d756587f45a7cdf55646f1cd72f2da2b7ae5772 e0fc6aa659df9d7d095a90cdb67637df1d2802227242b139e988d5202669030d +4000 000000000000013e3c1513a7ffd71ba89d7440fcacef6bb39a76527815a71043 6ca70d4bd86a4dabdf5312a88a99aeb874d851df717879049d8d91b464109adc 00000000000007a831e09844b26f357a1476bf9e99959ac3dbb92447e938835f +4500 00000000000006e6d70e292394dd1f4aaf1ba3ea7313ae981a0b2f38ec4b0503 e97f1c03d9e0445a00c160c648d2f4920845502e788f5c3f2a5a392544e18d0f 00000000000008c83a46958c24fca62b35237889269858a639c7a659ad8dc031 +5000 0000000000000278ac01346559ded91fc585defc88bbaa9d7f111b199e516779 45f12a1790418c3e9000bca11394719138f398232fd62ed3c801b5eb1e9199c5 1a022cc6d920c078509ee34069e3671e195d7a906d0a2c7cf78dd2849d53a85e +5500 0000000000000284e3d2455f09d9613ff71c49144823f882b003ed3177c1abab 149ab9c582053c69b64d9b3c3041f04527bcd47c572d600947d0f737d675f953 00000000000012ec069ab657694add0d888db799ec7c108c6de58b71da884f10 +6000 0000000000000bd43190ec79e54ba203c9387abcc8c1c03c52452a44466f24b9 ab0f1f81aaf4000295bec7b21ad5c272aecf7dee60c451bcbfafb0beddabd2be 0000000000000ecd84126d8a476fe76920ccd8ed29f4a2273a345eaa489f7722 +6500 000000000000029e27c331ad9865fee87dd19e5ed0e526f9974510649616cc1b 9ee7b5e21984f8e3ceaa88aba5ab2d88dda10cf28c57b826e3bc8401d0bac0cd 00000000000009a940eb271c38622190df017bb472da54a9a1aa218c5bf6cbd3 +7000 000000000000034bfd6bd049678a41563af84a9581d1ccaeb4952c954e327918 e09213923b66de743cf8edc0389ab1b6c07c0c79a175b3e93364ed73c2efeb69 0000000000000b7d67e13d24448ae494f169723a215e0d5c2f712af1e8e8b7fe +7500 00000000000003c5a246cab977e3f339041bc95aec5cddcc3d459d3d2cd546a7 4f26360f00347667d1c2f108ad3e2b2f599a599cb77b1ba9936988664ac53d4d 00000000000005ffe9c2f6517f0e04151c40e9d8cddefccd34b71e0d4d35fb34 +8000 34d2ddf9aa94d6e02224588d3d6585028a22f05f53529a19a202f41ceb36cefc 8bc3244b74f884ae355598fe0200a7f09bfab53de1b3e122020c4e2daf08fb63 920cc777b15af320bdd69029399e2632bdfd8b741de509f2517ffb8feadf9493 +8500 87ddea52f5073e5283ecaf0efc637da3a47986396ad30b3adec8ea2ba5f6a09b 65ae81f7094626494fe8b984141c265f689f4d6abd33a3a74eb491c31c5d02eb 4349cc0c4c3040b098d7f6bcf5f98b47ce1057505800e7126f080024dad8d377 +9000 000000000000016845387841c3d5a584d82763471d4b84af3921ee2832715e4e 11b2851886bc2208cd41c8381ff7bd6350379f6c0224f9608450fb0da56a59d0 00000000000002e96fe9805c42c0bc4b6a8811ba63fa835f2cc2883635d8c98e +9500 e64e3a10f2daca17836d2bb5868e76290da1fd3e0574da496b06182033fc70ac 5d6ac130a3a5cbbf28cf389cda08aabe9cd5bd9a4da2d0ecd19c27d9ab2320fa 0000000000000040b3de6fb9627d96a86bac4cd28e20cd2356724a9604fd5e55 +10000 00000000000001634bb95749a866092348aef266f9169c3ddbcf226d4807ba09 986b59e97d259c74881bec99d68adad8e219a0fcaaff6af3fa31b0b5a89e1b33 0000000000000069574ac2e1558be068e9f0306b79d0812476002ce7f17febf2 +10500 9a98c541a5e55bcfc8eb6d887d83dc6049a33381fe0aa3f4766006c1fb066905 3dc29b2469167c07aab94fcd87c03e0bad1a99d47c3594d80b700b05190eb526 00000000000002d53a0ae3c22c4424fd877c898dc08cc90860b382c68e4c8e45 +11000 54bafbe72c3547248f553615eacb2254fefe5a4d4cdcc66a2efde3e1ad9f3354 7113b80a2fd13692c85f39cf494ba0d30285981b4829caaa92b4b748df134346 000000000000025e9a743a9023c5edb762b776d61569e374b82accf5a78a95ff +11500 9d6f0308699be5bed63c54a2518b7a69aa2e7f5076202ec077d3d53159b291e2 32f1b2236a56fbbfac8b1a72e3e3cfe24531bdb2c38c2619828d11c1474df677 c3c477b83ffe98338aeea638c538d0ce0f12486695dfed554ba6b7b9c1c68db9 +12000 00000000000000734778db2ce455744e1a50745ff4d10ad3d787e49c9c2913ba 712f312d18d3c817c33e522dc5b7b50b9a16c0dbac13e56ce817e8b6d7f75ccd 0000000000000136e3a5599beaaab0b3a4d61e88c79b859be81dcf94ef9c9e7d +12500 00000000000001209c8fe742d1a45c5fa9689f8622217ace049fa3864ae24321 0c4bf64e0024dde945ddad558a13bb180d931ed8d6ca79c13112a154db415794 805c869dc4a5e69debd0ac3b9ed943839f89b4e75ad9e0129e29919656344ff1 +13000 0000000000000064fade9e75fa24d1d1974f5ca69e84e8688ef0a58b9dd2dad2 b3411ebcf6385fb575beaac292c70d4e79686d832d6138ff3b68cac8fb8e96c4 00000000000000ff65f8b119f936e985947155cc1dce87a01ca201f5808bbccf +13500 000000000000012cdd1996be2f29e14c0654b11476e254e4ba4c6829c6887ac6 054f36fdd7e83ed836fa5c6ca63ee54929fe3549b45da07a1efd1cbfca73188f 87ac07eb5721f5c903e1f30e1082ece5aa619e403f3267f3a4ce0d061fb258c1 +14000 00000000000000b930521b5956b17943d5dcf001b4d319ba7157bd7fee6a6fa1 80ed5287e00bf627a20e525cacd1b6ebc2077a3e2c71a400bec64eb7b80046f5 b11909221a9f3cb0cd4e5edfb6024d1ac49ada7c08a77c0ebdc129b05747fb0b +14500 225abc3eacd079cc0949cd8d0eb8978b5bb00720da7178ef5652e70754914d88 c87e7237cadf805554ab3f259bc89eecda51149fdff0ffb29925712a218f76f8 4daa8b7d1d927bfb346a7314e891a986bd793b17985722bac72223a15869eafb +15000 000000000000001f08d59b246a225efd70b813c3df8e468bc9d99d7d686fedc6 2ec038bb14816230448f041cae3a9ab64f4e237a53cdb0416dff8a2e062586b5 e874af931cde446e73ca568e2d367e777e799a4bba62573373d36ca7c7f00bf0 +15500 1181e59d86d7026c523659c152db3732c69e56a04ead32a0617be36ad3f2f0ad a2511b8ee2e0158dc668e0de527e71455b7245c01f41ad66e296118715aa33a5 000000000000009e8b780ae68208f996543f46c2580ea3bd12fb75d01093498c +16000 0000000000000015155b08a0f074b1ae3c960bb90e96549a16d0b3eb20a4353a 05409419f76edb4ecdaba62aa65195063865344c93cfa1e35bd41931201830dd b3f2857fbea121637598c8f7460fa13da33cd224af1373cabb2e6b2581ea0983 +16500 91d0e76a759d19aed57d2657cea4dbe861e849b57602a4c5c69028d24f795fb5 767a41f042292ccf2acdb0b91163b18dd6b59aae25ba60a8557a01f02a5db8d9 0000000000000078da7ba00aa57c04dd563cb07989d2c329a6913b7736ff9044 +17000 000000000000009f949c3d1a6eb1d50cbe5a3638acc49987902526df0d4c3eee dc090785300641d04d64f572fa7d645faa11c4677d74ff356bd8d51f50c0517a 3074c34dbe4aa0c81eee8b20f475f4adf1f31e0711057caa2394e46f3b0490c5 +17500 00000000000000376f6a1ca86680e16d0127507a1182507e502c6cb85cb6719d 89dd74d7a8b4f5ee127e7b4aebe54f4cb2c91c79fbc3045a59e5f94227ac6b12 b128c00df0413a021711fb36ca2fdc1f27a5357ca63ce93ff5d1b40e2683cdf8 +18000 a02b59af01d4fc762d8a5708b22be769b7ef651afa88ecada21eec58dfd53cdd 42abadc5ef27ee4c954518ed1a1e865a3b2bff3683baad8fb35589f8953ac5e4 00000000000000a77265a8b139651c098948666521ff2f23b494e78e1dfd384d +18500 00000000000000dc2e6182da1a35d916b98a4778fc35c50de27a770b9f63daeb 7a44c2603b3d31b23a607a40cd63f9ce9486a7a3de507bb26f6ad7c1e0e75466 0000000000000031466bf69a5d20f11e97c1a2f96bd3e77bc632924c589d32cc +19000 00000000000000017207a368616b26632bf68e16984c098be64d2fb064d3a2dc 190ef6e670cda631380598333765702648c55bbc0c92d68d3c2bb5f76bc546d6 6f2c3f758ce2e2ef7fca1fbc0d043164db325f4a886001d369af7feee1acba53 +19500 00000000000000ab3d7e8810b7ca9f8b61f630ec6e596ee105cbeffe80c41d4e 5bb4af1b5c912873e90a93c0d2c998b367768f05fa8650246bce8dd4e8b5f0a8 000000000000006f4d9713879fd57d7237f1050507bc3dae8aeaed8debd3bda5 +20000 000000000000003adb97f0d6976b906982f3272ae0d656e1c593406b05bae17c fdf85ac01a396b796ee5dfdf3c7869dd3f7eac36a61bc7a30a5c7e8a9c5dea1e 11afb3010b72d18ea6b84d2a33ef5801110ca44a0f504ce7aedd5f67443b261d +20500 dabee81d7aeb87b59d94c497ebe1552b3f5a5ee1e366ce64143e9fa426a6462b 017e99080b6064d5f8852f6cda7563f8bf299dd15370a64ac74f89f22bb42220 78c46faa3aae5ce7ca25ef0ca634750514f4a06d6c956d39b8cd3be8e68a8ac0 +21000 7b549feae0c08f58c44ece421b89b0626d15547fd1199ff172704a51476e17a3 50e176972bbd1528d333c01501e05baf97876b8a51030cc3dced40c1bfd852fe 1892435e8046922f475512ec827d870ee9f4429a0ba4a10a920e44eb7a960443 +21500 4d7df2acdfee2592ee66f6498c2b0de972ca6e0c8e2ab38eb641dfbbce8aca04 e10aafa5c02a56181cc6ed4b48ddf1a52370d95c99678bcf5fc6a106df343bd2 3a708e4a34101e701039b240614fcbea2f334a54e0bd1921257ce7a202635349 +22000 1f2cd2094e85ba89286a183da2b9135d94b2be2c5b3f31bafe89ab3f631c5791 b97f1ff53a6a11d6ad3b0ff270ed2bcf70500069ab5651b8466110d472a1651b e29e5a1ddf2f66ddcb413df0582977b27d7f4bb4e66b3a2b0ecb1348c0f54bc3 +22500 e797c4b4ed2720b494a3501a32a247f7acc38f526245ff89c8f148babbbf0cdf a5b1353f344534e8a9ef6365be58040355391297cde74c723c6a5465e39f727d 2602265eb704fb881dc85d8ce28752b8c46e2ce6ddfe6fa9c6303189ee6be09f +23000 50b9f76effc822c9f1051b1c0ce25bba6112a31d32a055520d84ca0f1fc39b8c e12e33c6b273416adbf598ccec93ce0dd6a3fc817c6f8e4753064e9ef78e89a2 b1790f4379c3fc9ed1b2a9429ee58a7f186ea7fd2b0fad8a784f4f7d2f771e38 +23500 fcf644a9930ec30bb933cc37061a17d0edc29bb16a04ea4bbf8b27444d442415 d5a23580de1505a7df77130fda147aa774abfa1f16468a55b542f69bb6199019 f670d4586d3b84f836bb9d6a81dfcae930072b3b4f665a2ce6ec769b2ab4b8a6 +24000 144f4d11b3a867d17560ef3ef04362efc715c89c30082882df0692a214cdbd75 add23a1feaf6ae651d6d322142bed5998f2d3345fc767082817ca86139d2de71 231d9a803ad8076ff5c2039720e154723bf6673a00fc6a44841b8ef89e3d4afb +24500 8d8fa5a290cae00be37053ee99cf2ae70b37b4806b41575a09b7a948545215eb ce758bf937c83d93671078985a70493b6bc1ab33e680143c6e93c2c5aa3674b6 3257b67e00dff0255bd4a03e9d09ea6400096e44320ce0a7f28a4cbfedf47d0f +25000 b5c67f326ffd5481bdd18f140c03ac34a9d467bee8116c7a559a8777c688ee18 2e618ba056f201573ae6222928d56fc3321a3b16c32681dcba8c07587ce581b5 c7cfa101584cfd837d9c3d6d0067f9ebf9ce8857abd0c508e3f1cf7a25c1970e +25500 80d41cb90ce050cb9db84205aad00db5761a465b000b8b3a74bdf57e7bc272c4 fa5e727492c4a83fe816724e80c54ef2add090d60c3fdd788c44721b67331726 5e151a04afa93b9e1c38040bbcde89080e66dbe99409eee73ed21ededd300d54 +26000 de58126ac82bebb58f841f75602b4307ceafa0d9aad7271567ec69d734b3422e 3931c58b417157cbfa4e990ceb75e8f2aaef945922962b671c17fc9076be9c7c 31e3b4e3c88d910ea31f6ee7c23d5fa185b43aea4ec9e18fb210882a3804df6f +26500 857f050c1a4a323b2f9d808bf2da8e11a9d691517cb0189ed2f7f103794bcad1 a7ea3d0c368fe526c8a1a79c9ce3b5cba52634c324271b3982c70e2ec1698800 540c63627ad9dc26a6cf2b26a739404e4d07e76fe8e9a2cbcdc8bc18a60f3d23 +27000 43b14fcd1424ed78b3cf03615ba16c8fdb53c414e894a6fe555b5a0221053ca9 6719c5530a1c6579dc00a6d6bc26c59900d5437d4bef8d03fc47cc018937a52e ec17180090117c4560874b64677be3f2dbdaf6840d050887f719a16338d1f755 +27500 503b22cd2997d3ff79a7857530f975798fe48a3b46bad0a38a3f83653beb8d1a e013d7f398f337d83d758e6af4eec6ecce14d080ab95f037e8c4354b1e4265b3 e2bf10a3bf1aa3cd6ab411d8eb2af0d50bbf21c7ca24a4e6c873f4d14ebba287 +28000 85e03383bd64b7cde88467bfd7973ad219d635708a69f925316e958d524c1b2a 112902560ea7fe15351297834affe49c0a8e768b587d1a8e6574ae89903d8143 e04c436fc9403ffb3716e49fbfd18cac060350742ad2031e07af778b5dd9f847 +28500 57c1ce655a20e5d4639e934776edbbc5ad099c383b62c7bfc623368a2c3368a0 c3e03e5754ed76153656787b565a0143d538298277c55ac0ca79e99b0ea134ff 1742f2919898d186151f39cbe3adc53c7d3bf3377674af4bb27eb3aad00c54f5 +29000 d9963c1d22e68c2492bef7a33f34bb7bda7b326b4256104ac1ef7d6421862c5b 91dce271c5fcec2b60e9e9a7d1670f191be7f8e76d3d13e75eecbad77dce8173 ba82a0879da29a77ac7e402693bc183897acde32a327066933e15b108ad28ac9 +29500 43f543efd477664f84ee78bac095d5413449e552ef90204f79bb8463ecbd5e89 4e93e04161f98d745707c6c7a85bd4b223f124c6dad64aa7080dc612526329f3 2ff134e1f184f488057bd12cc4482364d1e15da2caf46c65bb924a05b18f1fff +30000 23da6267be7a1511a4f9892875bd61bc1ae5d1b35063d78a7a448379db07c40d 760c525285ec0731ff71deed949476248fde392c8bb15f100af786b7d7e60642 949a3e5c3fa9e4347e193891a994db3d631577fa519243b5c6085ce21a246795 +30500 199d170a784a96d70fd6421057653141b423cb730e577bbe490c4d9d5b31621c f836756815de2b187d68e2729bc667522ac6f00379759c5a7815c728d52fdd6b ea22c401b1a3717ccf1ccdacf25b41b305d19e1d109a9dcc0e459f7472268464 +31000 a2f6774be3decd68c4fc0d55249a61d73333358b03a5d7f48f19ff53c6eca193 a72c7c5328570231dfa7e3b7fb68ed42e4b4f9f4e05505ea4526779d279b6045 a51ea6dddb667211fbf69dc697d9061d05448d3c9be461d18362ae977c8db721 +31500 ead2b784815b474f24a12e57068086c7cd2b59051e4570eb4eff43c00079120a cdfb920e73fa2ab6278a84292a23123bc921782c7b9648c137ea3b5d936838a8 e8b8f3d2f6c037a46a617533bdca57edb609ac7526b7f025caa96b180025f4f7 +32000 51690f90531b33b61489e34c805c7d1235708691163d0b25a9afe161b5bde918 44ba77a723c883778528e872d4cc6779c6485e4274ceb2ee7c1f219274c74297 9a85fd835a31d057ade3ba18680d0e79a328b3632fc16a302cd782889f52d193 +32500 b8f881e8f20864ef1db26eccd81bc46ce2b5dff8359ab86cc0b915bd6d1437e9 f390ac467135ddb1d88617c29db574c34ee51a4a79cf041bf7444c522229f8f5 c4c06a639a920b8f6b788d9481f45d8dcb2e5284127837cf52edbc5447a22903 +33000 8c8c61289e79ec3e22d294ab824743c29194740fca09ab44d460291599a33186 24bf35eb0ef662470b75fe38c332729ec8cdfa122a52be3d81a97bb9cad009d5 01cfa5ba001b9497b25ba9226f0ccb17f24d7e948d384ba9bc993c4362827dc8 +33500 958755e9cf4e957d0471cfbeec0913140759fb3219aa74096c26cba2536579ae e88ae01956031b06310eb260b95a76e2e4e9b66d40df56300ecf108cb4579c4f 095cd89a4e4c95283fa2438c6d031ca1b0422816f67168a499f5bb3320c65ede +34000 d4effcfa7746bab24f9c3d12bf94680770ecc8405b5b0a17bfd0b33c2f4f475c 9e5f3f87097c229ec5011c8ce05cc12a81dfd166741ad2762a0f156a8d3b3928 9398fcc470c7c81ac2160660b5dbbc134e4ac35b60255bfae5e07a4635224000 +34500 7f971e1a0d2e94dd8cd0ccabc451fef38429ddbf2400bd45278fe000210d5f87 8b08d83e6bebcb12ae7b2b9fc1de91a0566ed33f2c40125d7810e2a97566a28a 70b251ad75de6ab61987951c3d5cad249ea12e6e820f8d935793739cad30d4bf +35000 90e4d16dd67369b4b5795571fe0cfe63be8c1796ecf5870cad20798a752d92f2 619428a018aadf7a144b3981ecf018bfffa7975819a58cfc0e16f9ef0ba274e9 724316079c231a8a8ac11edaa2652aa127160a355df35b6e8ca40054b29ffc75 +35500 03aad5e354d5019e2cecb5a44c4ab79c7120543370cce9830b1d41590a59706b d94a9fa2f0ef62b409348c56bc376733e50fcab89ecd7fe711845f66c03a8409 a153f111a3d9d4d98d06f1eaa3660efc2ab84bf4d8525e7c41cfd1f1cabbfa22 +36000 5659c47e9c1b006ddb991b7b0163777977d04d70b4b52f4e3b87bc3aae6fba2c b1cb79822ef346bdfbcaacb59b7a289bd07b5cc02c8c6f9c9b1c5d27111c892b 7daa94c5b2e044db9e991868d953c7df2cf48fbe15bb04af59916a6f4a444733 +36500 166c22d2278b5d4960af665a6dcb8c4718ca3c489fb12f6744a60337a6ea4a97 b55d2820c96584bb049d4f57766a2fb7b21ac2998038d1dad3c39dd553309a5d cce95178fe08033f16dd7e6bb1f1a57ff8aaca69441747ac339cbf5c6ada01f4 +37000 0c73b35172fd5a08dad4570ade1ae552008a801be8f2df85e52ae71957cc8bf1 66fceda7365584ca4e28a192d4716cd0bc61da166e5c6036bd2dad1ba0f034f2 75bf71b04fee9102f680ac069773adca193420ddf477af36e71dcafd129c46be +37500 e25729880903dd4f6562deb2c3e076c00d29e08e9c531518b2920b3e747ba6ce 886750b60b53c72b8d9bd1cf744d74fd3947ea62b878fd186618a46f1ae114af 21c5623b70151d13d93303599698d825c9fb8080af8c74bb812b086074287297 +38000 fd1aa8f0791fca7ab540a37b8fe5a6a23a84d0bf372ee35d6b12fe540b53f746 3bb81e40ce808ad93fd0057fe4c8c111478857f8ee143a27383a4d64f7c9cce7 37daa6c75e80010969a1c65d80c8eced5080cfc70b3bc023e90ae0789f458cad +38500 73dc7035d76f11e288a04b87036996efbce8dc6233d00a1238f40ccd95a4ddc2 b8f0d99842fa481e5b0e6011ddd8abed25c9073b259e37ee7bf2f451d4ad2c92 34ccab36126ddd68197efc40b27eef83462084a914f61953f297b14db3460f8d +39000 f0e3715e1a7b82521f8d39fb490f261c5b8684008f5b52fbca7e5f7b204ddecb 2851428725cdcc924d42f907200a50ec708342cc1025ad035dbd7f84c0818340 290a3f59a71d2af6b93a0c00d93fb1852b1d564d59a4766be690c0c85769ebfd +39500 16693e3a20a6c2d2d823b7c3020af1a20d555401ab098f94ea8a83b7a2a9af4c 400ac0ebe9428f526123f90c8bccf69a6835ad322affdfcfda314ea795e1a1b1 24ceaf357c22d83a9a66ce1da14ae06e18bd1271b5478f3402b64d60d848a613 +40000 fbe5242823fe378d36335366cf45b3309e8fad0df3f9dd542e10eab3b7a296fb f73a533f1c917595a88ca8058bcf54b2d8e3c8cf8c46a165c84ef124fb07d15f 2c4922f36ba63458af37d6ad62138ef67479aec2036f7224b131899b72536045 +40500 448e82eebd5d00a7ed11123f43f8ee955790cab17cfad0fb4f1ba154b20cd1d4 f6c092a7945bdf4ce8bbb08645a349b208b054925376821f469309fcf46cb4de 9b365c24bf635d86b8e0506e21683ebb1c6f588c6f3dcbd22b4358dfd2bb9581 +41000 42e29e0fc3e8fb2c517bf4b7d24175f7467980d793bb18d4b1903fec0292d0a0 b8d88a3f3968b88b98e51232a0304506821c7c83f405515d2acf89a6a39a7048 1d10fd930aacab4a063e39d302c2f8cc041cc1bd1591dcee998181970c05bf5e +41500 fce90b09826a8120907462a95aef4b8dd9487efa4b0b2cb7e90a4d6d3d40e4a8 2a4319200375bf38a272bba432cb62054c4863db024e4a30c5bd20bdd569b939 fd08240c46d9c5424c44850720b857ac2f3ce88e509476d40eab2291f72cb232 +42000 f0815d389fe88bfbf5c361762efc5bd1264dd9256bf895b8dc6f39128e130154 b26d951f8be8ab9091f1e6c56a539d1d7a01b50c265ae1c025b698f3edde5b6c fc414c310ea4cbcdbe701ee801c384dbf953c002341efb9295760899ec66ef24 +42500 97171a32bd838c19f12586fb03992387b4b4c8d1342a0ddf3397e44b7c9b432a 04737e3fefb938c73100a32ccea93455aa0a564e41e608a1772ffdd2e0d10033 514d6f0e769246a01deb8043720d9ebc343a30061dff74b8c2931309ea70a177 +43000 a1ae4df09a7e3f060a6693d9bd75af599a658f501b0a5583442aed2bd0393dff b6290ff23b70623802b15c12dfe3e19111ce081bedd2f24a0c6b4ead9d8989ba 49730c987540a895c5cbdc00a5964f893213269f8086e01764bf83d73674a4d2 +43500 85e2d7b7fda1433ec964d4ea6cb4fa7af661d38f761877bb9b0aa0acead5e437 8dcd8aa4dd692a271a4e6efe7b8314f2fc5adc4b96bdd932e2ffe76b496f1347 7bde02816df1ae3710696092c464b82d2d6948ce7268f85b500f2fad7b59bf49 +44000 7526450969b0254a66686dd28d61c10d0bffafd0bbb623d0ac71f6c45048b195 7c626106e228c853ba6d6c9d63f934e51661ebd7ecaa02d66608bc2f1da0877e 6ece98559c2f3e6e595e5650230092cf482f3362ce00a0b5a8a598a3df11bb2f +44500 313c4a7250c92bf888dbbbe977f119854876d877cd7ebad97da3e793e4167084 e1da8d161f08c6e7cbff74ccfcb80644b571747988ada991c4982625e59d1a0b c6511fbcd73f38d607677d10f5ebb270b78bd392b83907c58b4a44e84477b859 +45000 9fde3334234a707dee9c6a2e3ef6069a30c0bb4293555f59ac70ec398c818e94 987db78e383fd57efd0a1b0b0b8fe38c50dbcd648da9a1eaf5d5f59d0c15235d 5664ee540251229a71cd2ad5913a8a4e8165fee2ba960a4bf092fb3dd6623856 +45500 30f5524584e0e3016ea738b1984cc7fdbac63956d6a154ac474ff28c873eaf02 2a6909db1ed2d684bae8cacedac0453a13e37ef1485760b0ef6329228a71bccd dfdc3b0ccadc42a812d9777a6023ef1dc9143c81a2b1ffa11e57743b96597da4 +46000 b79943e9ccbd2513710f58b3a5ac822bdcd6f390afc8258ce7fa1ea6822daf2c 1db10c590ef1fb219c3b98c707fa294e263bf95a4ad26c2c214ebb19d4236297 7a680be9d04c8bbba564af82f08007abb0e3528c35e5fc3cfab68a69ec47df76 +46500 9680afcbae2cdf4712605c9d592ddaeb87f9e8c522c6b5f0beb219e71de389b8 75ab5e40232ac575b25c0b892af025d5405aafe1f808551e7bd33abdca9a86cc a625bfad95b8b109ac2717201cb5e5988418cd26471771706a797b59fd0be320 +47000 1deba95895fa7fa09760b2b6f12395e6a40dc7ed3b14e629b7d85875e6913eda e735fd2aefe57540d02327e774c7069d08a3ec5b35e6ba939b1609d98a29a245 e955c958f1444bd9c6f6ec1f3c081bc37e2e4f8bc554ae806df4570adddd04b8 +47500 400b71a80cf5c7a408363c4a88a6f17b9fee56830f9639bf682cca7f6a1b9ef4 179f44d13af45605ea60c9fa6e0030b5de6c274104649283e5929abda3cabd0b 7e15cf3d27b7fb311eaa8e5be6a16f66df730fcd917206b04944bb7efbc0662b +48000 b62fdb21ede8c1760346b4325be6d08852ea3944fb0adea0b408742977fe122a 8ff82f9540381a20ba68681f6e5442df8852cf38b2476d0a6bc61162d6eeabf3 f9590291e90b1145409aafc4b35b003c3226a54b865299168fdc55ad056e6cae +48500 baf6f61655d7a53726d313806841300c1d729f7206f62a267c1b4c351b365763 fde6fd7055e1f6e03b9d327b3c502fc02bac00738ae0fb079f128e2774d0078a 7bf98929914e719c43f044b8bf5bd0cb23c1dc197682fd0e62e517d426cdc1ac +49000 854ab5b99aa89fc7d03f0b2d7f8a54aa7c98b23957520ebc8f4e6305902cf2cd f39213ce4a4fb7c2de3088ffcef3712113958562638395dcfda8ff6da621a09d 82dae721c7e522a846a3964961366f428d60788ebe25f8f649ecd605fefcf2c1 +49500 c964b7057db84d6b9282baff7f2f09dd72fff06dec110201904bfc3846923bdc 51261dc44b1299e50eb364ca4d236b9b5074606928ecc6acae0eec2b6352376d 39f54442526f11b0c232276a00372762bd2481def4502b9db2413e0ecbe42ed6 +50000 fab7500f5f0b1694a9c65a4b02e84dff228af92fa447d810200a3b14c35242cb 194fd02a69a66e9293a06d354206757e2bc23484e3e8cd80522ff71feffbdff2 4da797c00b7fff361aeda31e847b2e8675c4061d1cc87e02a040c7ac34bd198d +50500 ed4e556f251680672e442c00cf6a48f3a787acc589ef3e83019851808ffd05a5 b51a4252fdbf12378dae10ac1c94690365e096f786feadb8e75cbad87c8f8a99 5a366c4316e15730fdc118fa8c910850d3f43ab2534023892dee2c1834c4595c +51000 2410005ccfce88835da97372f39ba6708e7eb10f97a4428ba2cd51e8ee87f7dc 64e4a8d5a545ffb1af7a5dc66be6ff2aa517a99c7bc5d7b2d1d1afafc1b93a84 574faa5def6045f6a923539b36bd27d5f92fc7043c3d6fd783cd3721ac604c4b +51500 ae13af1cc26f53deaa57482111239bd24f99814dae1e01580a1957f11aa49a63 4a0c54d391ad8bdc303e226fa1aca24cce0ba24370424396bec9917804f0bce7 0849cb255103b5a13e30455f5666a79873a4ea09dd8dc06d628f2812d8460133 +52000 163e369cecd2362ecebef4717e206124e3bd47dd40104efcbbc8610fb48dbe46 3b68edeaf66e8bf1e1b187fc0a5e0424b6cc896661e2a4f44882cb060f9815f9 8ef8dcd02588600e7235ec512d10ac2753b1d0d9bca850de6479f20f678757a3 +52500 c3e5334bfa7c8d5d577b1a74df2deb553a006f68b384ebd44eb7bdd7aca3a297 fa5cd9249e7b39e2aef8bb19e83e214d77a45b4c67c4504522f94baeec2241f1 c3208eed6877bb901a5c104dc7f6829e8f21d26381f04dc9913cae3354b52cca +53000 3a790689d0f51fe7dd6115b7f0e5f5265a3aeb912692596d2611050a17795705 23b602a52f2e393f2cedd9c8ea0597931f6abd7b4f4f1d85f1de8d6382c03ec4 22e3b57a04499e2821002a0e4bc9e81bd4f49b0455ff1a369a84317b53de5e8e +53500 70a1da282b26b9dffe0b36a6dcdfc0c4bf218a86164adfbe7df4cc9c0b978969 f6ffbf0fc14817b41ce42831d14add2f8ec22307e5b6baaa9f07dad06c387e8c 61244a97e0cea7e9f539d0b93a6f2b17be206a6191da6b96c6c8bab82bfc48f7 +54000 630d02d2f2a8889fe47a4c2235a60b2dfd31ca78e487860f59d24637a2032af3 901287c9cb47c082b5329f422d94e71def436bd0979e939e7def8c60f99272bd c17de5403465843f5fc7e06ea68b3d45632391503ba6c3e08fef7e307efee627 +54500 4943f865d3e75ddd060f8145558ec7f57c10d186b3bbd3d90377be4713e1fd22 26a8c618d328579faee0816d1d723736a249dda1e95647ce7775b0aae5b72854 c55e2330f03cc18e461c27c80393abb8cb22e02809d2381e58ad9f72e44a576c +55000 6e96c77b0964fc2077455aaa2067110351212e2ca707fda778c963fbbddc844c 350612a0426a630a0b001ec51d875e2d1c87d20353a480539e5fddf91cb3097c 818a9301476f02887da2af0daf9e7d06ad8b2129957706547ec766937cfa844e +55500 cd718716c94cebd61eafac70f8562db8b48735765a8613aec79d901e0c5a05e6 234209073d425564622dfa5268e7f2af5aac71a18e2b15d23ceff1da4d876563 aba44d2b14d211b90829dffcdcbcbbd7705056e49f671290cd160a0b778787b3 +56000 04002106ca4da32c5c7889c8f17369d23a35bce62a8196477c8f8e0e0dbe4efc ac25f2042536f1a588ac6747b2ff3b45de9aed063b096ea59632b3aa45441ddd 5ff02cd837efbf14a19c5a187db83c5406947178bbcaedcc4d1ca99aaf9e3796 +56500 6460fc580380db980f3b76e9480b2dd98f4fec5c9642b211f7258f50575522c3 12c289cc82037f732305d895742cb703eaa35a4656faf84c6f7dd9a2783cd2a9 ddfb3a3ff60a67bc60f19d00f0c63f1e97ef355c74ed1d85fbe4d5b1b214ed1f +57000 7f1a59ac62a06df2d3d82226e03a1081fa9a8c72c5333ba485565f9215423362 5363e6896a5eac3c62543b82b6260a18b07597b5963d038e728a9508ab55b181 f0e932ed8ab5fc1e33872aba4976166e13b6d879d15dc3c87be2080ac8914b32 +57500 88bf14d568f5b9d8e88d27a92f2aa97a569f371850be3d6d1ec175fd9e1dee54 56aa31dfeccbed31839cc2399397a826f2e64a16c4fd309ba87ebb2ae7e7f695 015c08dd60a5eabf977e86e7e037c946299fb6cfea812374dad62fc8f8dc198a +58000 0ab0e582e675d0ead1173cd65e71157f13841b22560251a2aace14ca86fd66f2 bb20d53b616962e78610b02a60785252e90c54d78f33a3578172cde77075a776 9baf4ea45dbf06d4508012d7b02fbfc4b56beadac64d579d65e86b2fdbfd9093 +58500 637d24d3f5e56f5481735d0853d74cc85c170dc95dba4eb733af11ec3ff048d4 aa8d5505be6a30af2a0292fcd19800b0744acd87634bc49ce43b0d767117a5cb 1f591f7deba103f980059330ab5579257932772930da3bd5cb92c4ed3a2e3d32 +59000 2d88b4676741afa7b183502fffd15bb1580f81b4b8631844be86bacaeec0524b fe841a70acbed4f52a83b35cf30c0cd5ad38b36b21b24da1a0ead110f5e7b2fa 40171cabf3a46be3a3987f71fa7a969987191d9f53316919c098a4718923c4e6 +59500 e5b98e82ea2968293969b1da31bbb8e30dec3ab5cf10308d4a979e3264513bff 17429be3ddc868c9e3662b5aa6223340d57b7284138db428c725c8fe69e1f89d 4a351a969f3b5658c5ed9d91bd474827765b53b8346b4832d1dcbfb2f5a1be4c +60000 98764fcdc2a2f8a740a4a1c891ad966b44062f64195effad2ba0aa4bb9c4370b 55053a4d083f019f602ca159faef86ddf421c4c4c3bcef9f0849f45e1f8c1c44 cbe42ad4b0adeab094db6fd8374b6e3d6696664f583a8720ce1bb15650cb9647 +60500 24bdb847b0ae121363eb0d2a7ab69d672627b4d68195fee18df5ab5c076ba3ed be197241a0c377fa6982b5c24af043034024f889cd3ebe42d4a9b3fa5dd18953 a2955e0abc57b88a148cb41f22fded072fd04da5197fd62677951cf86b73d9cd +61000 54222686316d912f144e6d0bbaee1b3fa50549e9da65ffc21b04c5beb3ec6daf 6c5a388a8dd7f9d104377e1f5b2817b50f9269145da48dd0d71f48e2af8b8731 b8a43a400ee3bab44c6d5340395f0e1f92d394d577fbfb58ed7bbccd2cffc10f +61500 f14bee1d7d3830f8c316f448ca36fd0591371a63fb9d04596c657051ab4c2ff8 86c9232b738073c671adec011771072c92ed0616c361bcb6e9af6074d09bd6ff 54fe8b0e5998f386356388ef8bb5454e1c2526ebcfae9b677e08f208f678be56 +62000 5903eccbe3d0442fabf30748705e88e9cd83128a0bbfbef66841f590b5011bdc 4de78ca5e16fc438337a8d5f7aefd2cbbc66790d019a1bbc5de082a79e39c303 8a85e0a258f4cb99dc4f83cc28a30721618cd33fab70ebae4695c5c097debcfd +62500 35db59c0b059705518e07b3beab25716c9fa347a1fdf7bfa0089d011e2586419 961e208bd356ecb07f838ec1d1cba0eddd79d5e026ae350f0945cc321dec970c 4a38f7b73e53602754a6dfa97d9ae5d289f190c3cad7748f7879821d204177e3 +63000 5fb6db58962ea9eabcc50dde4f473a0adf58eb9a409665d57cea3b2d3d2f44ea b673d848fb79ad142be92514c27dad64fbf98d26e1e4f5957376bcb2f8542288 9056ec83e8dcee1f4fba1482124215868e1fe542699560acb750083a63f77259 +63500 92e31a33e15bb677aed01f2ed669a2700223a34fa7342270275561ed5b88eac7 7932d5bdbb9c2fd7f172a79a9e93f73aa3703c284afa98e7530ea4ebbb4ce7fa 471d2a03dbf58e74f50681d6dfcaa42b2fe579c9669b40fc7f0c608d99744e5f +64000 065c7297e545fd1739d04c6ed41da4a82a24404c7b3573bbacca0c266c4cb716 912632c93e91f5f539b2f9d6ff8b16a1817c8eca88b6d579dab56bf4d48eb31f 45cf6e550b32597e97193b7904c3c8c4fd709fb9fbbf00bcb178393d4b0071bc +64500 a011434ee029b50acdd49262a91b0767a897a5dfa7f5c22dda0a32aca9ff334a 37993dc2223b292109f02e9eda7db4178f6602aae957b80eee7cf94dfdcbf020 30367b1daa375bc234f8ac0495facba100246d643e308ce11351a9d090e23791 +65000 5144e900145e481fb1e569b1b522143348a38052d35452dc7d97e2140b812e26 217530b550c589b0de7d145fc8b1059215bf5c124be7e79b5854acc200b511a0 26ba9b125f161c2d53ab6665f343e060134303e77dba1cbf22a9822a59cc4b87 +65500 6db49e04b2c1ed108caba28d4de98628fc786f5224b098de1636a697ddbd6e6c 5cc92190d39119982836cd5b0759902c4c61517aebaba16e6515cfca53bbcba2 0278b2431cb9eb97bc1b003994e371f9bde5a602452443a91791f1ebca9406b4 +66000 559d2603be7835ec386467221e23836803606f7fcd7068f6a42ac5054e48fe88 68c9698e2684c3375d6b4d83b33155e15ff1d50aaa0fe61276a854f7c022e3c5 13bb29b335c2c7d96c2c1ed7a7c797065c1d9ddbbddf5ca63836c903b799f23b +66500 d724f78b706b6a58400a729586b050fcbe843a3e632376f24db6fd4cb9a44177 968a75dc8e7e9128b5e7e00b22a78fb53553102b54247bf644247546a9db85e3 10ccec92a6edea5d410279734abd7910dc5ac0c1e15ddf157d814cfc6d6777bc +67000 8ddfa37cf395f7b4b8d6d09e29cb7f11e7d06f929d7ce7a77ced27c79011235b 9cba1d323704f1b566fe4b639737ca2f6f96ab6f9f1373d95e1d8cfef0a0a1fd 58670ec690d41bc890ae2b8238cd529068dd4a26d72cd3c953fe6c503b7b601a +67500 2c5e2421936073eb47199fb03dc0023bf42572f507f484fd9181eb1a862e8972 4928ddef10d983dccfdbcce08743afe2a0d1238fd84bb4b6e1781ca7847d6ff7 80c4fa7ce15230b8e68ba5d72eaa7960d34f8045407ece0d3b1c4b31eed2c00d +68000 cf49fb97e127593bcf3591390401803095f71ea86922369e573b1c6bf59ca692 accdaba238ebdebdf85fcb74a46d17e5c29a996e3f1be6147a3f6027a13c8412 0e50686f415f26137166d657c217b547dd943539dad26b19bbf746af7df6d8c3 +68500 eb68bd36c8212efaa20bcc2d1c17f17af6ce65b060ca7ef80dec2f44052defcf e04d8a45c474fb6ab8071cadd8fb14f5d208472089f6a22ff5c04904f7a01d55 14da49cacd179812640740b70aabbf5b3518447f669024e44e0d3c49fff50e1a +69000 03609399659eacd9b55c608e6f35195530a35358812bed13782f9d5df5da1ebe cf4d7449a4a7aebba820fc84f3dca2a48ada14feda094a425833d4a5aec834aa 41ec9e81ab7bc3532110cdbdc77b8b8e7827f0302b2e53439d1e079fb6a6e63d +69500 1d23b15a2484a71d270170f32918f36fb87e80cf4020f6a3e6d61907276fb3a5 2a218f285edae9995b3334352864684c66f4a919c92031ee3b24510b568f6246 16ebeab13ce1ce77819913c4c6866628c4541e3548f242a90f2d034fa0cba0b6 +70000 5667dd2604c90cb15f49a75456b0bcc2a0098bc025592d48379f4360844b79c5 1b6966e82886048d64879d2b76663fd70689c7dee808cb42352f57af598f9bca 40226bcffdf6f4ca816a09f4f8b19ab1fb245b506648ef481dbaa9f0f3c78a92 +70500 745715d010b5ab51456342b8772a53b95ef0cd409980df39c443531f2f6c2346 a1ca05cd11e6f3d9eb2f0498b8a4743defe546c7602c3fe06642f0226cd22719 2d34067c353b61a32c8c6231f77f6d50c4d95598cd3101532a3a02e80cda7113 +71000 c622f3d2de9a6aa2d649f10532164082ff6ac21da796b037f2b2a210fd2910ad 3c24535ccd8328940b86980f1797d0c4e0dd0fed2ada72a0d9ce7927f4e3b040 0fcc88b5927ded864afc1ce561cb814d9e26a21b053ff81e7201cb06432b6472 +71500 c4350561b063c19326afb0b38b7aa70a65a928ecbe3a545f26f1dfba40d16599 7167266f09bc1b259fc6dc6ddd1c4e03514e4b4e5a985ce79cc320d80f376e9b f6e1408b9924b633079efcbf87a6d58ada9b92de902e1cf06dfde2aedebcdf8d +72000 df857691f4e2d2ad6a7de6a3fd77cd3e1ee19be220f7f92006e30c4cab62eb8a 1e962f15a4472d511bc049be123041f357376d95df56677c32ebf69640fa5459 6238d0f58374c120051c6df5ad197884fe673daa41fb9744ad261e3b102be59c +72500 affa0299a9d64d61176179cb14978c6dfd116b0350638b5e2633c5a73bb9e5ba b04e559b1ff6d04f2fdd2693c384bc89f05ee28f5ba8cee49cd057c575b0acf4 a19593b0eb1c2af96cc2b8d2a51d1dfc01e8f3199fd034a3166d5f2b3744b06e +73000 a50964b3523aaffcbcfd0be0a6fda32ceb87018450ad2ff81f1ba61de5fa20b7 e3301d1249deb8b1065c59ddf02c4480af9208ca0fe70f0b94f7135e3baed857 925258df26bd35c53566a703ddcebcd0736a83c02febadce41775c6a749e1ccc +73500 629acc1dd038725bbad7598fc49a7178771332ca4f12372248da579ee5dbbe54 8d2425646be01e20cf3554feec43cb91bdd92f0a6e8791c7f8fac4d21767b45e 0cdd774880e4510e46ac772c74a1d7e9489ec661e385ab2a30c54d302073b69d +74000 068954a253aa54239a0a4169f50ee7d37b0b5bdfcdfe9719ce9921a5917715eb 722bb617216427a0cbbaa037d1234bb7d6765707108aaf171cbe14e24392a8d0 a1d78d4187cf5554867bbcc68949c2998037c4be0a7cb3f3b0e3c4115089cf51 +74500 e688640c22b3c55fdd29e86a159e1cb665cb0937cd6a5591730a1b5de7c04b76 4ed22bf35c9c19ccb01db47714af7f2ed0a7d2506f40a5e43b92b971edf62250 9cf4fe5d63466b2a310c28107621a4e2ab34eddbd8593bb426f334b2bf9942be +75000 31c015b503c6830b93948a51598beefedc78d8957af82aca6ccedb2aa592de8c b75f99a073680d704089e1a77cca65d027722aee3a4fd7c1f9578b535150d5e6 b3081220431a4246895b22aad5fb257d09fd2ae1cdbd57aff483adf909a5495b +75500 3eb906d2939c3f6ad815a51421f488025326b8cbdbe28c15ef32ba410b7b8ab4 39ed4ea10fdb97d192dc03a86a397b24f6883439e7ff6e82d9e6738cb90ed5d0 112ca7210993aa0fc5581f7819420bfd74dfa5b7b9e2a1bf3e0d2fb5708e28c7 +76000 d21f08b186c4d763e03ff71b1ae4e7c07a9dbd30c518242740c2c93119d8d96d 3898b748f911a413cf66daf2e319b3e72ad25ceddb77f56a7de9165484405cd1 c3a319de284ca1cf8fe3b8ef075d1ec77f9305f52c9651610d383993213a5dc2 +76500 5c8f54cbdc2f5f83621da3e57c28d8e19faca81a438cb5f4aa144a4c037a0055 979a3726654c4e3bc195da85f13e24639650c2d65c460c91ff1b377e27a3b73e 520b9b2d18e11c3aae19fdedfd75036c9035e115b287396dcd53f45fe063f812 +77000 e5e2e50e27fe46845384682b593999c03b4848a5912bb45d22974cccb551d125 75be98b3706894389661b6e9c20057b55cdabfa26ffd74bcaac8fc01ba273340 560695b5286f2a9b5f3a61891adbd806476ba326c9901d89a4144d25730382e3 +77500 be8371eaee6d9fbf2c550f71e9b41d135201b8b4657b94e6660c908f239f986c 32b8f8fdb525510204119ba84666c0713d8f486328a98a130c166f36a2582523 20cece5da3a52ed79ca9da8dfc49906e29abb2fd13277d8131ff41ed5116409f +78000 2eff5feda9ab021f5afc380a7f931e7d52e7fe2ff3e2cf1ee7fdbde0eef82b64 65fbc737d459fa4f14f34704e11ecd9adfd51078f45626671bc698ae18d849d6 2864e1e45f74b90f0c7d05c88b86c31c0f6534a8a349f626fec3a58508814b1a +78500 3018bc8d8b545e9ec88e936af13fee6bdf3ede83f61d2bab5f723803e53e0062 7b2380f5e4d64db1aefd218b868cc51902a54d0a0db42cefed99c7e8de87a218 92a0304a2442f4c9695f01d26aa2e8b5d34146c9b8a858c53de43d87e466b863 +79000 b0c165f1302d8f19256dc2e278a7a5ecb99eac7c998306a50c8b4686a077356d 491242e8fb5fc40eb435f931bd11bc42428634a5b83abd1fb9f19059712b1ec5 53e79c824e8c366f63f1d49a454053093c4572423c9c81f23b369cc9381feca4 +79500 68a1ec922af3091b3f2d59824979ab0f53a92198465ba557236cd41723deffb8 fb4a299d949b55ea78834906a69ab9022a49d8de653310369fd8ba9af477b7ce b2e281683255d479875753fa7e28a8d4d18ff9e2a88efa3096ab74ef053c0a7f +80000 3b7489d3c34d0848f031a2325269daeacd8d00cca588b2b0155a81bf5bead1a2 9ec13567c8ceb32e9315afa4321f0a088d662f7853d492e8fea9aa0825f0c8ba 2df863950a969a02053217306182378d8cf92e7d0d20261970edf99ef4f81e3e +80500 a4bdbb1067263df39ae9c3fe98b7e436bfc29fb020ca4e0caedc4b92409cbabf 5d94d51295cffe3419841c9aa1afe3a281863f571789ded22dbee32e03726946 b28f04015449472163c3a2de60bc86a748344fc019737e96005a72b9cab30e54 +81000 ff01efad3f1d35001246db4167727135f57b0e2603185bd8f43310d2725b4da5 41766254f9700bf8590b6bfa6993eb56e866af75377438b7b7ec4aecff1062e0 4ca72d6d1f8416c9c1d62c0adacc2fa865386e2403c611151aa04a860aaed815 +81500 1e6d76e93daa7db4bef0b866414eb884b80193359343f7984cc4ad813f10a555 87b53a2233125cc8b28fa7fce0ed9d4030665fe83b9e63a76e545f7eaf332fd9 7020d3fb137061b452f9946ff2dc143ba7388863becce1b384a50481c63d75e7 +82000 f77522692699eaa7adfa876193ff59d445443d55389e9110c211d4892d0e4501 a283d883a0705d2dba7c61cb45d6019a7e464aaaf297d8cb28103358c12e33db 384ed0155684b2265e88923aa42ea92fef934e279d5c620be94078868d6bf789 +82500 ce6f78297eeeaaae876c2528e2620ee91005af068e45c079f16523772b1ad1ab f52cb36181b62da6142382debe8325153fa672ea2a82ae0f4f1f05d3945ab944 57560eca2d832e2ab12c003beeefcc53a73d9af27c28c8af087ccc786ad1bbe3 +83000 fb926dce75fe0237ca38f35e58a77ce4ee8be04da61b16f360b029ccb889ff75 28adc102bd9b8be9013e2400e65d2d57750e995bce1b03ecdf1cee59712f359a 65ea426980d984b17394705620f3b309b68fc832a60b8ab81263ac84269fd795 +83500 f41912c2e881115560d9b957f91a8463c082efd4b887d3a9762fa7aa70d7dac0 aca22527fa30f5d0e0a8f2505a12fad648526bf7c7a0012b2ea02ecdf55b6fa2 28c9c97c6416a1a1566abf837b74612f3345849f6e0d20af3658eedb30c246c6 +84000 04c39ca3103cde71f02315b339936f58cb04aafe9990c46326733493897f848e cacfdbf9b2ae2aeee8bfc355d807badb9cc02835889a999e93c14ea7800d54c5 a8a1f5a1cc75741b3597b9371c208013cd2e8d98b11a2895ef40954a8ff9495e +84500 5f40a8c35de9dd97ecd7244e84a895deb4fffaeadc22ed8d206d303578471ad8 e1c2dc0617f6e76b2ab84179c8bbc55c46d9732c6952beabec2d14babd7fd9c0 f6a927e6e9c0f51c6819da1dbf55beab055f96c3732b6afcf60d603e7a96f232 +85000 b181b9521ee2b12c19c5db467c39855af3e1f636a4086e1c6a728e2b45165402 8243d308e207fc44be4180ad0a63916aef3877e6278d30cb6f795d463541d26a c0abd81ab72aa7762ddfb2d2476324f5237705d8dd97542242dcb8c3e4752bcc +85500 b010687cf83e100f2d398b3927659ca342b25e443147badc9be5f13331fde93c c635b1e609f40f3bbd4aaee0df1ea6b27f18094f1d00377f69430b6507012e88 c47c926b3d18f1f2853fd5fd99e80c0cb9075b6fb333cefa64a0b8e6fee346d3 +86000 291fee34f060bf3d1c39be96f5ee8cf18c625515947c5495775924f5702abfad 47e1684b5b4942e0719228e060af33e8f13389619e91925d58f86408ea149035 b050f83dff11fb334541f21aa3f8248e3e88b055d4017babd998ad01ddb57415 +86500 bdaeabf298427c06e09a2e646e10ca3d17056bf1ba9619371327ccdb3f72c09a 4eda2aae345266db3c1d7f8e49699c30e70c8675735a83972d0dbf0db2372c24 2bc18aaed2b179c27204b8846637ff5917663850fd453ff16ff09f891d0f59b5 +87000 8f8fbadad337ea15f63bc845e472d58d4c6467a516d77d08fd603ddb3b98d823 2d021df329f3c3bd4a39a5ecbae773b063f4baaf776f8ffb519b0fd4d803373b d6c50b050c32e92b6a9b462aec1fbc4ec26ac4d9ec9d1b26e84b495d66bf060b +87500 109c6f62e3aa5e0ade745ab3544f8d055d4ee1bf27d217bcaa0815f8b31118f1 1cf68acbbe94735132fe7929ae72e1fced6fc8cf569bfbc088a16c93c3e9e403 b3b55622d8f81f35eaefd008e01a33e2a78697ee655c93d24866f618836ac65c +88000 f46e00026587a254cd7a382218d9f2d61d37139d7c3c4f0ad76d35c76a2e8fd3 fc2e809bba17e3198bb92edc5999820f19a4d7135330b2f7b055252ab91f4896 6e1a58ff143797a81cadf49051e123bb3851028bf1a5ad1e8a41e5abdec89540 +88500 a048c5a363aaf55cee60a2a4286afc8199b7bd0d57d5e039027d3db2a6cfada8 fcddf7448b220764d0452dacea67e5a91d537830349e307fdd20763143f92bc5 0f39a201acad8ddb4f46cc03f59ec624d6d427e7c5f1180f09bab87e16cfe8c0 +89000 95e0fcbc78961eb79d44bd8e8055a26e77056036cb235779fe1ce22086a8705e 3454b0857e99663789646a938c33241ff00e4f7f853870665767bfe04ffce0bd fbc9e1b12395084723c96867f18d41ef6e09a29378ae5005f69d47595077252f +89500 8ed9d4f7f4c3ec8eaaa57d893a9464cafa4e2ea705756bc00c9b9719d51ee56c e836a5257dd6be6b167b7cf6c39b17a2433b07e86b2ceecc6886e57cddfa2a94 39daa73bdfac0f7653179049450cf01387713ae121500d04fbdb0bdab729ac32 +90000 bd2cdc7f05511794992b0ce31ee8d58e428ddf12874905f102d2ca0a37adf8c8 e182353321678e537290c24a2a9c09d226ecd91044cc139038dd134ec1ef1a73 68188008335cc99621108f18feb5b958e7a78f40234e29b59af0892011a8c2af +90500 a996f4865ec304be3972056e4fa5890baaa296db692f4442c5b0b7337e75054d 98a91f31ee5cfdf960e1fcda3ff3d8d058471e2df6db7bea0e3937dd09baf06d 89ecbedf84c494096914b7126d5837b8f98ff5594d0670dad7d0df04aaa235de +91000 f6cb4c4b3fe3b7365cd9e05f757498cef6da8eb0e6730f4c569bcd3700ba1d2a 91a792fa965f57abd8c8c95a37069682f68a3ad2112883779fd33fddf3cf7368 94b75f07a61e22e43490bc799ed000ae3b9fffb955f63f2bf456954cd395d051 +91500 4421ef207f0a56fe208ecf3cc145cefe926784dc163500dd5018585c6bc4c0b0 2870e9bbe0c6ae16f66d6255485d6c6c5c198e16b7a721c0a027df05bcbb46d0 2c313cd244af86b7c34cf6a6a96a330589509974a5c1066241653a241bdd2c83 +92000 eb18cde79b36e5cfb7047d7ffd72374892d294d97b19965f67c264a42be981c2 77ce5943ff19145cab30c4b25f762f1e93afbb25e284388f88b4078fb934db67 d488ce3cee93a883d773acdd624b1686b74074035544625f494a7790f7f62a86 +92500 2a1e0986047c363c557e0719dc464f44cb2a5530f36ead6455caf22579fa728c 3fc8941af430a2cbbe3a9e51ece9042410bce0c9eec2905109433485e8dc6eb6 059825226e127fb3df58e84f2b060d82472347a37c67c6aef9a75b5daa5a2e8a +93000 759bd6b0b243739d3d6c28227f3a9eeca8afc6d341d17da49751065ff6d9027c ff40f2c094d151ad356ff66fd39eaed507a78f9d3c4ed2ccde744d600d3ee843 0ec4bc2e42e2782257d1f79a48365d5af74e82bf3b4829442bee0d3210cd8b2b +93500 0c1648e1e670c38758befb41e8fc48f337f3b9c2aa8cf162c2856bfd44dfb4e6 e417032b5b7a38c5a9812822810148a15818047c2e8364ec0766a33cba25ef34 487bef320afe68cb94ca64269911d08cab750286cb79b06782a0dc27332bf62b +94000 66cfc1f322a9971bc39ee18125a9464b9f82eef9c314670e51261402e50086d7 34ddac2e7b943cd760ed4863497ce0ba2a723bad5afb6f391082f1f1603c5a51 790de15153bcfc0e6ca17c286ac161e548c2361c689cc1e9a725e1140b97877c +94500 0bf23f1c069fc47b2289bf52f8462229a39ace7afa517a43a52276f5cb8a0f00 6d333049619b2fa4f612c1a6bc8bf82ab8a7db7cbedb51a258ea1bcc33b03f90 dc932b2e5268500fe351bfd2759302bd1987faa6c486fd740e2424c8c911a021 +95000 1781fded2a4d5a2ab054b04de3935c97fd5f535f0bd109496aab9abbc6564dba 18990d4e8be1e75e4e97a92e16bb4fbd805afa2d419629a5eec4d46a269438a1 3ac8fee137a3e10fe18575baec6a598e3fb2cc7b1771c4044e8e079a3be7a1ba +95500 ac453fe6cbfc81ed0c9b32241f121410d4caae7ab57c62ef99e08750f2d5f153 e3c4ea5da181b0fbd82e45e106a9c3dde36c28382093708d8cebbb72d001960c 3416c602f3620d5c1d3b1dde6b61b75e90bbe01f46ed14e0a73f737a8c20b10c +96000 e464e4c5f135dcbdbe41de354730b1f633f00f458994d6ab3e7b272a5335e3b0 093f11b3784b1ef794fb06db18424f84c6a1bea0b9038666ac5eb0d36b18258d 4cc144ce8742ee482ad9e5e68aa7f51ef8de2bba485c4e7234cee76a87962477 +96500 82345f602aad0d7ff796eaddddda22958f4d3c9c41fb987378947be6ee12f808 f6bb034032bc77c931558568182e10066932b5326940dfe562048d83dba4c126 86c5337f6554d22573de1cb49573549633775ad3c236db26fdc53d91575c090b +97000 eae3af1d8bfe6d1c40c118e0c78bae2bfb1800401d532b63a3c875fd3fc8a24f ea34ca2227308ab8818f085e7fefb2f140dfe9479558e6dae8c0dc049e09765d 145e4ae1acc6cf254a5e21b6b002bc6f1eb0b5f870b80d3fd5215ccc3fcfe059 +97500 60dc3e9f055602d3673ddb11ab25d7c094057a0c71db2a327a491b3be93eb9a4 186a25fa3609da954813d575a4128ff890d571f0c003f0e6d62a6322279125a1 097db3da36ec7ac168d59915fd8dac8ad15e6d7e27273536d9d9c5f44255a44f +98000 5124c9f250499786c2948dcf5e2be2c7c61b446be3972adbc0d65edc8ff87b0b 7f5892932cd29e78d17fda5c3d15bba0a600f1e9ec2281dbaf0fb1dc67d5e8dc 102458513889b0fe4946100a0d8d3091f46e7627c09a5b5c08a78f2cef987f25 +98500 6f507567f549b3b1e387f1bf80ec0fef03a9a1af73147dbbbae2134d6d1633c1 60d73750b6ce4d508dc18cc64adc9e68b6bb7ea4828f09e8fb7419b56eb652dc 93645d925bd3d878b65cdee59ac3349db5af2325abfd0fc696fa8a2831d33d77 +99000 64999aa405a2a2e5de34a4c3547ee525b503566532d82c35839a9e74a1389ffc 20052d2448a28485dee72fe536fa8b6ffda1e8465af82491e87980c8f806c8ac 783113c40eca4f0a067fca5ebfb7bf091561cf6751c3e4ebc3473c8c4c5c6400 +99500 3cd60a841f4913bfaf6183237ebd325b7baee3a5992f092118fa49817240a385 e21adf8931f3ee5103fc1a3f8a92282e8bafa9fccd203acc2cb24dd0d28b6ca6 c43bb024c7dd0865bb95082f5864746f7bb41f9c7feca9adfd50856834b50d11 +100000 f0394d3c54a8687b6090333aa03f93f9369846e7c142653524adaa9192b37b7b a739c2cc2c59123a161c9b9864a4c834dfd5021066198f51fde3ba9348d195d5 2045168ef0fde83f218d83274f9bb7204356cee8ee0554bd6824cd9b720d5429 +100500 c5ad61c2da15ed8083a3d3dfd80d226b9977dc831c11e83b75b3ed68d2af0e25 e3121bb1573ace63889a3fb9305fb95857bda6e889e9a88aa2ad4c76cc407386 ccd1cfeb131dd0e478ba664886c27238e71ecfac2f3effe52e192ba370e5bb2b +101000 27c2691b9e3e9cc2008da070c0af12d0997c895fea5c405347496c6a37570f95 d465e2fcce8e1b4bf7355b4d87445d2557336354b86db40bc924752796aca840 982d0e97bbd8caa7a1f02b9b2093354bcacbac1d02836a26f15af92f5dd9c7dd +101500 80c3bf7835d6a11fcaa22931aae51bbc602af4412ee8ec0e8b96c3a9c7128f16 1d7c3e519be3686c4b9f09708e225c8259c5ba6647fd78653b387539f58bdbdf 9d7dfc1f142ad98c262face14a901620f92eaefadadaad38516bb5c7adc9eceb +102000 52bf59cb7e10047df152f35bfb683611f084d444aac4301bd0284d3e458b6022 7c8226cd17af258fd69631ce4cfdf204dab70dcf93bfed953d6cf488d576f56e 3c7c8a26ce9a97f67d1428e098c42ed2afa0256e0d5eb226f359e7fd562f2d44 +102500 5dc7c42f2501c79ca5d610b8b69d408033bf0f7d16d036bea01e90e6c1ac9342 403edaea352b4da33ec3269ccbae23c226a39961f457e5d3f84b806e517074fe 3b9710ebfe1aae2e249cd9e7ecdbd09fed6b067b5271e391da4ca5092ed8d556 +103000 719c3b85ab62248c015de680a8fba158d0a336492668bc0b202ff9fae1b1b5e4 d90dede7a044e1b11ae429bd313e841c12e8d0303aa6626db4c953d198b0f531 acc9eeb7091adb2d2abdd03b650c540ec439b8d74b605dbe0f6d56acc0fdad6d +103500 fa0bc10bbd112c733022783fa67cc4ba045bf93115654e1f25e680595024ef04 e55422d2e8d2b8b6429ed85747a8ee57c549651eda0fcb2871ae5762862a86c9 8010ad6ca7b744c25584f31bd0b389ed6ed204024d2a3d43085480025ca2c8e3 +104000 e63af7f5547bf8bc2f36058a43569a30f7edd8286ce44ea561e63a3bc11ea7d4 939e2e2c30e66ae3b9077e947acda9b7dc0b9f326c55cef4e4d2e5025a0df9a0 6a5a080ec382c2a1f1a7f7456bb1847239723fe6a836117b9aaae24d3a979050 +104500 d73f74f43bc0653041db94c60b0e68c194199041c830e4f90345c1dee78b9c23 d1b14fe1a0631af85d0da1b0376a93ed925248fb2c5bc47d4284832d40fa318b f3b6dd22bce5f76f69b412b787be853833ec93c80be63d256745196c8175b628 +105000 460580489a262514f5414c1fdc95ef0d8290a23bdca4af93fd226d72ca79bb11 11fedbb936fb27e227c2602d32f688f1d024a5fbc8d31823d273818ed142ae62 79fe072ab0376188eb2502e46fe32dbd4a36151959975c65f907b3c7021e90cf +105500 a461d00c1217d40b1774f631ce44e78c974be18cdefc160ec33e865b1c7805d5 24f67d2f822429d89701691d7834c58593be43e7249530a9c1dae9aa12cde4d2 4c7f21e6d5b6f0b86b0df017852e08e8317a7909f4ef8e9530c064f623e82cc6 +106000 70b95f002b31d55c7b523451d746df1ea1ab182f4e3d26a6a8146daa6b175f70 f59d284adbc90a549c211187c55814e85b8343c7797ade9c5f761e5b4c5855c8 15038f05ae2ec71ec3f88554f81aeab060849b24474194e70ebccdb89c802c10 +106500 5bcd8c94849d744d137dac85d734d893dea9963746e1d5adefc0852cc99c3c66 67b4fb04c0780ac951d84e6779fafa76dae5d46e84ef41cf690cd33392c6f926 5341b18362d34aa0f314dfb91efcc583fa160723051942c653b9c6621f8dab43 +107000 aa50a7001438cb8eab4442c4635453881df972b8707150275fac0867d7254341 9e2451f91358f222b3934b24013be83c1fcc78415c12b4fab2cc5dd8a3d3c36a 79250dadccf089c315b6a9929b1d1d0828fabc87be5424b7bf327faf08eb1b9e +107500 f83ed835545b9320da20a1b2961c285adf11dcde168619a3e7e746f93cb93cb3 e27c84ca437850f8aeb0cf3bd1a727caf91808663679f2dfca99f4c676a4cef6 2c9755d38f916650e6a237d3c0e67534b0ee27dfe7da05c503cc01027e79d72d +108000 d9cabd49da35be240bfaf8dc107e13fa3ead3029573f7711c51c874f09e2af83 85f41c365756daf80d25256a132c25ced262eefd77547a42a51603fb98f0fac2 b793aaab687ad533b67e99d954742be66a9d624e8f030cfdf4e1d7f03310f81f +108500 e6f6bf4d75295e5dfff4f979fb12292736dfa7d4d8a7dc683f6238a4e00caf0d f294a30724f9d9ffcc244995acf528e501f6ffd0840f5ba8ecddbba1d1bbe250 3e05c579dfaaa081ce6c61c4236685854acfec868568142ce188db8c0fc85407 +109000 154e12021e0e5198def8989a1d68326833d020409a76f980e4e41cb1662e0d47 2e486aa0080740653141a5219ef25dc79777d3976bd9fad1a7c7bddc2fae858c 410f3e29b17c1ba1714595fcd8697e13be3216b2747ec16b84523d612aeaae30 +109500 02a8b8fcee9f8a420ad024de30fb8f4b2db683b4f93e37d5a7936728ad1bc1a9 f9c26724d2d6e8398a66e8ac080c8aadfc5155ce4be3521b3ae5aff95fca7541 1354ab334c8590c339ff2f674497925320c95dab6d70fd0bd28bce9417e1228a +110000 587654021f4afef0e863df85d5c48c1da57af439c890cd7c82f57112b523e567 41299bbc731c54c00252ac8506c5671a019c2f24117534a52a6dc243de19e60c f68cdac1bcaf2c5b1d309a18816faf79533d8200b369505e74e88d996b520824 +110500 1b144103a2729d255d2c79223dc4804e9ec38bbd07105eda2eda5d350933c8e0 47988c8a2b50a19d5c4cfd5c657b3bdb19848828866e762f5fe40f8ed3b0fc5d a8de7b91c00f0dccc29a832d4e278a2a788065a3d491e566be37563e0ad932c3 +111000 d2dfeee7017ce245109d6fd20d439a58fba318eb0853369ad740a4c7d8cb3679 89d0671f5c51cc5e682fde76759bf130bde74a8c3d0334013165cdc74df67a35 a81b3e0f2b3ccf04a60d59e048fbc01f591da5425bfd9643220ce97b03bca914 +111500 7bad9ae95d958cfdfe5f6f1ab0692c74023e9676aebf77696f0dd92f272484ee 8711ac67cfc650bcc9a9a3b170896959954dce728667035278b865e843c5f5d2 a59bc8880cda0f7f950577ffd851a18acb7c750440510209f6f56ab31dfbe591 +112000 aaa6a01ee0e8be04b54950e9fc47308bea161476fd9e5f7d931a9ac7a177c6b1 cfbf8e1b380186cdd7dff5b1775e68857e0144a6cff5c699cda0df8a9b755879 f43fe907a5c313040e43adf015a98d0b9c936971c9d85e639e92c180b1196a38 +112500 856c253a4ff511cde2cd1138cc415c15fc4601a9cf20f97a40a3ed5a8e4bd28a 2418313d86bc12dd0b7ae5246d70c5c95ddc342c5f522d33a4faa38677b1cf74 3802e55d5625b66deb5cf658a3a498de6dcb6a286ed67ca855799e25e52a8255 +113000 d39c76ff2213efb6aaf21e1831e8dfd86e82851311214222cacd1065e5f442f5 7027dd65582113bd83834da3b8feb6f5e724156d8653689be02acecf664ed8b5 60ad7e5a8a6aa36da5c85fdbd95a1fad66955a25ad7bf051c740dca3ecc0d80f +113500 072de8c792fb777438dae0fe6605d05f84c05c478cf045595236439ed614c869 66e29b9bcaa1beaa8d901e8227510190b64b665c427147e79fbb03f4c7560df3 9f43ac28a04dee975b9b3dcbff3ede4eb7040d5dbc8d9fc79bcaa432464017d3 +114000 2727f22d9d9b83d232fb91cf7fef9923d998166a632e104da344aa5b2c33f963 afb687e99a9ef1e794a049e78417ff2b0a15bf3c0f0a01b5c04e381dfd3eced0 93fc7bc539d464859ce7d3ea47c7789a64ddee4155ddaf0d7be6891c7aa6939d +114500 fda2f80a90dd787eb236d38096e1f73b7ee1b54d067c53ee62d4201004df7f96 434c6e214b4120e3df23c820dfbf7ecf3facaf2f30b55fcce4dc094d0d052ff3 9aa0f3861ad62b5e80fa6c255adad3b7366b90b2535baac36aa890fede0cd494 +115000 f8642fb7ecc176c23e6919e2a5f9a3f69d60c1bf10329e853b94141d7eecec79 02a4953482c2887d0dc4d2980de20cf75b73ec8d81d5b3d6ca6df741a3f3fc7c 41838982adc609b176d3dca2460d01603b07fc794d907a314b7844692e3d2a7c +115500 96be8c04c6533cf914499dfa780622f64e3362ee67b888c3d187c7cd167c124f d160418c73e78f1f75972ff6fce579d50f936678a03b8e3e2e8eec885c8e7f97 2ac87fa3abaca2b37705ce9fab3334309ab49d40892f1c2e5389164f5f9c7cbc +116000 6efc2af9311adf3ae7cefcd558b25335048a0344d0fcca48f4a8302e0c2f4e4c 5bd32d67887dbdc6482620b347a1ad8eb9c8d124ecf4e6966269a1ee537f7562 b6f3154843cc3d1fa7a91b65008d690c66e21e9d1fa97eddb66442b77a1f06b5 +116500 d2fca2b2bf347959eda9a08e76c269d1e00d475d90ed02ec7d5d537e542c648b 9476a9957e44fe4de208e4c707f0b6d1a2c0c0b3a32dabd912707ea86823f62f 2dbdd08eb831f98085b217f3523857d434ae7eb9fc883c163f59ee6e1aa27cc9 +117000 5ac65e76af1b75c9aee7eb49b22ff2fee88a1bda49287fc5dc7762b2c5b8768f d357d64072327f9db3d73ea738abdf89f5bd20ed4b56733bc9df37d200b6db39 a40c37148ebeab7a231c90ad9d5f832f2a50a7fa60c0633098ac7fc58aa74ccb +117500 3d7e8e1235d8f137cd5661125cc0627dcb3c18945254e9676e21f2a445ab8b9f 0f9c97626569303b76ebbd2cb960341f2297f69ae140cc84a40a83695993605f 8755a33fd86f9497f14cf0f47e4729d735bbdbc609068c09712f1fd7146bb2d3 +118000 be2144efc3b4ccf0d4d3d7b66c5f6ba253d1fff069b89a69f8eb2cc4ff44fe34 9bffc6fa6a4cf35486018721652d5358be0bbeeef8b98398c9373c352cacd4be c3efd174ed8698f182b4e7839ee78549e91b42fd05537150c2b9f49e3b75d1cd +118500 58ca03280dfb1e73dfe8ae35f67b60087586b36823e7fcdfb0509bed23c0f9d3 58ce09f4189a7f9263ee9292d7cafb880bb3676175c7553a04e25bc261ca21f8 f1551f00755727e4c81091c294c0fbb99c7f45cfe091334cbb3708b8c3997ff3 +119000 907a0fea05eed4572602c76515bfa03d5cc79da72496d41d84afb4ce4098be07 32779d699cd1abba0d653a332f07727b9a2094a4149fb66cb11f16df7c68d34f 4eca044e4c6e854a875f634e37677102a876195019a9ab868506f33850a4bd54 +119500 ee7317e1516104041197ebb0bba085bb14932972d5bf4ce305a3bacb9ce17dbf 6c779c5b384b94c7649ed90936688e83762407a89643aa89f730c6c399abcade b4cb0f26597d60b510022272b256861dc541c5df07d45ba11f81548b6665c98a +120000 7105703f4cfd592d639e0b5bf6f2d25380a1787346f24331401eeed04f146130 2a44b6fc864aac66301c1b20def1cafb0704830fb07e2684651513a6f8a89843 8b843486a87af20a9cc7c7950b9b0406ef462f24d25becbd36433f7c005647b7 +120500 1dc347ca251ff3eda0a459a85d9df212ed27b9e7521bcb8445d5a377e23da48a 3da9eaf002870bd0bc46688093150e254cbc0171abafafacb2c03f6381a532b1 58991cbe89cb2e1bcd00dad869d9d93cda1269e4ca917b44d9b92e21ce40a4a2 +121000 7b8f755c93b69f842a1f9ab68f67e597f0fce31b94e0cfed7f3847662dd1a401 f175a7b245645b0f769638a6ceeec460e87782994586ff8be749cee06da716a4 96fdb34452cda7bb2904119d24c006fb9b4c44563a0e3be36acdc7c034dcf88b +121500 2e5aa2e8bd0b018cc58a7d1cfc18d19903cd57882ed5ae8f2d6eedf72efab59c daa4a0635304dda991bc047ed1e075a9bfce603bd3bc1dcf93da809f82b0c5de cc2f0ced896193b19fe01f8aeb16ddb1256cf7ebf311f30d8dd5ca680313d98b +122000 9c662917653809b60484673f8f223f3ccc52f9288b8598b6414bef79181de9aa c8c62e402da8ff36b5833ba9327dd92a501367be811157fca1f0b80ee49a4ef2 5df9ed5e6769b16609fae4dcd7b7d3357dc5f496cdb9c02a9a1fab3bc8e4727d +122500 74a15173b1a78cb7e95f220178205db14c5bb67dcc64f8a1e4feb2cb5b2a6e28 f480c746a1436fb843e7f5935f2a8eb79007857b4c110a9348d4391302537110 0ae1ab7f7adbb725c581632172d514e33a82dbc410c709d0d654f1a0d4d7de55 +123000 38b438bda7e108f97112d984725fab27d277a08b1a72affda99b79654c21e0f7 b1bfac6a48327a4005f79408df343adb7c9cb22d2b70ebf2ad79121cbbfddfde 605d68df65abb13b0b19301fb134674efae08e35be4b80d00e4124118e2f7a6d +123500 ec7a4edbed36c3d7a0eb4098e6c6bca397bf08cbc0e0b190a4cfd506df0ac656 7700c27d9c2e7a0360bfa2426fb3688bc8b3ca935de69d15b6dce9ca6b31a4fd df19951e635cc5ed4fc8c1b89b25e72949eec677b0a08b9f4bb1a2d04a00c99a +124000 c3d8229a44faa337d05e0b5311a5dda37b91babcf95e5a8ccefbe872af0bd2fa 793481678c778e8653890f1145e178e42effa2ea7f8e50522187ab298ec6b512 76327e3f2c09f87ca41a12c67941a5caea3779a1c84f0d37a8c6d530d21f626a +124500 1510db798814caabdc90f2b18282456d1b1be40948ba43fdc68e2da017c2dedd df6d64ca6cc492e32e22a218af5a3b802ae452d66ebb018c5d87ccd35489322f 3f12f0e3189266aba9532c078df96b9f6db6c9f4105057feee13485af445451a +125000 82460aef9d1133d30707bd416b3afc2929a388ec8d1431e92699aa625a4cc3e9 8ac7f7dd700d26de62506f88cf117282a7840236bd66aeb148cde751ee3f7dbe fdc651d228df5a66e58c4e8566034b13fc7c5b9d6e8ba6e7ad0ed1047e0c3533 +125500 cf883230f6afd44caf802508a9bce39adeae83cfdaea0ca10c5eeb7e6e0f7abd 269f3d0cfa2df454579a4b7bc758970ffb853aaa7600808071ff130b994adfc8 cc6f34524eeb81b4d04f506e63828603973ec28f2f6eec8fbcc89178f3bf5f29 +126000 e36d486bbf7eed518a2a1b1668b516daf85bcfb0359337042bb8c278a5826863 8ebd6563987e0969505718a915e7945f0d26213475be39a4b36ce9928d313935 c139ca3a3866adb6d80c89c4ffb871c9cedbdbbd8e2cc4e273a3ca2d5897268e +126500 41b57270dc8a7fdaef0345502f3ad6ecf8012b680714cf7723aea4c7cb03a864 e422bcde2c4b3e00c42dde121d189205de9acc58be35d92bc590a67fc11b336e 23277af9201d11f0c7bff9713f093d7d13827e9bf5ce45c95cf8116a02997c7d +127000 34d5852f2c7ab91f6b7ba43851efe2838a874f1d47e6c41dcf413f263617c4e0 296613313aa18e97281d6dc14419528e0914d61bf8eb26f4ee08105aa358c0d2 6bd6797c2eb799e28a79010c8f79ff632d6559417cc253beca15ea6805b98165 +127500 07f471a70c1d559e6fd70d2adf4720987ac72e71d29c4bafd5f78e428aa6dc00 c32efb7a2072cf74b7124a008939f8093f7028259a69d8c9d175e0bb4910f03a 4e5c23dbf9a28332f3c9ca25568e9a27e49588ab6d8fe605aad8c40b98f34139 +128000 063c53a0e11590d0f370d0a3c2fdb3722c1c91e0203558436fb43b16b06f572b 2cf68c71009f221feec16d73d8ec1b729b0624f854851153bf78146935b69148 4a107a87caf55b16d2951f807ebe93768d406ca00450cfb669b5ed6c2f6ecd68 +128500 32a9b0507313417fdb97dce6e15852a8a55c80690028759b577723b629ec0234 b2e0756fd80ff838386d84e8d82e2704a52c07e56c10a88fdea969948893b808 a353283c0cedf81c24102cae0c01d2297e7d965b5c4c4f6a6c1afb2b9dcdfd2e +129000 b3dc6186f79ecf8e7d4b2937ddc1ff5372684cf818665a730771a932461fa8b6 6da8856b4177dafa784a25b68c4df9c250a664cc6831c9804403cb021239d03f ed6fa11d6ab43cbd6b53ea78bf00a2c664e6d768f376a8b33477df69c50027a5 +129500 1f5e8b0c9c4229ece2580e76e5164e1beb86e165d959cff8d7a0a9f74660505a fc76b8f58cf2fcbf3f2821d871788cf4cfac6e52b0fb0476e96769311865d90c 169723a26b91806d2e4426a01f96d4c506a9004f8c858b5e4c7b1fac5b317ea0 +130000 3052fa9be8c4f5f24f40c5cdf0a8eef8087e08f1d168dde5d1e502960183f137 8d108e91ab41a1057413efa8794611be06459dc53a8d2099457073ba932acb4c 59e9715c601fbfda3ce117226d4e2d76e1d1c239e05aa23c2fdefc4761ebe4dd +130500 73ed2cd1c1fa06e01c3c6fa4848d31b24564e667e3871ee032a1ae04812c4383 df3d5e20f9ebc94bc84af002cdc9211efbbcabee00cd755653a0cadfe4cf77c3 fc6c50d51abdb07de66327eadb4b803320de4f58e4254ba732f5eaa17dea8fa3 +131000 f78703a391119a15b5ce6a2a2bebf2988fb164656c968f72359af65852080c1c 8fca74427f6789147cd1e233e020050d9babd0bd6f078ed53f704c6922b5ce3a fbc836afa97af45234ed223da7462c2a74383fd23277fb277731a3e1716ca620 +131500 e8873601a44048b85d11b25b05c225fa970d4ae14a3a30c0072bcf6459f2d828 140c8f3bdc90be5ca51e7c3179c7b8839afed4458278759a35c4a078ae8cf4e7 a3dfe4abdf91c14b0273001bbf71ec44f4698f8c6f1f6f30eb522c5c73170086 +132000 98752c54d7a5238387599ac3a0fe44b3ec462f88eb0c3c6414160ce79c128a14 f82ed570eb9d3c9078ccf41e675c13fcf6e73e6e5bfbc4b6b2c1e4649dbf8a0d 810b74f9c767aa7c62d699ec3889a615e85243f8cd7710845424677b0a43c5f2 +132500 7377043aca01beda7f7d70c6c2a9f59ecec4769cb330c231abf8439f231a6355 3a35dacdff298a95ee0fc61728b4711d99c4d1bd4806dc738c684d2632fd48fd 6bbab9b2642936d0e25f2f0b0e987c3eaa15515a7a70f6a14f00dce3eb63b36c +133000 0d70e8ae76041c02ab65bdd3b0f6a456288532d5447dab7f7e30123b28e16543 d6b3a5ad40a90d26a4b218b8b90852d49f508cde1bb2a23031f64e765d519dbe 2aed7749ae9e8c34545f6aa4b13c2caf55ef2a9c6669c18b2d6a2fc79d89f13f +133500 37aa235fefa6f62af6e393639361a4109369d0393d66597a3c63736fa5113a02 9c59c20c57628b250fa5757d8d2d55feec38752453f21232141f82c1be4dea63 cf42ac7466e89a3c791602ae3f785d709196d4bb20d1f8e19f5e69f30c57f398 +134000 2605e14bfe5b9a39a4d01da070c05d9bce4b6453b599a1f6f95d8a6344138edf 1b02cbaad0ab46a737dd848c3db0f111c3fdc248d472636765ede6a6c2389b74 3d4224d4eeafafda11e3261a668a714b7eaf019e8881dd30688dac28a087da93 +134500 12cb93a2b1e5ce4d9c6d2266bc6984839271c92f8ac34205dc621da8033af81b 6346ab5cc2bca05485ed517f9e494e1e35e33ab9ce011923c6713dd0bc28fe1c 6e270e7979e87e8a8dd0ede4b24ab6c2188d4f33d9f0f08f6fae0ca6d739824d +135000 5d475b01fc5b6a22c775b89914c3b148431956df26fff2631111e9ee7d1ea55e 182dc60ad5a4689e655a00728594807ca659ea3e870a4c71152b220279fda836 f0ba10f249ef958564d7cd9d31e2b1578e432e7d8c2285931e4d7ca1e740ecd5 +135500 d4b244f6df6c05a1c918ec0c80b4a230c2e40de23847a3c6a48b8706b55191a0 c0ea29271b681e460441fc515fe8af217459716e9116ebfaf9899531e55b9181 48b5ebd4690edb79ca74a4560c09d79d8da8647e57690ad8954052b95448904f +136000 123eb5d144a44b6940cc6194be4ba041c5fd8a5ffb342b5d62d8779605d1fff9 9836476b408a143b336dab7cfcee4c07ddcbf6939fd40267f8315a7d4d576fd4 f21dd2c8a381b01a01f3a4b73a70b4712f276e21639d5a63dc5ed5f69a34ceac +136500 c169555d2b59eaf45046d5c3832203dd5109c6e3018504de66fd99242b41d5ad 0884992c307a5b98b026f9885b6c81082aaa18a12ddd0b302fc5e358e313c810 24a2322238cb677fc929fa52ff40fed8ab3712ec28ecc3569b8c8fd588ca3612 +137000 123d022b5482871c55b3638324b5713e225c6e36ab4f83120d883ddf3c0fbbf0 024aa453462e49f50c55c36736542e4129f56cc81956b74f7c77e90b0e6796cb 051560bd18e48d8b27f648aa13437285f887559b306b979075173ffe19e34949 +137500 3dbdb568d735e6c47c5fb8f459bc448693566ee30140da275f786fffb244901b c0e599ed4901402951a3663d225047e94861817b0a412b01e4c770c9719cfe53 f998f1da46fec63c0c363b47020fe3f3422b4ebdc9eb514c9a1308982e6d9c5e +138000 9dcdb63588c3f9d43ce67bb6da88a144e98b3340eed60478d67941bc1f3e48b0 0c04f84ec720ccb4908774fb474149dc069c8420a53e89e9007dea32d90e380e e3e932a8d0a9424dc1ae73f0b7856d83cefd4549a0fa9f0519d11fd9b3c94a4d +138500 918f3566304f92ee937b50939e5224bcefce1b61503b8cf5c75cddd293115037 345d16e0d5aa525aeef890c1cd118edb3d1e6bf784e9445aad720dadc3408667 57234942c9ecd8d449dcf6237a637bdd009829bd7227f0d0aa4fa1bad549103c +139000 5a5cd26abe8d7b66b82dc847fe582d00c1aedf51bb747cda126f35d177df3780 b11a4c12939538a057f35a15f561da8ad09ce4ec33a1b6b965e6c35d7f6da935 d94865465650a0f5f1ded1d43c0fd0afea436f29e999560aa1ee0b07a5355f73 +139500 883ccc866e98513c10d46ce62ffc4b2f52914f9d3c77835ea88b2d772647098b ae7d18414cffeb5073a788005a70e1e80b3c04abc1726101177509d0872ef2a7 e0d75910529fdb92ebe2279551b7f6614ce56217e14ebcdedf57451f35025b2c +140000 0d53fc7a730aab5b7751832647af30f6ae6de5f66a26aec228c9642132460c09 d157b0bf7301f4c28143ea0266a95c92a05a3499dac2ab929d57ab75b2be499f a6b6f4f34cb06f19a0cefcba963982cfc4d0200074371e0cad65e14a3655b809 +140500 b67b7cad6c800acd1fa41cad0e075a544368d679d03d620f5cee45cd966b61ee eec57bbe03beb832a99ab0bc6b77817e6bc459e365367b09fbcb905f3edfa85e 2bd388afddafe559e744b0b3b07e6586edb24a1909e71bfd6153340b1d7dfb73 +141000 68756fe78e60cc7191d62c387eeccd0030ea6a67d4b1fb6667c068c5dbe20d53 113007738fdc702b03dc17993f916d40e24e88d12a95726aef18156355990d7a 695cca03b85013042bcce092fdeb39222498a6743031a96b0fc8af3dabbbce61 +141500 12aa3f916704a9120c99c22977c22b16bfb670c9e9d2807e0cadc444c9e8d02b e7dc3dcc436c770ba20dcbc3f4f762b7ab343fdb180e867b3f3db34f8b279871 4baa32ead38ae032e115655d55a31d08647c588a3362e4f6b85f8d6b8ac99b7c +142000 629495f161c45d033130f52a4df5e06cf5f705842039b89c3d499aa658ce5a6d 865d4be2b339178a44d8d9ac4a53abc6b4f710b723583053f23b73c0dabd77b0 25265bb92b7c7e669482e1ed6e8c41c2d60b169c5707d5bb15a33f959ee769bd +142500 941a5dbf034317971407a4743fe1c5cf11ae87be184fe4e7749e2d32632deed5 d8d4c2edb8362a39b9ef8b2693e1b4ed597a9b315e60e424e26797ac5266f353 57a4154baa1de288b989de2dcf06d8a1f3b50af5bbf5a9a085f72921841ec59d +143000 b8ac8abfe7b81372299d2a8be307e13786a5aeb4c3a671c8ae45d32f4bba9281 8d7e1ac28129b56b0ee93dc931e54293f181d3aa253e844d1807d47b31193f56 fc792c95df1f7a222dde5d47286fdefc2d7060f02db26b03708cf7642e445dd9 +143500 610bc499b94eb7e00d1aae8388937087aa421bfa9cfa70baf798b8f97e1b23d6 e990d00ff71509c232b43bde64c749bb1fe597e52e40116893e02937c7943b1d 09acf59e7f882faa32db3b0025aaa3c1a632ca14618e84530c665f82542d2657 +144000 58ab7580eef5d40c0ec3d7ac52425ad5afcbccac834192fe71ec5a1d15cd4ed7 d9194f449db3d58a1784cdda50ca32d4212d43a12e85c6ad9f8b77687ca04a6f 7ea883e770b9067c08ed807f0004fd96d3d35584781cf20d74a8269c34c03b70 +144500 9a49c8d5f6b072b617ff80d4b70116bf3db461f9fdf283009cd9e9b2c2df0925 a2921c9b5ac78ceb49666c487d217ec303b1f5347d6902baca9b8e3779774c5f a48ddf29d2ff688201025318bc0362f95f7f4e7fbd7265a8eb95acce19088759 +145000 29f1fe68b8289b62a4eaabaec5abe811c61b6f2220dd15f04bf3d2ed3f98ba02 8d3672fa9d6c4767e8d3819f09a9bfdeb98a6f35b83f01faf1f7b85c6871118a 4b5eb44ce00f52df4406aebcac1f42a9b2e79685ae8ddb3c0125dc14a73cea0a +145500 677d2c090d3beb31d1e611e42801e75fd3e2004e10ba8ef1cbbad5e2b17eb02d 93a4cedb34458ef8b90ee740a6b19364f5ba6c0096a16142929987d2386358f6 8b422f5ba0f1b2e149e032ca4f566fe353bc1330f5b40b5cab9bd65ebedb2529 +146000 b85efd80a2171505e8e2a83feb7f7d12e3793fa4ed2999d7b6148a1673e574e7 c76311a2cba2713e1e7706f71e22abd117ec5c45d7463bd7cf9baa7734468c79 782f73b81c2d2333ace904959e2e795099582fac13c71a11e051889864abd89b +146500 f1dec5d905557b23d644829ceb4f9de311a05ea717740e9103d155157e4d1354 3764ee8b0d6ae8dc762a3b43d012eea45e1e5c1008e90403ba84549502c3b62d 41a73a0299e49dfb3da0d483734e359aa70c9fa846e624314a87ab2e5291f82b +147000 1e59d25367fe453ea1e39d7f0c870f14bc37e99ae2899a6f0e67dc8ca110804e 238df05f6e2a851137fb165117f2feb458487307ae95d0683bc85fa748cea31c 84fdecfbad7b1f0c5f7c2fb6513fb0a9871fe8af6879a7e04a40faadc409aa6b +147500 4547d35c4821dd671dd3d4d99fce894d455c083985eeaff26531187f54349bd4 13f4a0105947e707604293a632917b8b93caeb00c02a28668a9559de36e5822e 6d41213b961e96e1cede02df017f362181f6c10b3faf55a066fee7e817980f22 +148000 f50a828d973baaefd78a069efcbc42389c7a9d0e17cf4476d6bff763d3b219a7 7d057f6f26c87ead3d5a3bd63b23ad81ba5a9a84258b46921f27f07919be82cc 88dcf2f5fff804ef8b64dc24ea8747bda74ec2f0f0b1c15e5144ebef5543d29d +148500 219d8ce760106e41d5b6cb72360801884950e795cb80c5cb75a4cbee7c9884cc 66abe4202adfd1c91b092dc15dcd702b0e383c2a9a87dad84efc20f2391d6024 2e1b9af96ce01ed55a76a373db6f175aa7939267222b8ae2b81d904ab115c6e9 +149000 e13e98351891f9940b40210188016098d67d555ee60922bd710d234393583886 2751b92f77148b0b55b15c1e1939f566749d8bd28b70f9fa9445d5c66b116a4c 679915acf67eff37a889fdec00abfe90edd8d9a6b5195eb403b4a33b2b02f6ad +149500 bd0986d58541fe55bc5615de06174615007bb0a4e9b7d52a6e1de27660ff5e1c 8cbd4ddd59183bf20e4bd2ce22136e8b1109ea2e81fae850281e600a04816105 03d93cf4d27bf5519c826bc4fcf8bdc5ebe413953587f82355c4df6b77346882 +150000 b0a52b599b482e9e081373c2d0c12adae59742c92c3feb16f2b56a536389c566 2b66e1c89afb06043357c8a702e15f37c6cebfe2c3ac2e2994b387b111852c2c d4e5a3daa131a0afa29967f8ad8f402f8baee17056f075d0c811687b53617103 +150500 348a90e69dee425ca95455f04bb8e0a9a5e8e4c9efc06e8358e90069f33cbd87 6296399a3fc3e48c09ff1bfda646b6f19277f2c2562c8cac5c850d691b2c2110 f2e3eb906a46f4e787a786c9372b847e3d667e8b7afd9dec5ec2ad405c5995d5 +151000 c2fc138fb4f13487c8f0ba65b1843cbcbfef598d66205495ce12eded834ed5d6 6b3d49e0f596367b951b6939dae4629d81758a560d8bbee402b4258fe3896e18 8db9363659e76cca5e94af0b7bc72a2da150e5e34a80aa86fb42d56df45e2494 +151500 f22af8f0a616af674ee4e07e5821c6ae1ba54d431200daaf39362d203283af2e 8c445485555c915933539ad6c8ec776b65480a6b6100cc2f2355af041d37ae9c 2057ceef9679c1a12ef58985712ee4ba239592d95eaaf5d67ea9023355d1af89 +152000 ffb05330a4e59f90c081b821c1cc26def98eaade28aa6fa36688c9c9ec2a0ea4 7c94c4bbaec72efc42d8c00f50f777d09fd0bf0c71475a31183bc391038e4fa1 13864d254b6e9099c6dbbee5f505134c40793b9c353cb738b1d97b80e6c44926 +152500 b7c7e8aa6953c0ad15cc9b003dea50f9f8bc08d8c8ffcbb287918a9e570affbd 16591b434c6436280873b7b1d81157359b67969455cab02fcbf7ed9dec87e64b 998ea569a30d37978769b49eaa6a5792e64a7309313f4e982b5763c2a1f69712 +153000 fef11d21d57c34ca41af06608c09e6d0a1623e6970123e654a81959089913630 0683353ede70fecca1f5f072916105b0fe941d24b2744dced890e2d4cc114356 20a6cc7045658dd34f400e80232324750eadbdd1375fd0ae3f72fcebb8e5d6eb +153500 0decdb908b6c897fd269156ef088ea6c5c76ad98cae97cdab6b9958fa458c4f1 458fa9b12274e81b31d551966d7992d6304bd3486a76d9e484af250b4d725e83 c8782ffde622ed54700cd51b78fef2fc8f1d0276e1398945678088c449428592 +154000 8e921a4716e55e2c03536ace904f1b76f2e1c1f44eb1efc293e819619fc64a6f 9f3faf97a3d07baee0cab898c7e2c16e1e75cb08b8593b30897f9290e7564464 58e96c936858c0d209e875234d5ab2b9e46ba4f0766cf53399e53a19804ffe61 +154500 b2ab747c57f1e073712e5c7c63d14e427e4c5aecb70c749d686ae6740eaccdd0 5b6d69da753ccb8fc0e7cc323bc544e272b607f0fcd7ecd3afc27fa454bb13c1 f720914ac67c99900d3582520b06c775eddb424243b2f00c74fa5b78534291e3 +155000 4a27f6a366c137b5b0d9a7864ad6ae3aa2aa4f92fd96afad203f9750743d1b25 5618bbb8a52a4a6523d7b79f9da38af51c38ec0b250918f9fe13df1f5ca4cded 5457390cf1c31b2e16cd5c42c20b3907b5f68e2031af2ed0e18f4e42f33ae788 +155500 44de83681d8bcc4a775141039552a3bc94ae7150ba6cccb0eb51d12f67cfd3db 526775b79eb1e6f88bf7b11c21c21cd3de6b70c591b146f75dd6f7dfb25d8258 fbaad0826ed4fb17fc50559bbed4e4465f62d7bcda7c2841868128f2b682e541 +156000 fd67b25d5f2f9e33e0717ef2eb6f7a8b61c0e369d1bb27d363c2fffec6934c6f 069fcfe28f96738efe2241bd5c46e5f9dc2568399dedf97a3b222e7db1f8d479 828d25c4b68222571874c8f59096afb593a9a8f3b21d0da13e80db52e1a7b1b0 +156500 e4ccbec221374ecbbed5f7515a62ab145566ca98f91fca6e9e9e5faa5a302e1f 0138154cbb27aeafb8785898175459b8fad1a50e5526745da4f3e3fce73906ea 6a9d291450c9e77ef6037e3ba4e4dfee19d922ef52b20d48cb51216247ba8868 +157000 7931d577b76d43c21d638b392ce9e89deb30440d5965bdeeff5ddca528b23f8e 2b3023999ab4fa8af216fc6fcd1b74a6d9b91805c25286b3a9b5c21d111bd929 5483ff5e1b7a0d69cf11b8445a1e9a1260641f7e303d234e880d098b76756971 +157500 5a785cae6668099aa3bba0aced796a2efd3f32357d5cda07964c38bbb8547f11 92fa0afcea0018aa72753e44978b29517c44b86583a7e7293bf41d0fc52adc33 f7b8d7db38fd620cdfc62860ce93c698ee8fc716776edc93f6fc03e2639d6b32 +158000 215585110369813d5c23324bba75c2fba77a3cbbb8074822747d1d5f7a54459e c2bcfd99aadb46819152e678172eca6ea41d068cb9c3644effd3da1d90fdb6d9 4555c9718c5e20d36a96dea771a7b3d3753c871454c10285057b792f62bece49 +158500 33ea7e9a89e3e620f7622a67f945e6a84caab88f8df84416920e34611183a012 fe4a8ca54ee30957c1c4ff378addca94aa3c2faa44d6dff2c90aa740c94f322f 676d511f80604351ac7666c70d8775c2f86aec0f43d339e705d16172517aa82f +159000 5dac31f23e99492315f0ec0395c5913a197ecc6bfa5a1f1c38fcbbce10f5b2b1 3f33701f476adc2de539a516353507c2319ee322415cbe2d2a81d25579320df7 1798754aebb4e7543f64a7935dead4fb7c197cb27b68e660cc7420eabe87c1c9 +159500 e49f3c6d819ba98b65a07f3e2b4cbd4ed74f8f352ddcc5b29cf715870ffc96b6 8d4baf5eb4e709a1749ffab123eae1c16c84c08c2b10c1bf35b904214b55622d 35e32ff53ab80061b60218b9e199045e59d7274c18d18b3ecb65ae67df00a73e +160000 4ffcbf8641b4b794fe4e304f3e33f8b252b45c99d647e26c174830811d5214f4 d9feccb9318af01dda19ac1b834e8aba8f1a31b7e3c0c874c2340e5f963099f5 e539bd7ccfca8e6a80a5826779678e65131dec0c3260a430dcbdabce60c018c4 +160500 940e235e254ce7e8c7884b846860faa5a7f8fe08fd7d05bedf60a178b294bbc2 4c96d0c1b2293677ff55acaca052f84941b801d35426f5f6fdd0985a772e140b 369a4692e6c3548bed6868c8f5540ff7773fd465795cb6f4f167a38a9ae134e8 +161000 49a2fe7b8f78e83709f195d11f092cd5bf6756dfbea8b61f6ad4acca38e0f433 c61985a4419ef741b3255effd2490b3959d9a37b9fa458a01e314acf2cd110c5 51745f2fb8b5b26377d02698cad29b811725181176b024b8cb6270a826aa2d1a +161500 adf7a049b0055137358e82ff4cd0b223d4f1e65a99cd9427eb8892e9b3956546 f2ea625ab6cfbd295435c3e70fc60ca04f444e88a9951351519c27066044094c 822600252a5f7b5579773d156f38accebba75f2da548111012f2413eadfbc939 +162000 78eb9152a6249d26cfb9acccd3be7692835f61a70f9c4dbca7dbce97e8eaef29 92bb404d3deec9249fdb8e8b0c11e1e6ffccdce4f6b76e49185e0e0aa6480b30 083108fe3985638966053b609666fd101cebb4826499205dca009f72106fe219 +162500 f0016f65cfe29b53a443c3117392b631edda432fb508e67f537158d939bd24f9 7da855957173b1caef3a5be9882b88d6be2feb3860bc528822ac203df9480ef7 97173e216716af1354c97761a088c7e53f624cf44e0566d20b1e6a4638351487 +163000 16310f334b323b1c422388a77287e590286b436eb1d54c99a7dce533febad9d1 50b8d182a094d5709040d1f8be2ed7aff41c50d3dfb49b6474ed04c7563a2afc b4843076181bc70a13ff31ac41a165cd89223f409c9e0d13f235bea9e51182bb +163500 54529c58d723c981aa51c3bf7202246d09e30d6bcc22b28929b2bc80b970a46f 81722de9f999145ae10c5a72cb03be616a2c631f6239f01243836ceaadb219d8 7f60e919dfc92720ef62c9e3bff5878b9a4406e01cae08ca99cf4b3f86b2809e +164000 135d6c860f9cd670d82153e8e37e5202b6b1632cc35280c0210587f4cb4d8f49 c5bf964eb82fb51d1f5a4507bc2c9d658ae2f868cd517674ee1d81266971aef7 fc75259e7d42db12a26a3e42931fb01e8dfcaf7f0ccbad81db12a4130cb978ca +164500 08495f35f925470863e7dfb79ec17bd61029899bad972ca0e5bdb0512a0ad908 8901ac98fdcdd833938280eb495214ec81269d8ee99e0c10886b9184b0aa9d26 ec01d72736d931f0852ed396196ae71dc6a82c0b42d661a43c424f43211b0ab1 +165000 5178c8e3106c700a225efb2d7453be3a94616e980fae5a532c0a9fd103aeaaab a71b7ee462788bdcf6b6945da2a2b426770bb4e31c7063db4b9c80f82ca88af7 33dd08e6f7e8858c84e0b9c438ad4e6c59eb9c4c30aed571f57a7c213cd78795 +165500 3d1e48c8657aa62207f24888630361eb85ea3f8225e65deab240e5a242fcc463 b16e47a7ad5a208fe467efb2f7a2aba78cccc41dbcdfde571ded9b033b2c660b 6aebbedc83a2cb1fda9df193023a8738e6e4ec691b5485a8229bb0eda0f5ddb9 +166000 2a5df181ba84755d4893b8af164abc28ba9d67f0fbf70a9fe44f78202c19e78d 6382ac5c3033076f67f758d9d4a66006b6c67983e46eb4488b8482e5d020cc7f c190f4febd681311354ce703dbc7504012e9e2c7f176f87d87d97ad0213ce2a4 +166500 f33bbe1188c265e4f52649d90a9c853742c89348276119166d9dfb5b0a1c1d1c bc724795f0704caf13beea8188647ee2d0d8c05593cff788541d1f694f02e7df 04e29612e5d6d95e89b80a3ca7fc24ca2f8472b2cc4f7b87f852a58a3e3bab0a +167000 278a49c7367096b101da81aeed3a9b3763b9087446e3f3eb7d279bbb180ccd1a c90bba777861cff1db1ef3cd40e240a74bdbeaa23e2d4716dff0700608431547 b1dc55904cc908d2c676275faee49c1a788c14c4ee6c7db7fbf85cfabee49924 +167500 de103832de75b420ee01b8eb238c7e5ab2fc2895848f1fb934bc0979af54ee3d 5263039373a72cea915df57bc9369aa15e7dd2ca6c3b6df27938d5240ef4cd8f 0f8d4bbae624d8c65e75cecebd8c8924c544404fb51a5122d6d79f6ad81148af +168000 c347ff8a9e0c4297f74db5943de2edcda14652f1e707b0d789878424b0f50555 fd732e674ea0cc59454e599365d9526a135a67ee82a1e54460f90b934957f9cf 7c421c0a72e79c75e76037f83184ff85f13a833acc677d120ca890d2ee62576a +168500 7c4bd55cdd16268ac7da91c44a5c204519aad6dc79a173d65227995d8f480ca4 66e715d9afc7e37855c6f1436bb3344b440a7db44fe5163f2674b542a3a8affe 756e2c879bd29673c2622c3ddf7ab61784b968784d4b38e8bcb5064a4056080c +169000 8d8295fb630e487b21d46f82e5e0bb95d667635b1c0cde080e9965ea021f0d3d 32309e6dc4e7812fe36a3e9f14079eb2f9a04dd910965a631f76fb23f29f2c5c cb1db6a081bc3bfcbbe3936ecbf34475345855d6a80e004f44d6f3a2aa883bee +169500 3ff4f89571d4b7f8e2b25a761e2b03dbe82d9d2acc565c8f06f8e61b7b84a48a d71ea82c1b352917a9a60feeb3ea40f35447c58909a0832d17451458c4a0a079 9791e55a423775872967f93b1c93656d60c275daec74680174f9f3462ada4fe5 +170000 e4612c319a4c8cda00c8853428e0c57c4c688d9c7ed0ebe3adb4ea410066230a 2428df1325dedaad3c6c2e18ba57184348603cb4e5d4fad961d9f66a33e8d4c5 298faf147be61758d1bf330195d35ac46b2a674af72b7cad4098a790f60b9a13 +170500 38f6d4c55c456c85b59d965db3386f3bebc9f3ffc101703667c9ada2c6f110fd 7fec7fc3f24c1f7e635e06427d949e9244c3383ae8a1cbe5ff92c20318d1b303 784adfc421d9d79b16745145916d119a7b8d21fcdc1b2b2a5de378b5caffc8a4 +171000 fa2d2abf42e47345b9b06ab4f0dbcb6d818815b383959b5b0f69a207e755ae18 6943c6e99feadbcc5f22d2000b715e609874953a2f6b06ab18c6f6fe0d9ead08 a5617beb4eb621345e1af0f9a671e21a92b223feb5ea9011fe196f8d673b5bdb +171500 b269e08b7b8fcfaacc4cb1cdc39bea13237265f03eeea6df488039715959d60d f978606a7a355e240373d149a0bf3b2a80d735371506f6d83a7eaf2a05f6a300 5c977031ed8854024e6d2484de8c4ebfad7c69f130b063240b6ceef706ff7dcc +172000 c1ff70cb404b9a3f97513e00fe8d713ffc5a1ea49b29be1480dfd3b0e4410d1b f2d46aa05b23a697e347a4260c9d14b51e08af5108bf22123b820a54c73c3fe0 878d911ccff1d8bc13825fae7d2a40dcfdf3c2c6c817f9d4f4f2ba0c77d7dc97 +172500 6af8406f49ba05570e46ebbea295e07ff856de60f7f7a85f29ccdf0483deb414 2bfa8eaf8be3fde78ec35b8bc4ec1274cd089732617255d9b1450f676d359631 1c5f68b20516cf13759bfc90f300a01c970c2ed22aec2f5440d524f4fb8ed2f8 +173000 4187e88e79ee333c661955addb9fd1ff4853bccda1c1f73585fbc4b866d46ffc 2c561a6112ac2531467818ef79bda7fd294cc2d1aca8d700ffaa8ca3c7e2cabb b4b9badb564279262308912a9588870961cbdb6fb9ca5488f37928ed9eb3802d +173500 979cd0755a559b4298c4e1af1ca1ed389c152f6800718aee777431e3b84b2975 817578adb3539145804a17166425c07a798bedb2637e8e6567e77406da8cbab2 e0337c7b2e52ff99af8dabedd1f1912d1a2201e8153b3b984036c26a7fc46ea1 +174000 84e476b10a846c1f76cd25ee8721aa8098a3a794f56a5a6e2fa8ea08dd7de954 7e3015ed948fc061ef3955ff4d18f5c9f2ccd86794be959d5e51e604c4ba315f 4282860b30cc16a2db68903e8bb0f3c1dbaa5949174240e3222d70a994cec1f0 +174500 daef6a8cec458daee2a97f145d74867790d12697f424e390fa5ea96c0edc5889 e70b3b4de2ebddde769763e56a861ea73e3a9ab8360f0626ef5075560899c18f e69b1eef08603fd07359c1216cb118cca49ee176a5448a49e9a3fbaddf9936cb +175000 3f6c5c68d024c26235bb054fe0e892b4172a50c900ff7e36a061b17bb4adb44c f36837bd4b44bb99bc4a99acdc71611e6bbfef26095aad173d5b6c2847cf5cfe 31f4639cb01d8370582158623353a2f1843dc7d0d5240035572fe76aff38480c +175500 2a25fd32974c49ec621f4256e89f3c1569734a675bfde35fe0ec4572459a99ce 0de2de8ab8f49f684a4ed93762fad169165b9f29306fddcce37a10b3e0f324b6 4aa307435bb260b7936bda377dc6b2ee78dea1859c5a50504adc278372449044 +176000 ca43896b57242e50c5e1b0904b12b7008d63f30810c9d1728929a45a051b1c28 0c0a240dbb5b8d9c5303c2e401b1a9be3eb940a2ccdbd40482b18ebd9d16fdc2 735a67586d8c32fb70e490082bff35c245683e46815882484721852e5cd958d4 +176500 01bd824255da4562af0cfe656645a2e644bedd67f5c4c2266e9d706d724f77c3 c1c8c3eefcd2a0dd893ec58a59d9b4b9fca2456b4ebfa118caf122316ec1758d be47ea88b1c0c059de0a8ec08c34a38b3595772d37516a3f23c86c12936aa27a +177000 1931b94a1d1731ee2fb2b959098279a73f2938815dabb1689c98ca64ca265eb3 9ecec3dcc0f626eff5310a338ac6ec36e52cde0e31dd2668510985504dec6b76 4ed89396d2f57a853ab5c7cd9df8b3a83a00c56806c8e31e8c229d835f56a056 +177500 d5e641f50d45b9d3c2f81c255fab7812b79d778bfbf3acc3a905255009efabb7 780102c55e6488511505df92213d370484505fcc63e36844adb4e55e28b11891 14dc898b282b20f15851d882a8a54723f6daa46598ba197a435faf51ca0cf3fd +178000 41dc7c791cea13b0c22c556ecf0b9c43bcabfe110cda05fdffc9a213d07878bd f502dfc4f8e1e754fb19789de0195d3f76515af97df6f6a4dff9af35e9e64cc2 501bdb86464c2e4c544c8c7fd634dd884c38c237a80897da49f526e44b452dce +178500 86fd0e05f7c975edd10fa04040fcfc06aa5988f25a24dc475468023fb5ba60d5 9a9d5b0da31bb391cfadb78b79de03e6d2f9356b6e8f2a6b6f3561718607666b d6a0a18399d9c382a9d7333af7208f4084dbc08054cbe0d8f0c0403e63489470 +179000 9f87f2c50cac2bf6596533b242692ac06dd59688c85711dd3075556a42b5a51f 62c5b9a2f74642239aa89a9468c1959af35f4218d16ae1c0e22879ce5aea14fb 1e72866f3fbcc54b6d32cce2b1405ea585e5d98f36eaa840882db29d1cb40384 +179500 2802d26be7d5a8dfa0e84d507569ab54eb2815addf1363e844143d4d1949aae3 04a66a42a874e8a94de4b35e0fe5b2415e2806089e62b0ce867206a3bbeec923 6c97ac192eebe679bc5905a7e5684ee9f1dd3f0988b85e8c1e104cbd40c8cac1 +180000 fc0f88ce08e8dfefa8774c7b9e101f82f4c7928aac246233b5d97b178ea1e8c8 d2cb3429b3bb7ca9c4bdbffed735f779979900ec989687ff9563819b3f340a40 ebc045856c0f24839f6a45dd27eae4ae20f4661434a02544469b92d44d80133e +180500 55068efb221561b62da4c6cd3933963165b99679274f0a18b57e12a0f59c02bc f4a3a53f8756a0f1ab9f0dde456df65f68b487f452e35119a395990224589672 bd9796c38a7e9d8812e8aa74fe7400283cc92e520eee8b25cec8fb8b49e678b8 +181000 87c0badaa9ad1ee338a1e0bee51f0e5d95eeb69b608604b687e1b75cfe28b1fc 55c6a1f3d35e1ba2c56261370b991094f37b2e0c94c585c83c91ceb0e66b4205 c27ff860820231b97dd7e5966560e39679ecd722ecc3b5d350db9d614072d9e6 +181500 0223e4ac4db7cb7aca8c5dbcccf4dd6d67c261e158579465c830d00f0b2065a4 1523b5a7b17c5f0a487b27b05911b0b023b7b70c1e93a676178193e10dee764d d1b905426b42ce35f13137ee204becc90c653d824d70a7ad3dab923aa6e49106 +182000 3bd580fcde83b72980a98de1bd2bc33f5d2e5260a45b2025f8993ff148006fc8 b5867c690edbe8ebe6938bc93774d516dc0de5a71a28b48539e4029162825354 44c3ef084983f11e3a1f40f9d87e3c0af847b4341e1fc53d576a93fc9910251b +182500 d5ed6e8efecd96800b30644154dbaef8704783309362f9cdba26c757fcad2d70 f64f64d8652b12527197f54411334ba0ba66f2515e4c99281a075d1df597c8b3 0c1f07a69cf1735407b92ec781050dc703cd29874cb873c09126cb3afa36d701 +183000 e926c6476da9f0d3fd84aec136e029881901667ff07d80ecd1e6e6e4a1e78979 e74160bd9ff069b6511c0602a1c72fc61dddb22899f805cd9c2c0be184848033 96eab6f32832d3e27bbffae0e7db6c7ef6fb2aac226893ca446387a1b76230c5 +183500 5bde7c982564b58b9d46d8208922b3ae8cd1d50f2f68c7a4a8d71e636b66181f 00d016a3247ef22887c0909dc0a7370c62bb2601b09425bfbcd93f782e1466a1 12c823ca9c001b3f59b04b61af005cf13d260633d4bcdabd77594c9e6b08c14b +184000 f1cecf410b8d9f5cecd6bf19ddb1c7157cdc5c42e110a42596620d9b54216dbb ca3d938eed902785feee39efcc9a60f26ba5a53ef969f174ffc7f44dbe544bfc fb6bae9cbddcdad7e3115e225bac8ccfd62e4c0d450f84a1b0bb1d40e716d095 +184500 89d6e5e381ea4c429428a773caa457945d6e5986e77830699d64ca84b6b7cfde 30e5fef97c937baabf267183b5f8bc9de88eb72b00c204abf6db1962ad1e1f0b 3b3ca3348b62cb425ac208e34729700e2c0f40c8ff769c3a2f078479768bf6a0 +185000 d55dfc02a7dc5e64f615b9821e7738cc3f4b1cea50e291834b3d950457c0befa 3976b8fa6d5486bb07e4f6a5a63f200089781bc8c347f858bcd2d4a8eb4ebc7b 896b5c4d3a04983ae70e3fd2a3a47966c20203204f3f55ddde32541d3688aebc +185500 b74792db4244be3b16341cd6bb1af5c7a9b71df58b812691901a59e2e6889f8b 4523193666a8f6eab2f73949efa94fd98d9ac8821ffec1c8069abfb1dca83b0f 41b6264e2cd8870abddbfe47bc199ad0ea07fcbcdc541b7b1891c9dc1657515b +186000 673e42a71dc7428d516a2bd892f5bba9740deb4a8e7100afbb0db70de4432d4b 54bb7fcf882d25f7e4cc19b41bd13e44d70c04d31a6b4e2ddc388b6ebc0b1818 46d0b88252df9f4992a57d8accf413548bb64cfc04dddc3cb04ffd994dedc695 +186500 ac9d112147478ad6096daea4f3b9b76912367605cfb6ac68a5951478787d84a5 7e112c5297f3521039d52a994be89b1dc3b6387b4be5398d7673542df3db0945 f9147a1faa3d7041dd4c83681f8fce6bbc11b307815b2697f02d133d6fe7d5de +187000 b06838fe81d8bc39304fd98dc9f24ebdc0e6a05a363713e028382d77334c2afe 53c32d4af24bd19d1dda8c23186b6cbad5cfbaa6ee169666de3b028473f3d388 7da79dc097ecfc37210e4c4bdd457cd81c4d3e150a775b2665c44b65e09de915 +187500 c3f730a1d3977c557401a7ba920f22b768e9e89924a07598af8f6dc0930a4585 a83e748dec264dcc6494d6ef7c63025e554aea410915c25db93249088c287442 c3933db2926c4b67ca839e3be9171e1e075e9dc1d001d4da8b7199477c673ee4 +188000 4a74ac7ebe38798b80ff54f21a428c40915895bc44a528bd8e4ac3b9f378def9 847a11b8eb71e0b5dd698b277fbcbbfae9c54e55477320396a602a26b1f73d8d caa476f95144ecad27f8d99b6b8f0a6e5d1c247cc48fa9535f4cfc986e0a91f7 +188500 59891ac998632472cdca935fa4a3819fc676d23702621f0c41d6d38fb9e354a0 4393d0b0d5af19f6c123777762a186fd30666e8498fd76468c3cf928b4e6fe1a 38f92f653e9cd1415db7b4f10650f767133e43f413173f20db9689680e33be76 +189000 7c43d2b882946af37b0d1b1e0b3c08a8c55e83b9d93e0d3c10ecd3ac7a49c1c9 0a5758bf838434644aedcccdb7905d4bcbd576745f82e53ef74c9539b9c95cd0 a78379476f62d06d8e3817387860f6ca0e409869efc3e674332c2bcd5a543ac4 +189500 4913cd6821bb3900bb012df98da308582c7f99c8907d1dcbde5caeeb04ba1abe 83dd01f4f3544a1254fb7b6c1fd8654a10b4ed99581b1058c79ff2a3a08b3ab7 d38a7cd403d69c3d04f3ea66cd135fbcb77393e3d8747c81a43ae30acc6fb763 +190000 825d6842d16dafb7b6d3fff172fd176916478e6a14c50efca5e2b6990f7c2299 0d7f3744d4e18d9132d3bf7e94b9325900ad8a574c6a48b04e6594f2ed07083c a485cc141b0697e8239feb81967a584aacc332c4f0c9dc689fa9cef5a7d52a32 +190500 b7dbfde08c23efe184956485d0c19d62325d121b493560ebb0d45321b1832b38 227eab03ea5949234a281ae85657bb5fa39b271fa2218e294c4dade8273639eb 189b8d34a7c89ad218babeadbb95200ea07e4aae2a840f432ce29180cfee95c3 +191000 e61629b5f59b130b4e6fbe4d3aa8027d13aafd890ac3a16b1ffeb1d3f590bc5e 7736329d7fc7d226fbce139fd58d1b21a41381b442fd62f1d03bc53b5580f906 60f22a08d5f6f33ecba45cd1d80f82b42029db3809d1101c43ae3e9bd9efc2f6 +191500 06e8304e59c8f386db5f89bbbf524959e5674c1f560121ee65e04b5902833f98 5e099e60aa5f56a39831962822390e897947b435b4b84cc2f45a1e98319aeac3 93ee0024748a9eeb8124bf9b5c298f7402d928459d5e2b8c5e3e241812da7fde +192000 7a94bca1896611bedd44c28323897ac0b065d2832d36000b51da6d8da42ba38e 640f07390bf420c0f65d0b59112d66b148df416f2a139f961bee379df0928bd7 6196ad843e24ef1aca394913cb15a1a659e12aaa7b7cda6d0b87764480164193 +192500 23a1270346e2cd8b1439b2357aa6d9967285d727963656385edad740cd66922c fe551350fefafd463b3d5f47a53ab239b346bebeaca875c6c7a87d42ba976bf2 f354c08b5a5faada798b058f860e779260600c5a36827b2e00280fc368ddc671 +193000 5c7ee526691d558d00b30f649c4f77ca4c595742f23e389ead78633f8ce2dd35 68a041f99854b2ea4ae5bec9b030b48ef9edb3aa89a144bad9c7e744b234d409 f54a673573587b3d9d1274e6e0b65b29cfc204724c6a7bb9cabfe362e28d04d7 +193500 d03957be53c5a92ade2f6caa1e1999c3dfb567084580cfc618fc7bbc6758fc1a e218bdc4ec703cc01b2ec52b860b2bc0ad51b90087088c9cc0e58736d625de91 b68bf79767cfeef3edaec65988b827e286bacca28042ce3114d56658177c0cfb +194000 d50b3435b1f5fe763970370fe9fba1f0a5af9e9a9abe295e1e61d8832b43ffe0 6f3878f181e0dadfd1dafc8b2e75c73c6ae0fbf97a6bd1894b20aa93139cfd80 4ce93b30284eaa26b7ea61bdd747fdacf2c4537c609924824997f748184fc30f +194500 43f28b5c1af708ef1725ae8b0e4542dc6c6f33585455e6763038d93b37992cf5 6792e3e7d2ee64a48ec47e9fb86823aa726ac49948e3843d43ef80995a4ba7e3 59421cc124edaf1dc5e7d717176118325f8f75ca3e9f7c4c506134fe9bb90cd2 +195000 27deca29e0f720fa505c64794b7904c2f15e2b2bdd539f6066bdbfa8b9cb16ae 53d423505456177cb9e6e39879e51b1a473abc363a6df7025d6c523f71fe10aa d8f3589f66e7c921cca22ebd1c9145ba10dc97f8d9aa1d738877d55309bcfab9 +195500 4996255d3fc243ca9b29ed6f5e7cb2799330bcf2c11e42ce9a82c017fa4dc47d 1ee2de24a628d83a4a9b796d5f3c6c65d0327202191554d0362ceb1418904a26 dfa80cb7bfc802b65a7f4a655d21701371798227507205908dab6ca115e53e2f +196000 c3861c14add9fd9665a1751e1bee488a13e0156bbd37013e3e6a8da54da26550 4da431d08df43f875267b70903b275831281c28902749fefd4bbe544989a910a 45a345fa82f8f2447a738b7a6489b6f5e64157753f7f661e391e4b6fa4b4cff5 +196500 9e85e9ce7c9f969af748556cb124ec97c581e6ed8367c4c44e8b9b12d5495ea9 14f7254f9bf3d122eadff425ddb06f86c16c4a4954bcadb5e99ba6ea78f8f0f1 f141304882870f7a1a54ca77797b0d713ad31e7f287765be87d5133e9abcdbac +197000 387b990115d39fb36240de77081a933eb7d4f8ae20cd72f0dcc162c496717a4e 69c3b4cee6ad5d2d315e2b133a716b8640b170a0f5ea53269343bf4455a886f9 a0ce44475b164c0f91bba84d738187d02ca78cdd865fbb28a5d8f22c33c1e237 +197500 0db48271823bfbbb62c8d9bb68a0ff7f46724dd251ceb8244253418b3089060e 0c2cf4682db25fe743e7e2781ecedaa243dda4d9944edd9d1aec7a9e93b831df 1f3027ed373f00ea7980e7e14bc8a1bd9fe3952af41e078f2b1df32f55c77d38 +198000 c65104e71ac22bf228691460ed6036046fb091eed1059ce756e1056bf149148b 3c3f1f86ad2cd5cea8a979c55d01fe3dfcd5d6ec6fe485c3461d65604ad4adc0 02fc4a02986275f8692e7ecccc1264bc784dcc1ccd811bdb1db098cd1e3eef1b +198500 30e8c038e2a43c5ddc9e0f3a030070380cbb09e577ed7d783b83651df9ad5015 dd0bd23d500ed9eb599249629cf07236244c001e0517c93dbe6debe262e7f4ee e6739a8f4f4e629a08189b31048e82982103b7d33ab0b4b56c5cdcb1ea2ed1b9 +199000 4b4e61aa4eec7a39dd94aae2c114994fe32185c72050d3908b7fc0860d41458e 0443985e3352c7ec9e83fc34187460671679f71a3eff263956dfdb306f4e518b f6611077832a1c9dd956b563c1b09457d98a2b6b832d3788e30d8319a1026fdf +199500 09e62ab674ae8526370e0059097c80cbf382fa098e67d4a1175bada96d5d87a1 83de440f57fa996de35e346f73bc616137946dff6edd47273615c0a7d4d3d7e7 681274c8b4d83a3eb9b76bf5e984c2dfe0892282f89c2be9fcde7921ebb62dc0 +200000 cd9a04e20b651dcc4518ae71ff5b0c8bc2ed5c6eb3d5fd2196b1e636987c3a95 6160d970d27a8f799d74d3e01630761bd655268486a9107be28b128fbbc9dbe6 e00de657836ceaf31f5bde6a5751a6c4c475cc23f9e78a01b405c06e106b5414 +200500 03609721a5de60ab9175d5cf5b9dc444f8c9d420b94814be90e39e4d5411f33a f1625e3d9d93f152c9e351928677f1e8cbca9c6812473c759de6216321fbfe53 d3beb126fd503a82fc169a7b4b2c56840e2313847bfeeb520a91bfc0bfc721b6 +201000 f1be5c8c40f967dc2f1448f38a7e7e6a47c6d7e6ae9eae150762642394644f19 562f88889f723e4c4d2a7b0f8b0eed383db6aa34c8e094f88238526206af125a 1e62d55da61d7571fe187cac6157379772d99a15a967492074786b5aecbe6250 +201500 668f7b1463226ffe529002e0dd28b813c68396ed381a5725d166691660a0383c 0077ebac17ba34e5d77c492ce62473602d1010d21a99380380dcf52f1a6a3318 fa3afe138a87f31ecbebc18904846de2b7897b9759f7b6c60b230a8101a30e60 +202000 60ea6173bbe62b24b704cfe2b6e1d1995dc8854d618fb0e42e0c712110b70e50 aa3b08fccaff9887aed03778827f73871a658dfae6ad99b7521142cdf8e86dd0 4e95ee5671de054d13d166e8318a170bf440ad2ebe6182b2e55dbf12025c171b +202500 6de298a7a2fa7ce5bba344237129f982b1071969df56c15d0ca2c0fa39f9c1c7 dedfea5340d820409423688ebf7c236cbead8e502dcb39af7686681b1f4cdea2 cbb2326e4c743de2d0834b486e4f8b1029e96db14dde184423a72cbb284b4341 +203000 0e117900e8f0bc91b0279b83445b8d9cebb374dd81c84a52f0b3e6b94c880e1c 74c1495fb1f720209dadc85404e75bde143a59c7d21ecac61204734dacf63545 b42a2959dfb5317c241e686bcb83ac1bfda5b7b87fa8a0004cf069be1193ab9a +203500 ee347878394b9da8a6c11dcad54882196eb1a6acd7e323154167e764d57f00b5 6ef1bef22de744dcac118ba398ca60424a713140fbb76fe0555f1e89369458b1 33ab652565274a6f0ca4e32152c5ad71cca5e7f2a0a198ef2e7af6d11e7663a0 +204000 a687e4d0cdb3eb142d1acaed94b80625e8d9a9d472545ed1dec3c5e966db98b7 728306e941f0ebde00511bfc3a30e50cbf283e1850ad4145f2697671f14c5775 80256fc3b1e5468981bcc71318d368520445ea6a76654b2c4ce3c8238bf405dc +204500 c813ad2efcaa352e786ef9dc912e133bb1f32fe408a54c114152223fa3c4e96a fefab4b9604535559292b1b31c4996dd815f25a8ac474cf8bc31d0c176aba97b 904cf3d024345bc0cb59b2394adea94e9f9e0b24c0b298369fa8f13a4a788443 +205000 b67beac20c8c3dc2e07c7d88d8bd4922b8803da3a5cbaec8c8b0a6601314df69 88197fef17e17da657552b7cc5ea2e09377fc466d37dbc22ff8a948509057d63 b9ceb088a6bec5d9ef64b9f3fbea11d3c74a023589afc1d03d9ebeb8dd171f76 +205500 0937f7527f96ec479765e3be263f25130d7898056813dfdc67f3f95f4923f2c8 716b95c3c62dce9b236cba23dfd9dd3fcc68cd41cbe9d13d6f8349503fdc3827 33ad2f9960e74628b62f3c9ee3ae6158c811656b69b093eb7224d9e7de52a58e +206000 aaa70022052f41b2195c68a4c77c11b78e1a8136f03477d310a57ffdcdf835d2 dd9991c1a086391127322eec9667bc193908aa869a012b36f0968270c8c679a0 5dd178775801ce351cd81f8a943ea7226c58711a5c51e1e1a23f5697728b9d3b +206500 7724e797f7f8e157fe2292c5a76a018278bd7bb95924932df289d975c4191c6d dbe2029b6398ed4f32b906956006915345255bfac82ddcd79e44848574c50d36 d1b982b2945accffddfa88f88a6ecca1857e5004ba7cef7c764c3c348989bfed +207000 3d779550ba9dcc4e29106cfbd2efd9b22340432345c0df139ab31eac25a45226 cbe3c2dd884e9ed7a1dae427c3d475a8c9f3c8803d0f3507398b92a6cf5ddb96 e4f050dbe983ce3a4c222639bac89a731956ba1b8d78d9ecb04c724527207e5b +207500 5484677fb6f857f8009fe0e371280b61ba15d0a5fac08bad41392dec1f38c85a 649c2c9faebadeb93551828d590b757b444b6a54b40298519e5aa8505fd81009 7b3fee88b64fa8f3b491877f080c4cdb756e70d4a3cb4731c384f4be754650df +208000 cf31a458b286a4f77890e65d02cc506bb0454be9f373a1685f2f6b2b91a76207 22e9abf8f61d55f7fd7b85e0efa3d8a0f6579f43020b19cbe921a79d0122000d a28f21af0dfda5b9461198a4d1bb6a1668ad397de817cc1cba0c9ca092831401 +208500 4fd3fc158e9219659c7ceea1c4f02bb89563c7524e9b8e9f158b61bc82c52881 4a0ec89610a1cbe8193dc195991742ac08583b9c86f9d24a5b63241f8da4b476 7ec70ca3a2fc695421810e24d119812218bb549b078d36d04c272ddf11255643 +209000 d54f4d0b5a8ce4ee97d0ef4cb455ac54b93b0092e177f1532e6513052439e9fd 59a0a1d9ca71393c4e4271d8d1ea63d8f0fa6e8388c610fe4bfe8362dc0fb231 af3eb79681d6c9ab82b6d4110b48ab5bfef942b0fed6354464db6cabe8526e2a +209500 14e2bf16398fc52492652cc0ef3fd516eaffaf2cc3b7f89e37f3bce63d1117de d9a9a12a655ef80cc830f766200a05617bb235555e7cea98818bf103a3a6c1ab c5206760e03824d9bc3897c88f85dbbc62e0c26bf0b399cf3b0b0cc2556608b6 +210000 4e035fb68e9d78b953e76e14a90355fa127db686af2bed4bdb301fc3223c322a f6916044d1b6a16eb726cbd05a2e900f5b9f828625c850cccb699327c22037ba f1e000d5a2879e26b15937259b57891c59f50720888d76ee66ce7dabc3678231 +210500 e9ad24df7fe871c7a87de17e0c091b99a332b47903d8d39da2a18ccafe02dc1f f2cb48175161b22cf3369f59e67941f77675c6109590ad622a4bc476364043a4 2733184c95cd78942b971fc16340175508f01259703aaeb2c8ab74624c1e7f50 +211000 21fc2c297b7bb7c088668fa502215ac26b2ded973796765acc4feaf2bff112a9 e21b83547b49382c15c8fdb2929711d49eb8693d08c0738813df68c359fa2442 204c7d0fe115c292647e70fa3f45212bb876f173885b51c402a6f47c9f6c7f3f +211500 a83b2da994898b752271b844f26d88d300646e04c4e89786f24fb4c7397ce6fd 4d8d8b7364ca603e61da4d09bc9c0b1dbc2373e65f5db2297828aec6395b5991 2e8e7abf5d80dfb979a72d14b5636b2f43a03b732e81453167bdae994b5e0730 +212000 ab0f9dd7169c2b902f4762fce10983fe94e3c349353e189a510781244d66b77a 3ba1a0d61a8b8a750cebf79f5c00362bf3c909f11725bc9e9762f21de08a7945 8b45c656f9e0a66ef94b346f2692ad3cded09857bf55991d280dd9e27e614a38 +212500 b1fb4ee2f329a5664e6be5c85834dd79452b1f89551d599a70852bf49daec183 d9143da167a6553a85f452745577ee6ef19fd21565b09ed5fa6cdc00a0f01a49 dd2aa2786a23ab647fe5806dd1f2feb46461090b4149ede9295ff2dd62ab5120 +213000 dc4c87ea7c60026a65104a0d8a04e5540e3952df79a62e59deebfef6ae235e81 8da8a14d3971436306dba00351d265f0bd06b1f59005f94336aea44880498b5d 1373235a2734e53819e68a14b579b27f63ab5858c92e6b405cd990f30daad0ed +213500 2466c2e233db8e30bce3d5ba87f694c3095fd391b6c38c2edf907a4f97d498eb c3f5734faaf87bcaa9be69122a144ad1f26009d8fce1f859a17c2fd4bc0c2c0c c6eacb28a16d84395e1f13d6ca6de8e3e7eded624e85739f23bc05cc917041a1 +214000 fa84d9bd1c6575cabfcec73e1834d129821b6a94d7814d15d038239cbc4a568e bd1413d32f7719df41ee9caf406a30c8b97e2f875efe7c9ab2fc56555136b5d5 41e83363b59ad285cba7f5b42e9c845195bbf14e4cb3afee000fd51e3b03f790 +214500 556dbda0caa051476bf896fab40e8854a166c7bc416d5f3121fe1d312369dd0c 4e5d7dafa56fbb04283e8c41e18697dac7beddc742d098bfb87d4df1fe90679a d3c7e3f958b443a227af7473a4776564e6f2820fc88db797469ce6824038ebe2 +215000 b7ccb76ed29ea49301f630ca5e9cf200ba7a9388156304636814ba6a6b417265 8392386752e5ac61b9856b95e9c833b57fbbc5717e93f63e3944676202df04e0 fe5fd65400df2fc764107ce9f33000c37d5e27cec021c2db43364c76d2d2d4d0 +215500 a56a071a789afd22ee4a9e4abcebd695a26ff824a895f5291ab639336d609bcf 6dcf6a9b561236f8f627cd567d937ca4d7e6e9df72d466fcbcb505af9bf1ab11 5db7fc42ca74a15514001d9781c8eb72833094b6967223e45135169f12928feb +216000 0e1a9b2d055f2e7b637d9fdeb778c040967a8a2fbe0a38ee57bce4e8f4bb0a51 c5532c221b5cba08f4ca281a247e98d28654b934c8595e57873232111c347ecd d7e521b1376e2ecfc6582d4164d57d89e61196fed40bafd33052cff69f65e101 +216500 9890c0ab7b427bfa46ae90fda04503f1b17a2493c7b36f12fccf0dc010d3f9da 24ba34ff5619c38e4dc516e815af584f4c5ae6518a57918aedb59403a3b356de 2b43b5a22e6fdaef8644a6113189ae7327dbf69e2b53c702bca1993bae8ba0c7 +217000 b282a7dbf2dfcfa4a46938422e557404ddcdf11509053fae49f5add5dd101d8c 645bf6456c36a43bef5c217fd00b1e457ae136d52396e504db5ed9a97e406594 80a8a9c2f44c33be9e641e56b5d9a5a154a2800a73bbab2a0580e214f37c7303 +217500 9539ac7cca0ca0524060e3fb6ee956d28ba115c7ae3f54d5927492d0a43eb49d 21f680a60447675216989ea718c68c63361fab5615c683a7f047960d50ff8873 05692be96ac1ea5432427408a51b86eac351cca847b10c46a7181fb2c46723d8 +218000 dd15ae9a3a001651303c757cdfa162b252b9aea2d1c4fcac645cfbc1d7dcbd7f 78cd6e280ca819c264e6447e6cb93c616f0bd03547259a0f23ae38234e907dbd 2516f646e05b15c638a1ff0ba0fbd35701cf22f4c2518d18f8791ecc77375632 +218500 6455bdb4441ac37e8f0d04b645fc033010698430944a873c2c097f7c0d3a02bf 466f4eda729538e0604472f6c00c4f7398a28c9e59c89602716f611ed8731edc 6e8ab1cd2afe546d81758f4dfd19312cf676fe1e7efe7423c127068f4f91a808 +219000 a8944486d2a12285430d1764ccfa03bfed013dbff38ff5fada97148b883db9f3 5e8d4e1d9d6b8bcfdb3ca94ef5d0f8c75b9620b7bb5f360d8172e1becad9353e a1fca9e49edb1754773ebfdf2dec492f9d49d619d4d39f7591f7b8c0aeeefd48 +219500 adad89636c4dbae0dc680326d95d5a2bec6ffe7baf704f26889730681328b3e8 d17aeaafa2e7a17d6aaabe48e88ffc53a8e61bca58de2e844fade3461f4931e1 8fd8c2a561a09d2a686ec49ed898b43d4bae8383d938b2f7191d102f3c4109f3 +220000 69fc4cb8e3103151a20add15fcd55a9ee3c1f2cf78ed3bf9ddcd0692b78c2a71 25cbfeac28f67981d5d011357c01ad82e097c0d09e77f0746fb11a93329c6958 fe050048a14dd17565ae650de9a772e04dca5e2c7d53f16369633356b18a886b +220500 fb7731f8712f081c1e9f446217bc1882d62d3db40bbe2711a25654e2e74c6cb0 796240f85e38b57a751b19d648938d9f8f66cc8cd2e8611635832cec8d25179c b360d59819b84f71e3867a35356907474f67539eb4d1ec02911ef16bef70ec91 +221000 488df413aeead90e34c182fe75cd71227be759865df577cc6a4508cda9f13213 bce1bde7cca72a43d9d80b03ea33c845799313914905c7800f7672654821a7a5 3ce3b65c898cdac02127d69d28d38164fb235730ae6373487a6dfd3fd3b1a3c8 +221500 84d958c341c484ca8e85984cbdf5ea436fc1564c95baac52ec00e9f03d5dda3c c493d1eeb83f8dad5c17eec83e69277fc98e519c639d3c892faee2d6f80a5fe7 e88c0947ba38c03fcd4661c33c9e2ffa10ada3a77746c6d28d99adcdf093ec46 +222000 24f8be00386b9a38f5507e77e72cea34598910fb8aeb57c5d7fd5b8b082b1d16 77d77f3bc606ba0a8ac17dacf2d6d794bf655c58709a5e6affb1c2238149fe94 9190732d87bb2140d12e5ccc17025a725480f5192563b58bb78993a5dc071631 +222500 c9db027d5a71c17a32dfd7694775edd913f829900532a36cc673168de4b41cd1 c98ee6b634235506cd78e47c3c51ff7f20e2da5be5bc51c9269e0585a77f344a bc2e01c66f5e16c5166f33d813153626b5e29d2f72fd135ee38002638585302b +223000 2491331dde706d72557719b2d51300a41185e0a231600a748cadf6d76cb97be2 f464bf83372078d78b37b0aab9e98a697eb07bca9eb62d65919635d9a62c29f6 16b0949606f4d837cf58811261026d3e7a014f716ce4b8775e94808c33fcb1a5 +223500 757897eb0ef5db6fac3a16b4167e73ac300fdf2126d175ddbfab527fe72e5cc6 8033074e1db6b73e123b62aebd8983887d50385f70770bec207b628e9c945425 ff9e7cd3fdafc513b0522c21678c4b6334872dd9c0487fdbbac6d8bd11b3e516 +224000 b07c519e796e7ca9ecf620e6437128ea8762b00f16ffb3f2ee2abd5973fc3b21 eb8135fbce4a5f3d73713eb67416be84d02239e85bf87dccd22763075438c693 ed89408882869163baecf310923d4ab5bb880d85741bfb2b4ce322c6b049bae8 +224500 4a873566e5cb9ef793cee37c09f7bc11668091934776eaf0cc5254cf8f565ebc 9484bb580ed6e25fec7482b2f708ee463088b54ee3bf3a06ffe06a1892e70360 ba459cb6f5e554cbff0c1fb05d217e2b67c53583b6ceb3f91f0885ed76af94d1 +225000 b4b671d3954ba70856a978c8c173096a9db7ba168c8815730cb445ed0b921f7c b16288a5f727839ad38a64139741eba8f93f33035d294365e841e714927ce5d6 0a54bbd14b732d0e359a9d335dab210d8fe841f5f60246a688ea574a19b171cb +225500 17279999d391f86406797119b105c9f5f6a02678f7c3d34d9f272c73dd77faf8 d555247b00f10b1b9825a09d2692d22129b967e1ff244d1a60a756e7b2d9cefe d5fa227b78fcc9305f36c7e8ea6cf1c3f8af9cb61a697b5ec0658d2fea876edf +226000 94d997cdf120719be0ea6a4eb198704a18baebdf13f65e28e51b49df7de1d861 d3d5f6655db1fa41b2f916399ed5f36246ad98025f6943480fe15e43b0a8a034 c5144eb0548d037485fff77b1bf83cb11fcae1177d23d5883c4b711ba0a6419f +226500 dd41f722e300bee85cd30450c9fd08c3d4102b1095f88617c10b100556c5da49 f43f89d4fabd9330fee3336ad9bf701601c33aad3abdd56eb6c164c21da1ff10 28f53fc862f547a8ac2ba68d6dcd67af9c55ee7f78cff9da296f327da4ac711c +227000 a0e48510962ea5a5f18c8d413b48688843e5cb36b8b74b5e61bf357b43334ec3 0fcdb763c6a77599a872c5baa6fd1ddd761889eca1c53e882b616dbe40de391b ee39eb0234440a966c8d7908596539d233186b96d16cbfe4ba353d3c488fb68b +227500 7f5337c81192ee64e2e1fd4da832f60ba2d89b0336e8e169423dd403d6f76a7d fdebb66099af9283e9c026e1e9a112a66af6e3bb0f657ef78392a9dad4768963 1b8d657321389d19914e8807820f47f412ff10598ae38cc6968db8f07e897cfd +228000 a8779b9ce01000a531f400c46d8930c487ad00315f0ec4ee8acfcbbd02ec9e7a e9b6fdc4d73e7910e18d95bf096bd5becac7b96a9989d60e564f1ac2480b1fcd ed4a46642d2b08d633609ef1e2b606235fabc7b6edde6ddd1b7efba80e24ba7f +228500 074c0079bec868361a58eae22d107577538fcfcd531bd3b0516becef48d25083 b0bb15325aa285bc0890e24b0892efb113246e6d785554e59022c0917ee4c35f 6b0fd05325b08bc3e76624c3965df9639e65cd6a09836311d36ac958421a4b29 +229000 27c38d7adc92ec6c3b2e5c16ddea6cc06d25cf138ebd45a935953a357143cc68 f916d1f8fef52c7532988bb984eea0f136d7c777fdbab72ca0011b4535c91e46 f91af3f0774116fcdf41eb53e3daf292b151d5ca659b06138bce03949d7d0882 +229500 1010ad9db0dbaf647e510b73feb8352b927c1170dd09dfa15fa0f5b9735852fb 7a7b2eb60a9dab15faf8e37370dfcbb6684a67faaf7ec1f50980694c26dc558f f2b26bdca9c6481cc63717041a580e912d81a566798355274a8c0fd318174bf1 +230000 e84c9aa480b0a7900f557d49afdc6273171bfea6e6adee45c3c2c7408c7a172b 1f03b2bfbe709d7b411679979aaaf2eccfbf14b2a08aecb7139b191691acf77b d8a6802d515be3e56d7a00368b1b2621235aa970d5bd42bbe3bbc52610a88dfa +230500 1cab5352d167b21bf28c9b3b0f8cc821eda60b32ce9f2f77de5737edbf28bcda 8867625cb142e048d056cfcfe5627fb7ac7a20a83de0a9fc008bd4951ed7def7 88e69682650794237dadf48c525a4ae488acd73f9f312672149a989a5e86d7bb +231000 a7e7ae0369d5839690ba5cd0f83167cf68e6dc9c5604feddeb986b17cd35ae76 4f7deab8e1ace7033b726836f01863f33677e4ecf1f8a488fb19b99630fd2176 7b068f0bf62f019f82ecf753f56febf8161a14d3fd602ba2c1f3b652831a5d00 +231500 3bf6451daa832303c2242f195ad2ee1a205ca168fe132087ff899461f29dadfd 6b87a643ce4a5cdee1f45ea3ee7fcb9b5df8452209970de76513c846c73ae7aa 9fd201df310afe19da892c9a5ec244ad5670fef388f54872c972099a71d32de6 +232000 6e1ae43ba56524a6e2bda4d769f8ec8e99620690baed8d8d1764c3a42509af81 eff179dfdb3a490f2038514a8ca3c65a1ce73c266f808378d767c60d1a8f9b16 514c7d3a6f929542b5c61c3c2ae5f65273c5fa335c145688344bf30daa47ad12 +232500 95589eb200430bba2e6660842109cfceef9a90889ab8eef7091685dd052037d7 2b8b93e3ab1fd3b12368ba3dcb7b087d84528932cd4fef51ae863dc40718df55 3ce34edc74e8c7e402234d169c5ec387e02cd9fe9ca3701b06c1ad2a1c5dc65c +233000 edef1536377488c20d7836daea81dc7b542347febfdb3b7f0e89ace9a9a2f980 ef9ee2dc8e6eece115a4fa188288ac21117d58bf45921924db619655394ef4d5 791945e15a74ac1375df1076c41b37634e1e812d6cefed1e9bf18299b177e1d9 +233500 7cef0816722fc26a5a131003a9df2d08cfb005d752a7211cf52c6c27acb735ae dc9115037b26543076cef7cfaa03c2839378b0cfcb8b164f883f2f73cfa95b11 fc90108555e02fa1ab8434db732d30539708376211e5f2d4c7a751cce2302395 +234000 da363a034d807c2ec1aab013d8695631a0d24c50c34dc0db04286a1a53fd58ad ef5a49fea7936d6c151fb533277c19b7e2bb3e88e9351cec946bdce22c5ae5b6 f2dcc08b2d9b7b39269b00c9a1ea2af3293a51a7b516308c7e8d28b88692b0b9 +234500 e35fd8c71da099b9f3f1d6017c9b799b6f150e553ef827f83f84b4d62ef723cc b469f833b3d307d9f12fdfcb7a9777aff2c37a2ccf713d2239275f39ccdac37a 8b2a09ac35e35fc13ee005a727ef7284948370812e3a2fb1878a7b12e3139b69 +235000 903c98a140b5e8ce72a2571fc17c585544c4076e6d2b2efa8c58b635adcef6db 5d048227793f68e79facf5538ee5980089562490688dd1f929fbfd459edc3263 53708603f5ccc4ad229bcd619940e473bfcbe112d8663ee4de727ffc5b812f99 +235500 1e0c48356729ddb9196f9bc8cfff295e2205283e468534eb127eac2a8503612f 152dff3242d0914c503c8ecdb376d1cec2426abc09cc99907b1f43b31dc197b3 ba7df23159f8f78ce63125050842c5497c20bf9d746e5985ff964dd329ba29b2 +236000 48c76115fb5c845fb7e9b8d9bcbe2270755b054db11cd6ad6c2ad89152607576 1420e404d7b541a053200034e94f9bdadd705dbfb57532c2a454b9b17c36cee9 f38a89aee24a3a08e18b6f5dedb4cd567f646d7ed3aa06fddcfa4129e4983c58 +236500 76dbcbc51593c2ced3dad33d42a9f8c522f01a21383b227b0e6511c76363d782 f432ef854ed6a03b4809d3ecd8a46def940a0d251d09484ef1b6bcc3271b0f17 dcf2169bf1b7d2d68d675d63808d7fc41a7b3b8396365a32928a367def6f23c4 +237000 8c821cb30e183a3f5a3b28bff8b16d1606566e3836a2eb0d47f6c02af8d3f324 b4bd12526051dd6ba2a2d616a95212c8ab4d6adc18ac21822a57738eb8284e2f feafff7676658b8dbd88abfc9f266df07564bd279c37ed6d9317c9264224feb5 +237500 ed4f21e0bf654339e17083701448309eff81e272b89e00fdabff166cdf812bbd 9d03191f41bf9d7bfe65b5cea79e55f32c57765ed5909e11ef961fa56f3f69fa d5c2791447c14649d99a71a5f6213bd71efe8ac7d56cdaa7ebab49cac398868a +238000 5af7f4d9b69ce00a56f5c7d89de2ffb0df0ae23520ff218ab2330ce4817ee326 509f60bae30c0cb7666f7baf33fedb510f3364abccfd0881671650caceca4cf6 765f7f7eec11f7f3be4461fa8c07e260ca15d5231f0df4106750101ffe2a4cf8 +238500 e95df9d3b7bae4323a4562627b9926d2a3f4c152e93513f0b57d83ec88ad8868 9d0e160a8f87e36e9fc815538b27d8636daf94ae5c8701d323995054446ade18 4bcfd021d9f54456bb843225a6d760252dc8a914aa0b71e7db8bbe57579168f2 +239000 17dd8f7338c85dbdbaf0d87bfa224d5fc13e58aa465cda17eed21ec1e5a13051 61604321167ce51b0c2043524749d385b40cf729814d88e0394149298e1d612b 31e49ef282416590d0ccd69ea1dc54cd191a8ad5aeb3d65be56c96262089be3f +239500 d10a85ecd99d5fa8df9df4aaae9ff7b6360bf0f6c541fa6e1c8d743ba350d1b9 085caebd6ae46fd58b66481d21579720316fca78552121f9252ff8fd5019257a a818e7b156f2b8a6b2b80481fb48ed123e8e037b15dff6d3f8756e4b8ab26866 +240000 dd21b880d234b770079e0478bddfc53646feba611a1858a82be2d68a5f70b5cd d0bdb4e68e287851256fe8cd8518ab06b2f8bdc30984ef27feb96cbf2625bd81 eee895ab9a76886db1159344b4f0274145dfa8d3a875d42aee1df6c4d8c13d4e +240500 4bb3da166c854ac97920a04fff729b2da619b130b3b257fba10f5be47354faed b7081936dea5f45ae555b58ad83d42234183f80123236a1474f1df92b289dbb3 588912e750fca882ac5651cb56fe42bf2d3b39aa255e291940f2fb7b3477cb73 +241000 cad2acf8c8a9802e5c162170b2cb7112447b1b5bdf3184dfb6ffca5d5ca066f4 50a13b720476b0d72efe8fedb30d6c24265a0cef374e1de14df89e3488fd3930 db397f10c56a1c85f49cf2a3ad21119add4671fca5262d41168399675aaceff7 +241500 f89869f168fee009c6b743da990e96a296823c795da2fbece16346aff95cc0d1 f1e24d47abbd5056f7d3fd322a882ef885585d877ebe23b86787fd8bfda5c03b 158908caa9be532ba7cee05944c191206d13ae103310523dba267dae8f10759f +242000 8cd2957d89f5937f87ecdc188f5ad6b275768752b873f36348fffde02bfcc4bc 9e37495c487f19227aa0b4312458907ff749f668a3cd386d46318281e03497f2 be9e5bbf9fec786bbe5de797be25ff3350587f8b9f6e2558a7a7ee39444fe74f +242500 4d84991c165bcd35c6f24e4124e5b93678214af88c683ba82419330162070a43 dbc9324659ca8a138b7f72edddffa009859cbdfe03dd397da0d897b40eb97efc b3769991128809cb16c4692fb4ddbe36638cffbf285b0d2576cfeb5a4f1e40fb +243000 99f2ae7beed98478d52ce8a3e8106262d777e9220d54159cd29173f823002468 f1af12a5aa6ba842b39e357a45bcdcf93c9f718992cc160e1849c693211642cd 19f07cdc4b0a888a48f45c2eb9e9c0b9d7f41b2b20f76184199bb1d5509f298c +243500 84b668ed1334a0f60f2b7cccd9a1bd05b758fcc1d3b6de13314b60b1ce8dd69c a02d27be36d8ff1a07ad35d80e1b2340c042bbfeb7ba7c0f4289eeb8b66ae117 941e486598b5e0e2ccbc01ccbc2b353c73d9f62b9b65a7a6c19d0e0cd0661a1c +244000 58ccb25106990e5eef0f7118707b96402f853599ec51917347012350230701ce 989a5646dc6e9f91b27d9d3f3eee07de2267b5b62ca8c2e0faed6883f1d04e18 9a1abf9c623f17a54724cd6dcccef464a48945860546783a0249155776ab6b15 +244500 60b50cdbc1be5d94c144f682c62cada4668154d94b909100baa392bd914fabfd 15fe02c7705d1c3860305d80ae479410c94dbe8ed03f942dde09d3a3094163c5 feded4a0f87382ea84f1f789e638864fecaeda1c5c16d83352595f9d2bcb68ef +245000 538eb0feb39a02cb69f673a6707d23f80be40a922ef8fb43ddb1782d8bca83e3 ca4b24d390ad10642d096a14bcf8fd51d7135681c9a750a80144b107ea02ce1a 30b1817c8d6bb5d0217d147708649bd75ff6af32a8e17d81c562e17a4c8d0c53 +245500 8e7a40c1deab5dedd03f960399dd0a59ae92ed849f0288ed447307112a4679c4 fe223451b524113b6d13c696681af1a1004e5be0fcd14dba4edf5d43f1b52894 e0beb5d5705be0bc851ecffc517fffcccbeb2972a1784750e736219dbb346da4 +246000 e5410e4186cb320449ee28882d9f32cd3eeb79104f807651b8dfa0164ebbef82 0a4203ec776383111ff8f9ff697c72bd8fe1203d55242790a9cd42086b2f6013 38987dcd959005aa0638e7caf50d4ebe553edbd892c4854e8ff4a99d0ac90d60 +246500 0c2a1c0920dffa7e8a582bb47b121ac02167b2015deacd3cc2a4151419dd8dde 1df603f77f223501d3036d16d2201004c712f86aed58cd0b3d89b32fdd1b2032 4d5324138f4576ee887daa3f45e7b41eeee59b71fef399c69eecfe6170f8cf64 +247000 def0d291743461c8680127c4393f912663ea3e8105026bc76c315de3f7471a17 830d9dfbf53d41d49c1a28631361db55fee2284001c16395ed3046f9a9278212 5944d9c5fac27c3034bc271b35c16247ff7dd0a7b5fcb49a6079b4feff366942 +247500 41c85aad59b4ed9baa25743ed3b2205550292eb7e5e4dac974f0839053d0df75 dbeb22eb94053b3bda3520ea239bf64c51d046da08951074dabeb73b06cce009 2da981e79aa5ee1fbc27622b35ef4bb96249ba35ee4d219e7222a7bf489127c0 +248000 e34f803c19b9214d128703d584947a348459dcb0191cfd0a3928447747b7e3cf e58a6b50690ab0de2e1d7e5eaac39e60495e7f15c0e494797c49ff0a83e80d6f f139662f345cef60380f9b3e62c4923ebd53a286497e8f90ced8a3a03e948f8a +248500 779f30864bc7a0eff2ff65a65af9ef49ed7125f708e923cff6a7a88d661c1688 34ac76a53fca6d0daada5f7f12e339fddf5d654bc1ebe03267716822cbbd0514 a0c941f4b2e5089e371c04426d84a1081972e00f6556b40ec401c4b02a66030e +249000 46d582e130542ed696e49a52224757fbadbf61037d15182cbaee9d6895261d72 7487aaf55ca988670dec71cb5386b80d8975446ba57feecaf64b3cc9c52a18e2 178e37d57ce7da4f4b1925117cc97773475e24282737d91eacd043cf274266cc +249500 87fdc18e9972ab01bd0f1c0314fe017d5b825b2a802da4da2be0c495e8a6c2fe 364509f6a5c984e616212b9a328735397515d8392c612f774a55e8013b80f868 faec158f0c1bc224e1b7f40a5e0d3c1302574d271e766b45b205c7f2d7da3f6d +250000 f345e75ffd358b61924b0bf3fcf99156f97c1479a0b31c53713c219a38846b5f 156b414c9c8d5782e5ff3c541bae9a14641338757b351f8cd7340d91ffe7c8ba f9fb2f646c22ff1d61f307af33c1e989499d9007340b70f191485b1a66aba30c +250500 111446c3129d174c80978898f17b8c14c485a4c92396a8c2b15c76d7da4e4ee3 67bc454190eebae6062bcfbd41b10f18161d777d0c7f1547d9c922fbe59301e3 849f8ac1d68557adc798d5a31397749d9eb37ccc33b91d14d91fb0e6af078c02 +251000 a1d9e94171306fd7e28559cfdfc8be43a89ce142208f0b4a4319177bd6e1821c bb9e6ac2b06ece214228cab806b96fafd12d7fab5899ad4b8f6c57764c04b65a 77d968ec31ab7d473525224abf9ff0361b4022ba8a4780cbd9695ca3954af307 +251500 011ed051ea80d7aa8c5631cc3f6c808582b7bae9533a47a1e9336280e244a66d 5ab6d307a8215f078406e4ef5256e86f30683732743e4e102fca988e3e9bf157 18c51804cd1c8ba5cb28eb6e3123525123e5eb7ce154a1e3ef1abecff63ab06d +252000 0f60353af5fa6f614467ac0b793c0cbfb723b48353e45a163384288db9039860 977d7256cf493f632575935a40240e3cbc08e8b82b9cb78666fdf4e17a80748f 9b64c6052aea790947c3560f6a8bbf66c9f1e4838ba06cd9a9e65a8e5f7fa997 +252500 856aa75176f71b2613ce0655d8bbefc03739a2ea066d1a396f608d596de9214e 6edcec572883a3e3e60b10a312a59c1e4486a0c4a73f5726b7b3cd1fa5ad8a8c 08733b998bfba6bda0e903937f56042b4e19ef839cdcc67b6b052f863d8a422e +253000 135cd797ea002f028f372b545ba294120d92fc0368996f3f0a4a2c3aff5e2178 f6f35b4573ebff09a1d86085a7c5ad8f5154bc67cf6f1b821780ce3f39d845c7 5ffd6a38fb26450294129d892604accf80e1a66cf02c5966a967d846dac8a11c +253500 7e62b3ed039f164bd4b37eeacc05736f7160fbd8ab2a0ed7c8789817ba43f47d 92fe7b5cfff4d6c5fa17c317ba47417e2841e65a9a985499f3ed0ebccb05993a 6d4c21387cf0c1bd29f3c94c024f4f03dcfedb144593562fa918ff26a5d511eb +254000 413a5fd20a447bae48dd74c04912c73ced49cb866c96a65aa447164084dc3723 dbdf24cc5fe71f376465115ace1ebbfdb9382c6a47ffeca175f7b1d71d077109 ae6fc5a32ea4fc5bff43651d04a34112f3cde947601cb41bf297bd907ffbdbaf +254500 dae6ea70719a1798ef4cd7eea67fb84482f58695bbf68106fb1ffca714532549 aa0bf86ce61e6a6801a133340c93e099d26f06c45ea6a7d0303866d59720cd45 846cd8c100d89c35d8e0f031c7c78403170734a71f89b41b599e3204b5bff115 +255000 48686fa37b3f22077cadd219544c1d55015b613ec8c5a4c367b0e32a1d93f114 8419590a10c931fc7b06e4f0c9cd66add2783839c03872569a4d84100fd3ec7f cbdd4929ef4806d80da65fad8800927305d763531614ef9b44009c1c9207fafe +255500 3480ad9060e55cf444b9f63adf976cc48c8e68e9c5d9f2e173d30ee5e21f8e55 22d1784cfffac5b2f3587152e60a93c18c3ba34d5872ac90a1bc249b98aa17ab fa4403617cb029fad549d6cf18eb128fde5f574647cb7fc0a105d1f6f868938e +256000 773459b90dc0d860e1caf2eeb99f85410a17adcd86b9c7a91e282d7375f69b87 dfe7baf5a19c7d41d0be344f1c0648ae6a720b5c9b50d1a1755908da38ca28bb ea9dcf13fcc782c2091ec7e84982fd2774e1e436cb2c4d33a3c12ba41fd3160a +256500 5c5a4002c3f5675ed11fbe0d1640a0cf72150462b9f38f2b6fefa04e2d47e57f 504eb85fa2d5bd399b16262f3ed52330fd25eff4396ce7ce96604c58c835314d e2cfce4f77ced79d5e0a61c0786b810f219329b32f52928bd4bb5192657c0116 +257000 f957080ceb81d1ff1a57fac8d99d89f92332198d332b82ed19f116bb2e4bb232 2aa6db9a7e207b621656e249da6a29182bb6e77489137f185c4adc4b43c2063b 95ccc92fe8b6bc201819f99cab1347b864098aa83aa68be978a6e31d19191da3 +257500 124667d3ac4e97b204a238e688229f21aac351bceaee670bc86b048aa25a326f 0806775e04bc4c3536af5ee7c404d2d53e780775da20c269b0c52258be37dad0 781b0b767484115002c26e4be6d2e903d49c472e9343e422ddfb3c11698619dd +258000 281275e81b624913ab150bb6061bfc3d065c3b8e876c1c84c933d1340342804c f2a8c5a57fa4b177d510bd095fcdf765e7b4c08d8ded22f12c07e3fe85011df8 8cb11b3cfeb5f2714c096137da42e4fad410aad3f856f28025b9ed2b261d9a3f +258500 99b3f45ea656e722d919f59a89e1ef97e171f1422ef68fe6ea17e84496369d31 4b30ebda14fbb69dc80d6219066b66d8716e2235595125113444f28e2e0e3ee0 4c7cde3753cfa77c0d82c7d2d292a2f17a82256aadc556c814a029e707274c04 +259000 a3c8b1010cff2df85b748d06b4070653855a780fa89c1fea1df8af1b99e1f71f 611c731a6c76c22ace3e93b064a4f73f2debf5f63d270a9a3a59a7a46544d6ba 1cb253f4e69ad610219c674194d9471a78c4128ce6ce918d7830b68081906b87 +259500 6f80b9fc49fe6de69d6ca2ec1a783fb006b73c7e2fc0caac427088dc31d0b527 d9ddfb40c125b781b7780845a78f6c90c2b887b8c28a0a930ccd6ce7020bfd3a ee8cc1c3f98c7f8f083ed4f4de0d6bfab57f3a3bb2b9f688289c66a24827b9db +260000 d3f3a0df265b13c30fd6d529da8a8628c98144abee10ac66feb2d98972e52f54 31ada4b62db504d84fed898117105427ae16309d45de494c4a266316f8225d25 fd7360e574377c4adcb394b707e421e770688a6fe8bc08c3f3bbfe82e78d6182 +260500 10c9f1214c1a77cf5d4097d05a4ecc043d8db4dc9ed855892763104094e4a1f7 273762c7e60334efe73f1325072dd8829130ace31287493f4028fa9c22c98619 b82c870a9178e80f581b4f92c6cfa3a78d0729db64312afe731aeb3150504ae7 +261000 bed3ea15e53cd2a4b2f8d515efa665b1552ac7bcdd575048efb6bafa8b3d0f0d 3fe66c2acc1cef4355c4ae83ecb34597060c44da2aa73f0a51618f4f6956a8e1 f5b264177952358c8af607060f3f962564d985d79b111f967db973a5f71a933d +261500 0e9b83d06669715a10a70adbd0a89d58a56a853be8c6b4e6fbd3894fb865c224 992896ed5c5c7c262850a9d3f7b10ab729de8fc572190e0c08745ca9aa2a5433 cbd1670a1e8fbc5c785ac30f2586d926bdd2f7991015c2d34257ab8abb55c299 +262000 61022120589859e23c0c4fa1f2650329f44feda0823bd30d597be34ed030c86a eec28d8aa336511816f17eb3cbff661e6fb35bdd9cc7a63e9ce830e7dc1261bf 6cba28cd036be7ffece24c46d9a749b6623cbd7ab6f09e0ec4146e8ecb8d606f +262500 957872933b3a7c22e527930d65220a77ebf04077130f18703f4d9eb8384edac4 e267fc444b94c0c3e8312c063746af1e93887e4f9affb11d03d5728885b63cc6 00b7841dd209bbebc1b00f9f36fcc7306cd43639a782bbc2cee0976a899eb42f +263000 e06e647a254beaeea41f7d2cf9d88531c5193df8a75d4f1d8df403e1c2a24309 5aa9aa86564cd18ec3e2dca55315b46958ed92e4ed8710e33ecf3da9b051107f 1cdf59e22388e040a20293b6b4c72b2589bb5efcc3a0dcc4913bea664a475551 +263500 152388327d812eedfbbaf6f841061eb28be5ed87dc9453402355d8d06c64011a 23552aaa4ce81d4ada113f198ba4c848defa3870f8093576be677c2e3c92c149 80bcdeeba034170cfc2c2aa7d93fc60adf78cb65098e7dabc3496f1dce11b4cd +264000 ce414cd76a86b1af60c778ff9e5b04c31464198d303c9f1d53126cfa930e706a 2a3acad69f31b7b30208aab2b1bd15695cfaca2d8aa20bb2751afcb5755ac0c6 49fda7e1acf5e17b38a618fcdd22e97de446ba8d276f3950bc9984b4951c44a4 +264500 d259e8637b4b48b373b6a1a7afcd89b1056e2adda59b819654f393e63ad2653b 31bbff6e4910bae42fb446c184efe8191dac8d6a86156568daa369230b5198d3 de1cbb25b85663124fcf585ba74b00c41ea23a87bb6384a515e0a08816ab6b42 +265000 ead49b3a388fe07616d1a8e8c391d50dffa01899a7444df60d4d2c40fd8afaca 9fa60617a2f080f521628ef3d754f1706c464fb43a8282bd07ce2ed26994be5d 421c20f2a014b14fe6c5ad01fb72e7469100e4d264bf9fe77258920c9fc35df5 +265500 6bacbbb516631a7922e9a988fcc5e102d6f58601085f09511601f4672a3fe316 4a5b61cce54e08360b9b2e338f39f45ae427b2cc49034fb0f1e71948a7eb92be 015b0e44b26ae7e3aaeac859facff0ba812e7ede3df26ff257b3ba515bd04da4 +266000 b6993a4fddf6404fe544fddf2df238c999366b43e7a335b81b4524f9aed32999 91407232bbaf55fa658262dd6269b1ec6c620eefab326e556434fa1d0d64cd95 bda05714512e418de85a00f6a90dd00e63f5d0f88fd95f96c02d692a9439c4fd +266500 a22adcd41d7ee4df6deb8633f53d381e9826dfbc7709e68b7b1ad5d71e8898f6 314feaaf908e8a8046ab6eba7cbe3c97aa478b2ad93c39aee7df9f5a72955db4 3cb8a12a98cda65e6dea78e1e5be078c3634bf5b8ab03b3b6ab7b66b30b9fe59 +267000 d270af2ee0a98e7e407e39d50cf4cd22005faa34480d638e7a6b7c10b8d59e4f 024ad7c62e3a9ab757d4905bba29fccf5ef435e4471fbed49ef50f6f9bd1075b 8f092d967cb25c5b745c65302fdf334662797e5ae57f62f19c527f5cf05ae1e4 +267500 1fa94c5777a0fb5f2c0b89389d3b537d5d6465bfd432810fc173dfed7a666c36 b4e5805d093717d9c5d8766b1ccbf2791eb10118c9fb51898f0c49273c3ace31 7620763c114241b5f75c35dc6675896a50037818e08d594bfe490d6f2656eb09 +268000 ef3af0dbba05b3633b87348bfa9492b90d0c500f8427c2f83e485ddb4e326b7f ea130ea23e47338355b0336648892d7c09251bcc9df307a7f587d7a425d2a741 339197172403a19a3eb4efd95b1e39d141177fa0df817add3b9310dcdce7d715 +268500 f7d6e8a528849da7d14e07869feea84c406697ae7a16ccac0ef890aac5fcf4eb 489c417d04b8a41f630bca15696e7a05ce36d4d216c04b1a6560db25e03e3cdd 22291189be339d88d7200e09e4348ee5157cc2637368de6c14d0c902d80cc94c +269000 0237cc909ecc6a560183034f478c44d9f9fc96d5a0369b89d5f9510676274123 e84c666b3a8122ccb250bef7b603c2afde722fd985aa36be484e76368f13f10c 0b2fc53dcc0fb9840bea67516680b5eae925125aa21fa4ffbf5d9c7d9e955e93 +269500 d342e101fa8308700ee1a663fd05b05da014141725d0b3655a3f0fb15da83771 93daf70fc7af5e7fb37d973246c434cc834a37a1fc69fb522f9ea5b82ed2bb2d b144b04a09760b2cb65ac9142ca3ee6a1ba87d505dbfaa34f258f8dea0ad26bf +270000 83e4f6c8831be3fa7b6b6a0aa13805ae107ebe64f496be123a4ed9711cd69065 ef10852638bcb24c4341161935a116bf5b764ed34380ee55243a35c938fef7fe 836224c011a17009dea9d2ce9842cb7d19c1b837eb26f57aabb14a786f198ff2 +270500 557c88f51ceba0d2dcf7bffe8ee8cb308f8fb2f14998db8b6c23764d00d756eb ed1e1382a827b3dbee6c583053acc263ef365697a9325d3ab3bb60f80621b66f c2da9b6c6ffde7b4040c2d4ef1a06465e07e6220b140b6c04d4e85259af35b16 +271000 8cf965660be26838d4edfc4ee6c9e3f700c5074a0537edf09d19fa8b25f9297f f717dc6ecf1404858433dea8353cae36a181baec3c8ab3fb0c8eaf17e76f2f46 3c1e09a5c48938b029d8232814e48f169f693f208d8d251c3b7d6d78f531a09a +271500 940439c29f8259ebd1f7a7a76f9cb7c34981795365d06cef15b272ceafddb513 e013f425e7b9e0c919d3a8a6e584fda18d798f64cd32003c79d1b9acffe92f8b 8f104372f8900d6abdbea8e173ebe003f60baef8214a067c4c037f0e599612bc +272000 6aa33a0d087f0a56f911acfa99469611ce6a9fc336e2ef2ede07c854c0ac34aa 34612581d8665965d653cd9736459b2708141168a297c9eda4c73e64ee4b3511 d065b6b1de7d2ed8f8190bb76d73f699f56b67f7bac3ba3fffa313b0368eb791 +272500 e165b1f323ea11ebff46a9365e5c15c736a639c87e0e7866a790c212398fab51 6e2b03ecf9ce016d375afd28e4895a3905c5e79e64a451f4b5863d6f8ad37c15 54bc63721296bf1f6f2990f9364f8991089b183b646e0ddbca6c1b31451b11fd +273000 7e8e42c625a39262e7cd8ba81d6042788c5685fb7e1925556bb81d87f23fc9fc 60337941f27f0191f55253642397b4141c09a3796a2e8c972154c90847a04adc f65c9be70852523b31c7a92f95821f306e9017297e04d39cbfc4c8dc3ac0678e +273500 50d2fab64d92e6bd34396a65ea083c254392b73b806c9c23d10a64fa2046ef63 def5f3f2d73ebc5c90d4a3e5e8100e51e3144b63d3de0fed9a6393ba3138f62b 62b9175a2c605119fc599836a2a00fde40a976be16043bf98c0773318e8ad14c +274000 86afbaf7b386a0a5ca9199f42849ba58e03c52c3e14e4796be5a47bca65c3e56 9fa018f6e78596557adb6a6294c3ed8c02e5b07835258d38d00714b662cb88ad dffa1e76e920169f88dd0892436e3dfb2a3a6daa1ec42287913d5b758ce918e8 +274500 f4a2f13cdd599a02991bab088d21e7d28d907caab124755cda5b5da1a0ac3514 3e9121bbd05409156a601f33892ebc88a1d832d59180e591e571cb8bb16d0233 77b22ea80e05caf4ff54cc45a88682693fb8d94f28c18084ec8f8d5774ea4a79 +275000 a655f397a1362429e51239e663aca0a3582f4a984001c6093e48c4e0a2e05941 c3a045ee8c5239615793c006587052cce7d63cc81c2ecb2af75e67f3c53a8ab2 380849376c9a323fb3a9bc59969eac627adda0498cc3f60c6c8979be719e29e1 +275500 b3b6e311d0f5bd738f2502c2684af690e0f71c2a4c55afd5661d069e604ef3fa 0690d029ffaee874f0407d12906116c79bba67f9b8378a31334b25483daadf3f a930052ad595d7b8a70e71c48aaffda01d38e459df8e0c1887b07799cca6bc5e +276000 f24a85fcd91ad6a82056c8a76c2d3d5d04070ffd7d9b84a94ad0d6b8acc0c187 5c21716aa2a15d63d306717b47e86748fb203faeb1c6b19d63a5349176e9fa06 50e49772aa15a6a72eb61487d735b18f15f493cb29145911cadc97c1b684bef5 +276500 787f090210f18af487a5a4f9f284f1d3314fafddfdee64723d3237f55d7597b7 3fafdf028ccf9b4ccc043ab7159a37ec9740b5cb34847a6ef427e117ed86f206 b1b6faf4dc475c27eca39833e9e90e8608609b31ab38600710c7e3ff30242b19 +277000 b431470e16022c9e3e58e772bc8db6482f309cfb72a197a773b67ee7ffcdb756 894962f8fdc8091b4f15d60a3ea4de232e7921227ec9092e4674338c6d0907d0 e5e101d2a2f32a1dc051af8913cb1d611024910988c45848f9b079d9621f45d1 +277500 d4f3d44e493b537d6f5a6e63e315dcf5031240fbe6b6ac65a76eb8c35f5db13d fed8c64ebc096321c5b99ff1d5d424c213c3e75d13375645f37dc5aa807eb57d bc8767da1df224712512ff57acc5f836153fcf3d33af4a488783c172c9a3a4d5 +278000 4f76c78fc8d544c1e8a0d0429f7dac32c9f0857f906944503c80f58d809d25a4 eeb4b5d853e4a976e994c9e129bad662bd03d8f2c7e78fe68bdbd47c28480ba2 caf3543690b2c0033cadcdd0e989231ec6ab6008140bab3d401030009eec98b8 +278500 494b9880d486e1151d466eb73004b3f226ea90b6127a4aef1b3a90edffd4d0ca d9b63101013dfd8dac4895a0d5ece4c62702aad7cdb81a6b186e530df840996f 18fc3d39d5ca9b8910aa153e2e32be9cbe36ba2d0cd789fd94e9676ade8d8be9 +279000 8722865896dd4d2351ef4e4def382a2e622b1e46ad54b3940a16f5073bb1d844 2ee3816538cef7b1d029887af7e39d60cc1e336036fdbf089439f38cf13ebcef 0a761847f3ea4261128d81a5b9f6d84c6f443b36e93d8830d6fea779264945eb +279500 3423afaedb970d2a590a0f3e023906bef4110f1389bdf54e2c4620c36b72a3ef 3e7446b32ace025408872375b1f3111075f305cc83f615ff2c6133e49ac96d88 70e66af4ab3048775db66647a98a51d42511441e864a3072111bb46e10c305bd +280000 9cb8d7f3caee172f2a7b8b8c2bab3fd01326468f8b5932bb88921e06167a0e31 468c01acf084fd4986b21d1c0e1defef6a874a01b0ec21be66098d53fc4244c7 6d0f0593c36f3b294d32c15b7e79002e2f15d8781ddf9781e59bf6f868da084c +280500 6cdf47d170a6a5e57f6a9cfef7f2239d4f15a61d5c37f5b44a72188aeabd541a dc58435982155aaba2de5c124a9f441a90a575c9cda3f071fc9c4a3c9db61c8c 2d49762f68d9f46ae49e6589818814e5fdc346b8e23ee41bae3595ab2a88f7ee +281000 3228123dd268365939c7fd5d9ea6a151b6a95825ee1a49b9fbf3ab9f3ea45508 9320e6e8aef527e622e610ab13eddcf82598b3f2b744f6e90727ebbad920c080 e9a2293b4c692741422e626e36d5a0608e04ae7a39a0d69aac2d95e95c783460 +281500 a35ba852d6be87b2a614ceece176b04152feb39a95e52e641e7da7c1fcfd220a 547cc277e5a3fe410e5265d8622bf0ce0f722c39c23b3274458f7f99e68f0ef0 ed34358e2dcd89d40b2b86b619603a413876b29ed1cf8c9407c5817ef8add859 +282000 2533068b9c436719d1eadc4bd7e3e805ebd949d57e75cf5e0b17321d109a9a10 1ee93f862e7504974feb14b488a590aa9221ebf331beae0786bebbc013278457 2cbcfcf0cb47425beadf191db745e5664af5d6e8a59a6da8087c260c28a03df3 +282500 47262c1b2c424270254ebc4ad32694e51ff4c09d8c8da9e944b17ca3bc734e1b f940a70f96d1369af5b0318ee86f9902bd122036ace273643a8aa0ae7878764a b7c219d4d68bd82bc079b6eadb8205c9f3a4f9878dd3fb4e593d6e1ab39b91df +283000 bbaa0da5024d6e74becb1d0d62b2aa4a8ce1c3bcfe27c587d3c89b581f22b893 b8f67f07d3e46ae0436cdbe91a4eac1ffd8a8de111cab322c4895423393be210 d3774c417554f65595146416dc39836999e63d5d4a7b617554d651ad839a6810 +283500 008c22a6e8d0b46e6c785736f6098de9ac43d5d1964b2103ab383498623a53d1 77b3fa5d6f930d2da8b1171725e9f6e7ac340b88637955083de8a55a0d129b70 5a762918736f2d6090e47bfc68f71005c8da87518f1a60cd7163c01a7e70d05c +284000 6273a37ce3e5fe2c58d6b1bbc1f31822f9e1f78e434d62c9aedf2c6c18faddb7 0e5422505c2be9b93d74f39ddb43b8f2a6cebccdad41d3e631e56a5c075622ea f8daf28977a24e392a7550087803586900d30f35b34bca786992c85c89b6c2be +284500 6dd5efb7d0636ca3212a14ec60bdb9940d355e75c4c3890958c2120c4e0e92e0 8adad9dc3bad71a55635afc41505883ae38fe99f3c96f021137e049a1b829a55 bfa9f23723426ae1b670779900fd77b957248dd1005f0677a51329ffd15b6a3c +285000 7d49941cc51ef16e04919b3dc5c5ec87b62e98267f173202167ee9a359d8a5b8 d947bdd3999caf548887208f2049fe528335634f5762d6882d4075dbbc6c6b1a 12d4187421eb70562d96f5a73261abb5c5d75bc8c3fd7baf5e4707ffc76eb470 +285500 c06cb12bcc248f8a0c2e764e2c160d85ca356ba7235faa143eecf42f7ac2f7b8 7ef16bd0db693d3ebd90f3e9152a8cc1c420a3c57dbb6bf02a86cfb3b1d19dd9 b30a3f94cff5b1bb3f8a6c7fdb4aecc6a36260b71670214078600b6356aa1127 +286000 45583c3f15ca70ada0a0c38923bf9a7c63a82d7be1a05dd2d3d098fa6040b522 d497cde577489bcf9ea8e08eec093ae16e80f5c58ea09344c27bf55b98fe3fd9 7ceb57dc1b782604406fc32b6219e84e88bd52e12e404b2cf064eae6226826e6 +286500 94f13e245e46c93614627914bf086bde72751bbc3f88b35877d73bc28bd4a7b7 83245d666cc2a32058839f630baf72c0d96977e7aa4fc400f58e75f2f9ecf78f 6b4d11e78c15ccf29d5162656a219cfc84bba07dddb0af95e7e14051700022d4 +287000 eda15ec5157413f65856008baef31e5d124c511a95716b1f6b7364f5e3b5e75a 5ac1908f2739c718feb04686b434dfa4e7ddfd5213d9977137354ecfdf5eca28 ff3f1fb5580aa6c748374c95e371375edd5402d81f092c2f3f7f99ed01050594 +287500 9f7a944ae0a5d2caa33f72042e674d47334445b2f47ac89da38e29357301a060 b7fca600d7445e8470e57c18e2eadaf73aae7abe888acdfba5d458197ecc1e6e 929c0c6c37a26aa97b8256619da4a06437cd8d9bbee1fffb21b2f821ba40f626 +288000 0853047a1ac1adb0d95427898e88464c078405fa22ec5def178eb5de7ad31e02 a3369699142afb6a7da295ca36953c883d67a31d3096d158486b578a6a585fae 4edf3fac88f835729201fde959ef538f8b9f6201cf20427862755677dda1bd30 +288500 eab408ff9eb88ad56e302df11a2513c1dd7873311632911cfdfce5ad4f814066 4f39359784cfd3619082b590cfdef0d6978434ad01885e66ea50f2d96abb2674 4d88e8cfd4f195cdac4908f10c06ec9c7409ace62bb2b765beb593f6db52c99d +289000 1eacafb1bff01bc0489b29ebc39bf137d040e6641170ce3dd89ff6ba59abf97e c8d5fe21e49f66adbcfa0c7d71ddbd5bfd2210554315f1142656f3802fb9de86 95d1e5142422e26d394a2aaae4e79d7a5e6075b1207540599527e424d3fd9025 +289500 887dd7480f6c7ac0983d66c8af20fde72fd415dc9341eb28e1c017cc0ca046fc 64cc676cdff6225d910a798088789b311dd78932e090292f289b965e35812bfa 6a410a3735e9b9d42e2ad8024477d603f11e3bd9a1422ca3392bc99aaee715e2 +290000 d537cc92d4d860c7d1e74c77d63543d1ee28bfccfb33a3798b8fe4ee6aad5fae b1422ca72d6adfc0c8ac92b75dd68b19615bf27ce351c07dc461e4a483a01d36 6e13f50e1bda168ba72506ec99a6481aeeb6c6a4e934b24c57ed41f95c4ce8bd +290500 1f72a0f641f0e7c0a14ae8aa3a90a93130a302bc82616e7df2eac6cc893f8826 7cfd6bdf925165f98609e9ac990d9c91cb484a1b0c4f26181f519180b2cd0ad1 aedfc88bc4fea62174ad9c47b4da51e0bb89cd0d2977932943422d5a4cb51827 +291000 045c570b2414764749905e61329694b5feda76d2656dc07c208e0f163e8d8be6 ff11ec49560b7c1264cc610daaf95d5bb7f581edf89568fefcc83bbef13b5835 ee75c4c5048c7b58b1f03fe95b73e6c4deb422b079c13ee331c62054d729c3ce +291500 fd55aa9e9dcba1752e4c20055a1c9b6ac46a21a3a932f059ee574f49b721f507 3575b8d9556832ef3d4d929787f0ffcb147cb349499026edc50e4be282b15863 329c508a52886135ea917a7ac4175d57ba7fc8fa928b6d9d453f10b1d1213637 +292000 37273300cca125ee3ecca17ef0b26cc7880ad9b6caf876a4eb5f248743433519 9e2e93489d99a34477c9e7e60d7a971b7e7a14f2b1d1af1d797d95c945c26d08 3aff06b73f04c09346166ee039067088d9f424f3b1ce7c34296e7e5424ea201e +292500 c6d6356e96458404221b2fde26482fa42559dfd1caab1b600f045d8f6a2302cc 5fd0c22eecda0a4ec51190a6356fcedb96e3d4662a03d1c231575dca131b801c 5b5478d4a6d58150d08ba008d03b0eec8e78fc46cc198d43a2d962b0ac19d5dc +293000 d3cadc149d4b135ec11e9b97cd25d6e1caac6560b16c0d53a798fdc191519682 e8fb2e323adbb30a6ac4a40239c68d2377e9c8fc2094901d694e0957b9815cb0 54527162bbf644ad5504de900d11b3393cfb533aac73038b6652a5152ff977de +293500 a0ebf3b0b17cd3dfce121b5a4466c2a60a9ce0169c79aa070efbab912bc0bdd0 c9da3ed914a818f8973e44fc8a4d450e68d775dac064b9baed30d71db09323e2 3115f86a9da7e78d766c7945f8482567b9f9e23e7825e1f3a07c5a39dbb94c40 +294000 492dad282770f45e70bc4cccb1ff2d69568a4d761395515f41d53d0d703db481 7c090581b9e3e74b2ae80d821555b83a563442f01ec32994b87b8794c8a94dfe 5e369901a873b8417c9a5f998f055a33bf962f6fe0dc054c4f3e421e23c75d08 +294500 8923473c7806f6175ad2be0cc98c4066e69dd2acf8e7f965fdcefadbcdcbc930 689e66a64c3f66de762b38b5cb0593b6c0f076c84a04823cb1f927f5d6601c12 b64cdfd0ce81f7511e0efd94ee32e02252280ffb38612fc41fbb09cfbe65b4bf +295000 3d5870c04b03d0cfb60c9d47169b81aa5c669fcbfffc602ae51b930391d06f7a 34ef893941a5215eccb47786b0d108e5150cee56d691cd6d54280afa5ce5e85a 9a909a02091159a4c6977ee981a8386a935a1b5d6f2bbba1192f675a3a6ec7f2 +295500 96c1ad430e0ca606b9da9929ea3e6644ba7d42c02371abd5d1a1ae099654192b 8e03c6f39a7dc904f768bb459ba01c623791992208f124c37bc679e61a49fbe5 65530d71db0ac3f29161ca58977a9a9cf8ee3383924203208a0f85ff60567956 +296000 6407e9c420afe4be97d10102c8cfc0d7f5ebaac40f6d5e678cac8144f007fff0 d19593e2ea6bc1c13a6a3269bc9d7c6ff918f0a01dcc61daac670b37d2d80347 f6e6fdccfbd9394a5b8261e3a23f91e9f68a08a442e39ac4d0c7d971dbee8e04 +296500 1f8d31ccc299f2c5b05e93383d8926862fbc09ca5b01085b3a1dd82d5d495d8b 31fe78d77df28d71d73858589dd74fd5362642fafc9c8d29ba137126bfc0fbc3 3fea4ab883e22a92a3040592c7202c45fdcf6abb271e0ef2f5bca2c337b6dafe +297000 9cfe512e43f2cd52ff58f90464a04f076dfd0d12d59cdeb100818f109a9003e4 5e47ee43df09cc31576cd9b0440c619a16298d39ab9264f639b5b9c86f8af572 8c0565ebc2d8ba4bea6fb9ff082542adf2656fba21fb1fb9a237ba73c92bd8fc +297500 95a02da1b06b1593ea08b020b4bafdc67f5e176dde40de7a1feda249571e53ac 43777410c9686e5c56891eb7eb0c37f2110b339e5eefb75da0bb28b78f3072c9 90995b05bea1c26dfe6edebf055eac9d8d67d5bb99a25b45a7c70c86ec6b578a +298000 0d802cbe03a4b85c23624a03bb35290b461d8d9dcffa128de936649b7007f622 b5b3a839917d03e52ba179edc51c12fe47a6dd9a5c57d678299387299219d164 dbdf55e36a6b24cc6ee06dc1de48c38df924a62fd30b08e60f01d04e41f625b0 +298500 7e4e639258fe47ffca25a4b7bc7b908cdff41c7e1a737abfd45fdea1ba62ec12 a8c88f6180fdb40fc4524197c5eb32ab9bfda23b88c4eda4a422994710030d1c 754859875fbead5f6bc020587b66511c9e853cd9ff27a8940b600584870a4617 +299000 d2980e238042ab1ee113dedd25dd97fde37f474e6ea666efc83ad169c7ac4cb6 5f89ed52f8866c340657985291ef23e18eb47e0631407dadde650801b632c010 78ecdb589efc3612834eaf00b8407fe1e5aa47f4b361a358b11fc686246b8266 +299500 a3f56b859e1362c88c4ff21ad8cf5c799c2ae565f46f15bcbd275e7cb0fbef1d 2a189688c70b29e449f6b3bc93fe61d4b2eef5af756039f90fd745b47bd74403 977e42fb9f0b3caf99b4caab3ebf3b593771f749c528a8da32d80ba48171d917 +300000 5a2452a4745eaa9cd3c1c42b7e4482193c4f7c3324ef185a4d0a403d2002c0a2 0276aa15dc1d6f0d96dde0520e357fb5ca4d8469115a894dd76e4a34d79b792d f945fad38baa507bf58a84d4fd333200b32de4b3ef2d6f6e872eee58f4e2ebfa +300500 d02571cc76f7cdccf536b836770aa02a0d238cde89f23f767fde8e62e2648735 25fc046b62a57b71347be8c33dbe9d201af1efecf98e973b35294f32b745fe25 b3eb3b176561653fcd519c66bf5cbb766e46270b125d23a8629850293ad8ae46 +301000 b8ef5fe2861b8750589ed344c9d8edc7ebb9630dac0ec507ce09bdd532af32b3 bdd32f8faa1bebe0c4d250a309d8e983c5444f63b8748eef76470b980c2542c1 eeca0264e569685a79cdc0cecf89d2cf3dad1571d8be44e511e6ef8c70698744 +301500 573f412e4b6a3a7cd2506df938810bee7029b9af102e096e83861eb3b29647a4 e8fb5de4c13ef24efd099f7808c0952e287aa23d51a96d37ca919c3fe08b9685 5b71da4b99e34534688a2189be42fa184431d1c7a65728b60736be85807fb972 +302000 18b4cdc5a75c82496545009007b5f488aaef67892f6886bb36ec2526f02a5501 c8898b9f003e3a651e963ce212412e35d3d825ad2170cbd1cc56bcb1f7a0c4e4 c2d335c48e85d4b2b4ce1d1e01016e53cc515e252dbd262a78a970248cb021b3 +302500 ca57a75391cd670c7e1ed0fde565c1c15d67ac4fadddf92549874fefc3a51c74 08a7221ce567158af54cd9ebb89e6cde68430c185f6ae18f1c4d7001970f0dad 9052843ea255f0c302eecff974f8d6abc74280a6f283d93b2253fde0a56460e3 +303000 e6dcb8971d8b0e379173bec442b5e465d02e700b30a79598de9be17a5497cb89 41c38012157119f65a5404f0e62a7656673f033eb64e8cf4275bc81aa4d88805 96e6876e63aacea65a02d3ff472db7a6cb2a36595f0a964b0e44de222e03768a +303500 e737b5b4805e4740cc8c50d60ce3769621294b1d20ea8b1bd3f3757c2a37e1b9 b5aba92d8014d56fa32993c21c908b42330c6ca382631f57162cc63aa1b842a9 7eb1f7d3e3a4a67f7d206ac431fadbf392a28d05179d9c89bf8670568b265a7a +304000 9e5aa8da5821d8594bd9ed376f69dc851e5a7e0b4cdd755c6394f0eaf76d0e9d 225f9b063c89eac0ee1e3136e644cba4f65fbb475fc5a0e2c1fb66270f6f13fe 57088e40e0af0d94498c02f9a08890126063e2a75340a6c47efb79fcff0a092e +304500 45a43ebbca6f1cd31a03e301398c2e9e9d15f1bf91db745a7417b4d8f25ac394 4246e0afd88d5225b8ed8642d8337681f42952d0df01a71aa94d268790755cf5 10ec6bcf6be4136829f4f735ffa2b6ecf32cf58b509032f99a84f45917a4e002 +305000 153be3e755e4953c3810e08165407725c11fbf92665616c708bd3b824e973cfd aa39085be20fd4450a1a03bab45c09f669a0a50d84219505b7077c0bccdde28d 2c2a42b022dc3f6814ce6df5667be0c2b2b2319c726008f1913f5ead0ce913c4 +305500 c488fbfd55f3fc873ca49d57111f71aaf5a42c4bbdd720c0d96a5dc66eeb6736 546e53c9ec8cab56e41df87aa26122e2cab4077646b800b63134a712a1e3d543 18a0bed423ccc6bdd266dc57f917e1e8ce9476f7a4edd39832451d6b5621ef98 +306000 83982570d251358e02e1b359a0d95b96b9f64f3736dd823654d47da633d48708 6a861e2b1c87c8002bf0794ea718b6be98b4d77ffa95a22a3decf18aa985bb25 1e58e6045bf77bc6a9d9b0151d0528c50ebdff775080472e225ecb3429351454 +306500 96485ddc1d2d81f38a752fcf1ed3d7b734197c472e8ccfb0eb4ce3101a473394 068dc5f5f5064a475c7c84960a192433e9bf18098d581f0877066c60ff0a8861 9f58c14bb3a4c813730ef2a4eaf4606c6d6688519dc2831e17dd9bd30999e353 +307000 0d209df0e3d2879d8a0f356f7d4041d6e0825ed0b33011d5c8db9bb1ec0c7d42 1f41650a79db8f7bfe188f47b7f1bb293ad4f178ad4cbea99d8f87876b68ce91 f81ad79a2c76005588bdce6f0067b4c4b646a4ab66ddbbc1b9c9d0c9f0a55483 +307500 aad6c7f578667b9527223b8e4785e9a6739169528d9b0bb741119f224e0125a3 d56e00856dd907339c3959733761bf3d2ed206bdad2bbf9d49e8ce6cec4be663 a376a5fce9cea256226a714a82cb0d71e7e1773cace180dee21e8cc96a4cd9e6 +308000 1a02c273d30fd2bdfd3c0391715a78f6223c944db913c846927b8a20289ea527 232e616645960a14c845a721665ccbffe5a70408ac38dc2f9d53e306c40287e6 3b07c2f02ba7fc2380635d9940e457db2f4f3cfd0c023e997110c74366698a98 +308500 b5f04f2fd81500e1f7d817b94c566b97c38cddb21041bc5ad38757a1d11c3a74 5596842f2ec00ea253eb5a0a5565d21e871a511caf4a40f7e559d089ac67ae08 546d23c82d0cc5671004032e63646240364929fff8f455146650de9ed4bf4283 +309000 ec31bf5b86d611359ba7818f0926b3314c13e7fc6be4771e78aa66c65f308e1b 19be4c08d59662682dcf27d7cea164915e94d1ff761f8321d6302d7de2bafdc4 f4f65a7dc7e658ae2336e13df29e9f5897544a9e4524c675df9d990460996c20 +309500 a40c3dc8a06147b339366c16bc1a21d4841ffffb9721f952276c35f6ebb0fc67 161fbd3c4ba1d443606832471979959ac0281462f897801dfc9e4a48d03df741 7694e0b93a2b2c3edd6406b8b6ad715c99d62a1c595f925596dfd343ca3c8bad +310000 10eeededb4d54ad661d257fe3ee8b383d88ea175da4eca06cb0d2afd91d705aa 82535ab42a3a4494e51e508dcf04f233df0ee6869b14f12c2eeb3de7d0d9bfb0 4573a6b08dde9b2e032125118082676e73366419cb39e394c47bed550ebea7d8 +310500 5937e9322a0b8b1886bdd639f3fdea48392c3a1f3ce5c729f4300307b30a9858 463320d4b753e3deae3eaba1c7c0c81de49d883a7205d34efc6f933287bec340 7c78e6d8f3831d83191c0f757628cc26c5348533681592c0ea35664c8e28512b +311000 106bcfeebd4f8d313bc06f691e30560fc6d5fd4e8eb2d3aa6e5e553d5d7d6769 efd1663f7e472207765e064537779ac8b52090326f6afcfbaccbcf0dd5c7cb49 393147e3a4392a43bae029a6c4ca33678aa619236fc2231d228a60e7ec7bdbfb +311500 81c0cd746d76874a8add01868bcc5465d7ff0a28ef2ba742b75c6c89986ca3cd 1e89778081b0b13e825bf16daf61ee16669826b50efc794cf871ea170399ca1f 52aec7d09759e499a9ac7e6121448a74cd8c268f2f6e541fca8fc6b685bf0755 +312000 bdcec2a9a093b8c5e6a3f712c866bf78e720862b26918e7387d511de18af59e0 96fb2b8bdf01cf8b391a87158b880f38acdf15a6f761abe2cfbcbee83478566c ea915f8312f50abb1f93d4d0548b30b4c4bf908c0716b636f11afda31c278ea2 +312500 a9716ae91f6c1577726c38cc4fddf8a39f1bac41cd1d9b5605e52184e573d6c5 4fae3413451a71a5f1e4ad71341035c582aa1aa721ded95eaabd734137ddfce8 64e176102a790cc4816fe4510450bdefb75cfe83407b62fab817b0dde33e73f5 +313000 cfa985aff09b9e7f22b17a600cbc428dc8e2dbb9c2b22420050ed8dd4597963a fc3335bb9389d77b4323758d39d7391d4896b94ad440a66b178b9366492fc79c 617fbebd70243a76bf7ac49007d32f683cde4914c5f322c9ce384201a1e50af5 +313500 959ad500e00153dcd9d8b6a8cf1190c799f69d3c5f6dfdff026a5d78ca5d0c5b 711b49060d7eee4f08a198fd3fbb3c611915c64cb12c8152210e9c4ffbbe9c0f 8c77050cdc2e2babcadb760c0c3ae04fdb8c15cf8bd273575a4e6a678d2d1362 +314000 ab6a7acb2629ccba949934209d7dc9cd895eacddcd7143dcd7eda19604ebe05c 3faeb9f09e3a75ed2247e4e6352c5744e091f5f44792ad20000721198a075c79 5820cea058fb71cfeaa1e0b97ecec144f54f7645c12a7e3a3601598dbd49af82 +314500 d9527af7b2e46e049c738a9d40f7720d8ac2e8e94b847cb8884d922ed004f543 03476229cf97cd0f2813169fab1ac07b9648a4dd86ea864feead69fa34dc498d 1367767bf0f13399e7fcf36703fda084a2e84a058bc7c792ed0e939863c67a27 +315000 626c5f923088c9093b00b846a1ee92657bae30a36370f679804743d1decf948b d51b5ca87ce3888f7299e3f2c0ab7f3e28afeef234f63337553c972f6e688be2 c2b5bd34a86888ab91365677eddeb350efdc08ea8e7a0412d1625a1e2a2c68b0 +315500 2446c74456b4b4b216b760d567abed176c12c2f474459d6be711490190904e07 23a8dd7d4d710ef6a23aada5e4fb960bcaff7873416c6b9904e1cf61c2abb0d9 682141b8f01b129962a351be4f513c57b5b9e6cc731af7d5e8a4c2ecefde252f +316000 32e55b2ff3cae917e3248bfdf7ebf79cdeb323cacb54348bfdd0b1f411c92186 ed4b4d67a3f55e5e3247f48d32ff231d24ef6970f8223e255c2870aa2ddfc92e 99c2dbb31a927d7fc58e2469d9d6696275008c8fd7ce8c4b7a763d451b262e5b +316500 634fd61f515e6ab677e142e73668fe41e462f25351383262b369e1a622bb9784 0f6cfcbdc1408b6bc3cf64c897fb67126affe7e82ac682707d90894d0c6768ed 907b1ad13b42c90eafc0f367ee58f72687e8e9206dacf4b7363cf224be8f0b2e +317000 1a8b1bfb7cf59f0ea1d7141f2859a289b1cc0cc312836f5754121000a5a08dae 189e9b6ec139450bdf78eb6e37a63c60a13551e1b9d0ab737051cd5dc29dc445 d6c457a968c9fdf545c1e3bedb35878c5625e78020149a213ee94cbe27906664 +317500 d2d2e1c03ca763382245658d9e13d60db1c11199930c6edffa504cea704e9cb4 5ecf2ae923e1b0ad4bb52dda4d3c5b6ab31dae5a1152f40688992ac56cf7c1e7 25ece3bcea84121fff756ce85ee8587c1afe2677fc24b9fb351594beb49e890f +318000 14c481ed71e0265d9971041215ffa9d80bd9ae3d8a20bdd514b3cb15e6d820bb b83d25bc14861317c60d2a38c2cebc995004a3164e49dc4109d195ce719165a3 b90c053847352df09121fdbea59b636a257c21b6230089ebaf9cbb7df6f4b0c3 +318500 fb1bdbe68f6fa03555a52cc7c70086b585d1585bad7e7f36bd7849b20bd62d7f 56c93b2ec1e226511dc23b53e7c6992905a4c4875ee9146558712faf39024595 f69310ba42600ab030dd00a61fc4614bc7ee33c8b0b4a7b3c739c81cab9ee01c +319000 3d520676419671efd72eb59b19a912dd30419f5d50f9dcdc3faa15797e8b78ee f0cb1c494644102763b745ed186810fd2fd2443abbf4c8ef02dd42e20e344e35 e38b3874c6a10de03ff946f37ea26ca61047c7b3eb133af49941a968e8f84535 +319500 e6f93385e77b36b8bd02e95a7be1daf93e43c2c15df61ad7a53cdf76581c93e7 8679904d6abde60c2f8b0628024a00f1357357852ea5e0085a8557cd55a3d5b5 fb8bc1b7eeeb5277f551dcddf5937bec026ff0d1e4007aaf3aa31f2c531166fc +320000 edbd0041bf7c7fe4378c089724a0dc3d91bcff7efae1aa5a5e9b1d914d9f4255 83d2528f44d5537305cd76560b0fe1da24549b295e84a37ebc9f7e442f59a2d6 f73ddd2faab0d9f48a5847489d5ee6be324d47c39797d98b05acad0368063fd2 +320500 fe6af92a7429dc15ded665d91c0280feddee060e7a12cea78ab54f591a2a97c8 3840d83015f1c9053f2a74305ec9aaa4ab9c8fca66c62b71c898c0d8e40f94a4 a5b40bbe9947a9a6dde0556b09fe2861d8cb80ca2389995690c1a4a3f9ca121e +321000 09fbf5bf7f04579822b0643da9de72f9ffb4e3b086334876dd7ebd4a0b1e5456 3d01cbb877ed01843faf98fb687aedfdd63b6eef204d7a08e5177e93b6315237 29a612c741f988fc0a2eee429ced3d48018b415ad9be263b05f46846833a89aa +321500 79143aebef47a364850164688450127d503fb0b5fbbf6b3ff422a655973699da b65e2511ade0cf401a38d1089a5ee4a0747e003fdc2c29cd48e47b288d776801 56d1c182d92b89acbd68757169ff8935bbf5544a916634b280965929168b37b6 +322000 03aa6946623b9252193d58e6dd00bf586ad4f57dc8fa04dee924b5c15d08d8ba 378b057486d0bcb43313d5206b5e08eeb06be740ceb84456f5cf8549e46157c6 bd11e7da95ef2ae8209685205c82a739873bf894bee4e50d6dae7c6b81772cf2 +322500 cf8971a02d54a830b3729fb8f1d1c283135b1a7e30d5cfffb4462a2472467d66 233e6d4bb154d5d3fb1739a4e90a258f0910ceab33eaad183fd2108d8ed464d5 7fbe3ed0761dc6172430d30f139157c8b898502f1634307e4f3f08d49f9be590 +323000 8d6c05ddfebc0476b7ea506c6edd8b1e7a1f04f46d3d44c404936fd8c8c97089 c8e2bb9126149c636285107b6b51a2ea4dfae6a9362ea82e9a01fc5b62317e13 5ad60ef0abc2a5ecac539d9f11d0c77c0cdefabdab5a9b5a4f839ff5d4986002 +323500 f92d520784eb12d8ae3c11ad1803d5dd95a497c0084c88784702a5acce66ae41 81e2f522cc756b27794e1472df684a598aa925938ee87027d455dada0d2835e4 c0a590351ad91977c743641c25a96711de72eb7afcae92068bec7d39044db470 +324000 4d33cb6af695638f89500645f741981a2b96eb2b6f1361cf4915e9df14639412 0d5d58a71b6fb721127f551a4744091aaafc4740ce74e1e094783488946bf46b 95d0d5cff5e6ec05e646c3afb0267b14cf1455be7cc94c7b2b99caefb333a913 +324500 9cd5a93ac51080a0a3dfa6e7612adebfd307a7c2ea510d033368490c6d25b7be 046e088e42fe85a8f29cf0c61d1d7c57619c29f3a5574cb7284374151fc02f75 ba026961f26ad93bf8a1bd29ed0fd9c00d3b8d20bffedde3c7656344ea5e7686 +325000 ea1bd97d2e59f6bddba189466ffe1e7be63f5574f110d5b87ec3e0294b2bfe5e c4d8725f512f352599b2a7506b3c52e78012eded7fa5f6bfd99058046342b2a6 2806e0b32c301fc7e7b517ae6f3499179296a2a56e71256b70a68f44a6c18b41 +325500 df8156f044118b84c3e2482e346c5639a19b2f1583944286cb9550931c3ca0f2 4310bc5bfec110e5da8fe1dc798b18d1b1453895c70554fb4d52dd7d6d7d813e 0121cceb434fb22a7fe131aa8e3cccddaed1db6365159c2a4540a3e82bf89af8 +326000 d46ca9a4ec0e9126c9b570d00f7b47a005d51f25d9fcbf0c4ca71a29a5f255e6 426c81fa951ff0ceab76207fe576bad3be2279d802d5b95b45881c73827a1241 aa8d073b426c4a1f76a7fe65b5f70ef93a2257a4d8736432f524e67f5845848d +326500 603728e060b7c7cfa603aebb548a3362364f3ebd83b07742458a412777ba9259 16fea467df6f746c0a430e00b12d568c7103829328a2bc9b57fcb55c74a66bb5 d919599180ec29d9c60387ae68bcba2f0c88c9ebe8876d351ece0fe6189f0753 +327000 6913cd3da36dbaf5c6d407da68f46bcdabeb504269ea70c0cdc219590355796e 745d85006082600149a72c38c32e2d378917153b7c8dbade476f6ba32726c893 f30e90e6104c58c79bc5edea2d7739d2a788669f2c969f8cdb1fdd6116137d07 +327500 b6538b2705612808867fe5d1da0fb00b6257c3a4314d327b0c6403facc8c06fe bf9d4d5ad9f15c14615c36f8cc7ae29defe64971c5824f95aa535c1bba7083e9 839b723581c717d4cb889d7e14505634ab4480dea58abb53b34bc47c6975c5b0 +328000 ff013ae3b0bf04df355f954637c6ca2510479c51180977a99af805bcc8c2d63a fad93d54a8cd267fd2e63abf1da6b26f2f9bc1febac401d4731af0103b31fc6e 88fc2b74015e76da36ff1ce8cbfe4c3b23d7c0243c9295cdbb451364fdef1254 +328500 ab64d04f26e2164824afa50c1b5592c172469531a20f35a38181993a087a5cfb 24d35a5eb7accd3545888e4c525742d90b01981447d1c2969ca744181e4d6b70 a030745dfc07980d9daf81655a705a35c78ddb6594937b505784fa1528a79a6c +329000 79384d9bb22811755a4bad2ca7d238243ad975b956019cca645144215ead0547 295fe151911572801c0d4e1ee4e753852edbf6078d7bd798dc5e2da10692e7a8 51f963e7c2e27a31dccdfa70eb948778488463162943bd74217df26ed9ede3d3 +329500 1839ba9cdb5db971f72defa707c006ef6ebeb93dfff2bf36ce873acd327531f9 a930915c8a7d58ab4774dffb87fa36a6f9b513b466bd73e5c96965f85ec3300c 7f1a0fd540c40140bd7f5d626f51ce2998064e9809c43719d309e35e1ff0dd4b +330000 829b9c203a0c146c2794aa0ac22bc71033ddd15a68959064526afc2722febf94 e09093eed9d282fce0825778bd7d2c9415fa5b9adcfd2263e7137537d861d29b ac77c200bec1912410ba921f77e306f6a09e4652d31514625ac78dc00bc71c33 +330500 740e9f27889b06a301e355ef7dee62cf10dcda17d4023c157c55327420b308f3 a298a8255a0b30782c5d968988514e0437f4cb34a0a2f7df8475a18809007d1e 9722342e209584cb9eef0f5f5c57ff8545dad281d39e9bef7b4c0eebbd3cd3df +331000 e2a4cc3a53ac8a24ac52f6fc574d0e9fed0d240710de0694ed5656abfbcbec46 74e67ad885d1f874c4ae7453085f29d254c684ebc71eca3af50f3278c9e1c266 43828e2a6cfa59da76a3aead5ae91068ec8031c348826bf11846316f3c475fa2 +331500 afdc42adb73a6717f48e35b3b51bb13dc6233645b8a4805723dd771062dfcbdd a3988534eac8b2c3f5d557d1277440783c624597b8b922df33b6fa38b824fc33 f6269385ecd144edc5dd3527e373daf61488aef4dfde18101b014e58ea3aa39d +332000 4812ec71190df534e5d8d4965492cabc3606e51c11e4f9181c470a779926dd7b 3d1fb3699e9f859472fd032915cab01de53232e123b1e4c93db2871f7c2aff6b adfbf39fde89189f36229f39dd7cd13fad00b9486a0d706ab9c19d4534e2c17f +332500 50ae97dd398c25069522d5eb3b45a2332fd045f6be4d615c7d36c7ccf54c6c18 0bb46697d721417a2217fb4e632513d2ff82f34287bbdd732b9e2f893ac10df3 298e9c841af61baf161808fe5ff29c268490906feb3a7897d3d433d1d369e558 +333000 fdd8f58aece53dd4f24881f1007cbd0ed25d9f3c62f356a00dc92aa68a13539a e0ed76c2c22a2e784c8a689e1032cf00b65a2702f2b3f025c78e2d1e5190070c 842641e07f071ed697b5689501d8455969c977fb6327ec31523e8c600db51fb9 +333500 5ea2791919a4000f9e363e277b7522fd9ebc9c06ee5fd9dc15e4ca8984a2d8d2 69d3bcbe827a926dca144c589eaa175f16b6e523b487773b93fee7b45a5a60c1 7fc573e06ccca42108fc016d4c9ee7d0bcd607245fa871470f4b034330b5b71e +334000 cac1a3b80353133e863014d138b408202c77a5759cfc5642546416d73f66ed84 9005b02c03c93c41c6c78357f4323a3234bf12db1eaf36e81c1077a324f7a07e 2ff0b8561b95225125133dc2aa1dfa52c4e816a4fe8347b84e63ef6d3167f25b +334500 50861ba6d952e1f0fe4dac891ff4339ac5fb7094205767f2d6233941d2821c10 f77408c3140c620c63f8bedefb370397dab67077b4168c628d787d5b22419aa4 d55baf24587b88808b8e35834c74869f9d3ad0ffdfb0d1da607a0f8fd8214c84 +335000 594b37798c188fab76d6d65c058115b58757893ec32173b45bfc618e8c857fa8 fe50dd76cb7dbe52cc6a9f6c25a3497dc5e4d141e59ce1bafed04367fb155b3f 61b2a970de4379841279c59bcbc2ce67ae76fae42d5e5ef2dae197bdd48f07ff +335500 69b0bd40b74e7fd15be354b734717bf197f1800bec85120b26ca21ea5ac0255c 58cf057f1edd07227964239e7d220b4a6bae95793694841f7a06479c5e5f7420 413fc049ef2299a39d19574d01cc36c85a63d99bff587482e26374b461080fdb +336000 71631092dff7d8d09d44bbf35c187c7cb5521c7a5eddb1422f790e52107b6797 e3bbb2e549a6c857855772ad5317902ce52231c464fa78a107811c8381629a49 5ca7df0ba49c0bb880a55258a53d084950bf0cbb4259987f0920e1dec015f247 +336500 ec3497d60fb7d85cfb349bd96712903aaf8a86e6d746f8187a54a1aa5b7b3d51 dc276fdf1858b7a7600213f9b06d4377dc53ef54e112efc864006d28c6cba3ff 5c9a0b41ab2b10fc7c757be7c2977e61bd48f4dbe79619d6f1656ff0a81278a6 +337000 70b67fe1ffc39b65d7c3834439efd501fcb9e5d31202322a878be2cb78f741ff b91daa38e81b0b79bbd48c50f9d5ef92cd965e729b075e10b270e29effadcc3f 6c505bfd33c714e5bc7702ae3ad169ea244b89bd0e5becd96f0d0284c28cc07e +337500 c5df2f17757c5cf77fc421904662468bf003326049de85bec43003d97a5fc47d 29d4cbe540e3ac54271d12308edae379b59365521ee2f09a6585a82a046d7550 fb7918c3fc90af8f8c951c5c1c4bb29ae06a1b57a35e7a597a31e8636b59d5c8 +338000 60ba652d7ad31c96015323efbe454694c5ec72dd732c8f4578ec2f5d072afbf2 2e3a1bbd3ea4e0f318830e43b20d53162ab6b6fbd2191524725965c549360550 f9495fdaa8cabfd460b7f8ab9ba36870eee6d2a0f3bad67fdb52e79a7dd9532e +338500 c898aa2617812d17eaa3f8ee142c3018fe2807862ba6d06f309b3344e7d799ad 6bdee06900bdd6c83f8fd8538d75af113af8893ff99cf9a25de6842d3f0d9889 25a5a722cf5bf7d4ee4aff66a6294274f598602717a0ecefc0be192633c053b1 +339000 e0d97756042e78b1c14495a68291e5033c39c56f37a48adaccaf350b12f59202 913f62e783258b88638a7c42b2f403328b683f8c657520ab723ce2196af69666 bd0caf46efb2dcb6e26d920ff6794cf3a77b592a7a33903efa6e2108cc6b8a86 +339500 1dbe406aeef28cf78b7d43eed5fcdd8c9d7d6d11363cb7e595d7bc1d1899140c 8cee4f37f98fc3da1826dbb96aa525a49fb1fa6db5b2bd64dd3bbd4fb7d6c238 450abb3653fc86852646e95572ca4653c1050de7eedfdf3fbc219fa400c52342 +340000 99ed171ddc0aafa8a5b6f9e5890822c34f6ddf4bf63f1488afde10526c74c8b2 ffe05de29a9901370e815a782c7478c3075f8444ff473b20ff5a2ab311a63022 abca9c6b29a08f99c78109f92296e105ea18e208af03ffbb7ed827393f634603 +340500 92da105d515c1952ffbdcb5f5b99acaa565500d8f4b6e45aa093b61ae53fb7e0 852c42d37d42f8d2c740e57b8e9e769e72445f57c8fc9d1f91e62f029d7d985d 04114d48ae342df3b1994cfa44fe6341345eb49b8d228fa0b77514f00c719fa1 +341000 da401dfe258750911b7264ccee0de1b53bd7b90f63d73f46ad5d5914203b59f6 84e7b57cabd661c1cfb68407595a6a9607e0dcaf68f74dce2f8487b1f43a6ac4 e454513ea741faeaab0bbeaaded3ff3244e8e2c8bc53942ef26efa9012ca49b0 +341500 ada69a2ac0977672d08682d195934176caaa7de0baae2f3a32b1391ebf550eb0 cc1d077aae6a1c18f60c874525182f8cc211cfd0a851381773cd0166c108a43c 09ef805774a86fd01d17e379b36357093acca1ea6c8ff5c8856e12dbc82b1ad2 +342000 ff83fa02f1e15e52a1e6ab3f8690bd9c4bcc7f3adf77dda003c6871283b695ac 5983b9dee33342727befc15d5982f9ce987ccee38fef71c34c482c92e062308b 53699f929f82af192f093ff8b7cabe83778ec64db78584a73f892235a9eb3db6 +342500 cfcf80f28aefa27c6f09f71080e4af7bfb33f94d1c47e80633187f80a806c6cc 08f62f928db36fa7757f30edd40f93c20dc43c65c693ca5de4c87467d40377a1 a1b4bd9ea2f7d8b01d7e1a761f09abd0c1c89ac28552fc0f2cb5e4e6666790c1 +343000 55e1b51f72f048231b675c90224571930a59146003b4ddd3e883bcbe4c8c2685 1f6c53f636480ebaac6569f100e804de9a604dc1bca0a626004ba9852f2fb546 2caa3fdaae8801ef2aa217390696053529040ce256b839f3f3d26557cb24db62 +343500 3d1f67b0a5d905f15f3fe5a7a07aba456ce3ce41422a3bd94f92fd19ce7960e4 4201088ace85294f87bf646209d2e9cea09ac2587654d57c8105b016ed3adac4 06928ab5b470f9bccccb6292549f48341536a3e0a28db92e2d8f17198ccc0557 +344000 1e718e4e82839b50bb5409297dc94bd783264f1bd3da639f2e4b5444c6765025 c2e0bdb2e293d2940f99295b59d2fd9b57a02632605bc66e4ed69de4e26c4afa 93c559c784cbe4d7df210f059dda5a5b7ea35df91b63704ad483680bf53eb9dd +344500 aee9558284286ee6de93a1456fd3cf6c81ff542b4c1eac2c7694b869742572e4 56b70751d01bc1925f288a0af1223f309b7bac54e1cde463ccc9667ea50c9ddf 879ad91894bdcaa2250107f95879d7cb97ce26cfa1a0d6c71b91689e41879795 +345000 852cae52d99ea4f4f299f1b5f4a7629ab0d32f8693f503cf74a1f0a31a9a80e2 a627a26363ae216baf1774585d1159977d378f34b54119670620bb82cc9784d1 9b6d95864a083bed38bcb6eede6fc4a8e0b6af52db78b9ad59121047a6f95858 +345500 09a3e1f7d56b1662f10470c2497e662495b62065364f40dfefdf8d34f5939fce e4d96a1576f516b5303b60dcdded21cb4e3f382f4e7c4b10399ea4b6fc37670d d46d62b87b4809283a35462c2841b606094612d2df79b3edbe90042a3d43cd3d +346000 3dc0fc157c00c40ca92c8125e818f8b5c6163761b0c6955a88eb48498b1d6a45 6f60e0950cb6f6ad48e5b56e9e94a680ac85109ea90ff94df6ccb58adc44d3a2 354c3b2393598bc3961d45c2cd2d8600076ee0ad3efaf582fcfd065bc75a6889 +346500 bd5552ed2748d686ed3540c52ec7a0f97b839254c953074357fc019667d69188 d1707671c71c75edd986ed69fa0d8462f1d7aaea3e0b5cf519972cd3ce7d73a2 ec6489225bb34ff2c7560d204f2772ec37b862d9b93642faa6089b8e73aad020 +347000 68b383fb101b4ad08a4ab58777b9f3e34c69143bc3872785c281b155de8769f1 0105724a536021bd7c8fbf2ca7e433c247009c97aa48a8688dc7c9af88018688 4a329bace708ed6a32c94890216feac9141147f47d53cf0439a22899e97d673e +347500 af3af4870dfdc980d2bc5c946e773806957c2f5d98200d5e9ace72e4301d0ef9 20b564b903b75c62b5c7bdb911c753fa67a547a47d47e5a60a0a4790362adb49 2e447615292fc2aacc273c021ec96b58a9d1856b557f684e531457ff4101cdb9 +348000 e72024ff3d0ee72f4f78b7e63ade7a7ea037da43bfa9deab400f6739fde391c5 c0ed8b08b6b7d50bf86069b1e8f6c7c36435817114e27745be63db96b5f716bb e8f81bcd2b69a03b9eb423336a20bdcf659ae0711c3d765e7ac89931fb25d2b1 +348500 1d9d9ad6a6b1a8d5392aa6d35a7472fbf80535ee334a043025cc3637d9894db9 101e9ff2c05137c25a2a270055264bfdcc81b290826d968ca94de4038f791790 a3afe000faf5b427c10820657138d0fe4713b009daad3c797c00c35aa35d2d38 +349000 bf0cadc56a8359bb703738a06f7a31b305fe7433989e7e4094f379511e27a19e 2a2cfebba2b09215327049cba461b4c56cf54cf31a0d3c6f8b21a637e6a4db5a 7630b9c11e847b125d2d7879d4e6305401fe6656c5c997c7a521cafaf170a131 +349500 78065cd5e2af5a3a4e838289be5d1460605048c1cf2fd1ef9ba8c88619631e91 c00a12d97c8a1cdf4cfd4e5185ef06ebf6b6c58aec4cbba2851e47c51ab03089 2d1790871fad7a3ac8348c2c1272d78f99e71e73ff4d51e4e0f1421815b4cf7b +350000 937db7a154c0d4c5043fe8bdaa0969670f132252a6c6bf8f7ed5858ee11c97de 8c276300614c430a75552e0cca7d83834ce7bccd7ea1d592012300ac2bc5bc66 1fbcff068ae14baf34f3bbce37b16a8cb04bb7d3cb561eff4207b4430d23b8cb +350500 6ebacc5b6fe9ff0e34d64a047981fd170f1b13d40139073e6e65da9a617fbd18 f181abacd6038099f96854c2c0ac8f7d19504609f36dd0aa085af150f21ef930 08c66db3dc00525562741c47770de3332ebe18568d59fd418949a93788b0e785 +351000 156a0053ebf2ee2e68a7ef337edc14044503653188c60669ec924fde43c21ea5 dd728a51d7f9e8f04e74e2116698305470591a6e7937b2c4b714193843eeb584 6e541a9fa878ece79546e3659f1a8dee6e9b7a49fbb66073f69e3c7eee9a8339 +351500 5cea6cb5b1b96a2641bcd705ae86c40ce7a8572ff4d6815d7531ebdbca13b958 fd4148c5b36775f35873746e962941ed43d95db28ef21734f4351f1d8a69d012 86fe88a8015b6b1c64b729af16e6997820f9d95de1d7eb12e70bbb1d5899109a +352000 43dc3dcb74fcab2f5e90992eedd8a7719f7b7c7658b2086583ef881092f88aa1 eac1623de8acd8fd497f9da85f85614f5cd02c69aac6044f24a3685957009f58 47ad336943ccdc25684fea6e107940073027bbf850fafae7139b612fc94dd123 +352500 6b895134f53c26c0b24e9909472962abb3dba5f8b8ab65693ff8e45b3b77e566 aa1abff115fc49dbd6847ba4779ee7c514dfdbe3895e7bc3105b74d0fcf1f4e4 884c7d07fbfb39307f6edd46fa87e83d1afaefbbe3237ec1e89065b70579a0b2 +353000 7785e099822d5b6bac5c707ea57d5d2cabeb52e1e2d82619c8bc2051b486767c afcd99c877d144c3253dacf018ca36e61e95761e44f993e0a4cee0854a7030c4 adcf80e9e4bb78e530cdc25d81ab9c78482397643a136c585a8d10738a62a700 +353500 c0790882442b7ad61aec5a64faa355a8486f8112f9a691208f38e9bc96230492 f7888632b88cc7800d381774153c34626ff63d859ce489286d9fe904403e9ec0 e43f0519f71417cb8a09cce20d8559384e86e64ca7a6b8f392b5f545e94afb88 +354000 de0551272a32e89def017385ba1833443c4e2ec02196c33739deb8bac6cdaf25 78038315c2d8c142ae67a01dfb98009847380ad96cbf6cf700af8693f6260caa eddd66351b2cddf490d23278f6afc79315da83bae7dc10084310bb791e7705ec +354500 c2e4b7243560cd6e4511d175e2c3fe98df223524124f44faabfc252f57d503d7 1d0fc9a93c812ad30f81462a5ce1fb62d74f14a1672e69dee3a3b797fde53270 6fd7ff9a6576088f6e6498606fdfed2a629bb8e481fa60ddab26827644df175e +355000 1a11051121727fbe8bf80391ee403566e3b0dce4ac611b37a516c7e3432aa231 f363b96bad7663c981865cd98aa36aa2cadf8b4a623a030e3c7e8a58dea81992 c8168a25c3140673c0275e75090ed811c6e5656bd49e151560df2fc1ae640334 +355500 c877ee5b39b2a7ea9723e1c90b2e307f861e42275c826ecf5b6c84f97c120385 d7cc21f18f45fcba316afb516f70ae028723a709a1a0ad2994579078aec10ddd 529fe08e2adc1316c2a0ca6128039d21ceaa68995c754340a769044bf6980a16 +356000 4226d4f7d74316c4f9baf33868b492a72f2a2deabe02b5568ef40606641862be a364b4408c45633b64ca685f42f4be377a4b730fd762f28e0015e2ae6e23b0e8 afe55e92e2c9bb42e4c02a6d0b5a54d98b52b8053e4bdb4bffb954f4f8942dd7 +356500 f0014d06574914b9215379d2b187dcca46081a5fa27d6a32a38efd382a9e945f 853c10ad51f992a4bf0c46c8471046641edaa972c537c8a92b32cc79ff80b445 56ddb16e6fbfa6aad2c73a8d5829b67a450b7ab1ae5fed5d75bb860ed939762a +357000 1c78c05a5a6c50b6d0372745b8a3f0ccbd6c4878e5fe2227c81bf36cbe31fede 118150dac00bdc45c95b36d35a57c63379205cabc42f8da5d8cac3f8198df0aa db8240e2b8713497a22a8f2ac518ab5b029c5747f314e86cd1ad8ff3f1503217 +357500 44900087fce8f2c01a87a2ab15befccc1d9b9e702b17c0184cda90876a07fc86 621888deca43a1398ce69ef2cb1ea7523e563dd552e173c3af45eb3f00667df0 82fefcfa3f4acf31f877878c219f83cfc671fe1f80dcf7f763636a73101fa324 +358000 40d642581118288429f0b72a73930470989ff443944b7215edbddf7ad8596d31 819138d682f96c5be33a73fb51c7b698f347c76086d468a3cec421b5ded9bdef 07bf777103a5eb60fac5053417011d7d6a9a5a89c8c34bfd0b202ba48dff697e +358500 39f707f88dda6ce8bc39c64bdad9d1fe29f98b517080ed55466a8a221ee19bcc 30d012c4929eb3131b7f50c34986d7e1337b46ce6ae7065a0613ba6ad336d2dc 3fb61fad96e3da7e8b6eb33c884df7ce843d64babebcb7b7926b613a30ecede2 +359000 8a04b19b8f068b14a987511d635cdc70ea66e37b63a5c3750bbf9bb2881439ce 7d053e5b5d919b21a1ca21dcb5d31126f519c76f8c0d2816555816496229c970 632f9c544be4365c0cddf8bf92bcb63ce286e7233344413fb313ba2ff586ac0b +359500 15293eeb7f425f8f041248d3cb15cbedf19eb921389a4425b8a14a30d9f6f08a 5b47bc2a1eaaf8b83461d28c535cb1b6b376826c9b554df7498216cbfbd5e76b 8dc135f880bb9401007f1dd5f874c1e3b005bc84fa1454288a7863ee1afdad54 +360000 37577d18f84202e74e17eb9fd38e760dd94096b4623917c8fbe4eb8c1fe727b8 985b64f248199de5acb5f6dd54aadfe6b2eec0580ac17701e1a6590b46830cab 70f9a5163ae901c5e23401b39f96a068c1c048b8bdad27586435cf669b63abcb +360500 2db2b88ab382de78f62fb710454fbe0a9e07dc7c09ba76ef26bf72e4768b8cfd a1f4e7d6f52f1fcc610793c0822a6c9a40e0224deb7e56495d34ead537fe2fb5 47aafb43595d1b250de55f611a94570ba7292572dfc257b0cd5b716faddda2ed +361000 3891670905fc1e7ca588a4b72a30c57749cb7c9c2ed47907ed3a69c7339caef6 164eecf5a84889a1ce42accb7ffcae55c4bf598b13720c34eb403fc849dc5801 087c29e43d9cceae103703acfe3b296cb4c50b1e22aa18c3473b52ff3f8885bd +361500 ebe6b83861d092f8eff3579515524a45568c743e7df656feb775c45981251891 ba453dda58aa37da9c4babea1597815a99cc4bfc9aec16fc3f8ba1d85a031574 cbcc76e776b4170358edba336f2d98c9195adc0d1ba82bd4c7840aa9ff46b5b0 +362000 8524397d4612f5acd6fe921ca9de4e9338e2f74221d4d1755c3682fdbb2bdada d9de4ba457b0d1ae37a2dcb9c8d921acf206e96673d45346ff85de620fc08334 04ec872f96170049e211be83f0f09942fb27a2056b14a9d5bebecd30af615a84 +362500 244d8c96246dd1772efa9b6dedf90ed9933f9a1fef43a5a61fb9d59e9e19645d fbd24f0a05dad2f8048794e8f0c48aef1d9419e28e125ead88eb1127bef72ed8 60c9c9ec0cc6804311d0324aaeab9c743338ad5295fdd80caea2216bd3a81cd9 +363000 2d0854b709d2c4fd84c1d66a736c4148a3b1001fb083f1acb38aa34416063487 eaaf97d25a09d024b71fb1dbe1935a8cf34bf0d30736df8e9a7b6fcd4fcd63c7 814a2b982f34b758a145f8d21f44d4518bbfabca32e0bbbce8117530a880622a +363500 eb76872dee58ba1a3285a93cf5b257a12a903f9f628828bde4dd320ce44ea11e 2145d5e2136393a6d205af57d6544782db4c701b6a5b3f14a90528f30cded69b 36fc0b74a6927578a7daa39ab73ee6d90199df057a75599c6bac59cd4ab63f63 +364000 043d7b87efe77f8f2d34833a08544e15838bd8b8e1bcd902d8b1ba9dc30285f9 71ad76919b65882a929954ac642c401dd8f298faebf7208aa01301815df4f32a 795babd03501ed1d5f9e5fcfddc1202feff8319e219d468a008d7a16d77dacdb +364500 10b77b07108cd3c1b5166e51eae74df84f39313508e8093af4fb5a5c8db99c8f 9738d20593ba72b8e0f80a8c960f343846b639d3b5f3ac623ab7d7d0258e8c61 a99e4094e7751fc605904406931c76491f4300d52ef5584e3d00eeefa01dc440 +365000 a88f0052b9b490639e238ed8d2bdae3ac573c598eebc036fecfbe8d0d651cb62 806193a3ff83178e6847129340bc66f087903dc85e8d45d50a3843511625fe4d f800f9b0da3e850407de0198d39482c22418ed5e085af6c6bc0492bda6491492 +365500 07674af4f751c8a09011204107b77df887eb0989580ab710bc28f86e1724b972 a59376d69d1fd2b3601728c2eb2f3f935177f5abec94f9b441a6734b8c9dd57a f050c7b58f25bdc732add78f058b17b437f684cda3cdb9697ef1ccc26593b3d2 +366000 e7f0e9b3671c1fd8ac289879d42ff60cb2decb8c9fb8095152e444d183d33d55 f04e0f59196d771ea62c59ac3882474ecd053519d37899e2ce9bb2d1a779b3d1 b0c17ab8421de54b13fa25a7be2b623f92fdfc99bf9cff188da8d00ee05776a6 +366500 28fe13630301f2809e429288503e7a341a536de22c078ba11f5056400837d18d a3a2aa196a595a7effa0e8a3ddf8197fa3837c1a55a392f456bbe2745442d844 6e3e34faf2a38205cee3dcc12ed0519960dc05b4378a5d7b264e977a34145362 +367000 066c5da3bfb95638c9b0c37cf99fe28f31cc4852082933305b1561f8b289ebe2 4d69dc379574aebfb8c507bc6791adee838a066e7de10e2e5d633faa6aaf7927 c10e1ebf67ad69e6cafa722890d7e63bd8fa7af02b3504d04721d7dca1cadff3 +367500 ee383e75691d5d76bd0d84fb2edb77a9f3e453fe14e3a0840524d4966eb3bfc7 addae0433c1a0e30adaa6bc21dc08c4c37c7ad6d12109458cc8b9c3deb4fa80c bd8e9a602a825d25fc27b6d83ad29e34ff074ea2a8ea694c919e88d639a3729b +368000 7718d30ae93a53584971a1aae7c71b99f17332702adfa3ba93ac53faa3131bb3 00d48572249cc7eb9929065f4d8e5a4268b69c425ab521e974066c7a15ba96eb 74789961c36e16dd0c2817513103375041368b49ff8ecbbabe300c64f66afa71 +368500 49160ed17423768caebf15a07b978b51b9a50f88cb934cfcb2ca335db599b313 252c55080a47e986faa7b8e8321239a25b25d5109f3b60cdd66c2d7086c32bed 9d2db8c4d6d232322264bd21f19fdd4abd273c77e440f79392e96302846aceb7 +369000 2a35afabeb4c08f7e0fc8564b016b65792e64b6beba78e5d7c0641af63530170 08264c57b5533fcc49b365920cb2d8b698be6d412ee0693e4d78d847530eecc2 4106088b6f4e3c1905df95439b4986171c20dc64b019149fe72d03ba0d79576c +369500 003a85d64df7bbbe1692464040b072934789d092d6f866338b0e9427e823a83e 7084540c646571d0af1e383b6753e92aec196cf20c88bd913e074ff05dd63502 b30146442cc357beec3cf48ccf52376250011fbb712a4efd5446004d201745c6 +370000 434d40143a0e8d8fe2e00984effc5579bd3661fdf33dbd93cca7fd72351dfafc bef78b640aacd4fd8598056dd42dfd6557355ba44f18fa9aba104eba4bad9738 9d4f569ef3874b03e72f2ed5029f9ebd8844fd88051cebb97c1c3daa087f7372 +370500 02cf8d2c1db6faf3e7755a2b3d144a4936dcd9f34214f1c8aa826465cc3918e5 24b38a6971f48836c71e37abbeeff129d21fe5975302103ec2af62a337c33afd 6061f78f93a983e545f9b0e06d2098b8ce8a67f9a98d9e922a58e7e7de1b754f +371000 2534f9c4ca46fe2df863db301dea97a3bfc6e5a3645f4080d221e9fc214efc8b 24faf019a5e3c38e1e9c941869b93a6c5bb2b2e3e3c754c37d83bfe009f78c20 d8f2e545e9f60114a37b677d35d5b1140c933a491728de7a7154e6f9eeb99416 +371500 1c3ab21bf75be98963553462f21fc369e7503fb8699d9f6e1f635a952c55db42 8dba0c68d6c580055ce406b81e3262b9c7057ba8cbb8b221130766e667c878a9 70c1bb70564110d67adf9d12494e89753fd4a4f05e0f4f0902c058e626cc7c70 +372000 b7d862d978a007b9e4afa1f2f0650bb20c0298b8bbce1666d58b009c07014bed f070560c4db4d96f47694e25dc96746634b3b1f172ae1efc8435b29ab083697f 4aae622c2506753047894ce5cf9d7eb707435a9e994896a6f4d7eb0fd02e0e99 +372500 aa2c34e6c03803e0edee9675926dba87db1bed0c89e605dc40c2213a330e53cf dbad4244855f790740309f5f7e49755213bec4d672cef6491758cba12b5571e6 adfe6f7b32d60df2f459b9a6cefeaee4c6d8699f7d021742a5d593bd3c4bde72 +373000 c03556ea141010a523c44868eca127684b01e83f0a76090906728aa34e599931 b2d61cc71ab0b18171db2117a6d535128c25e68031c3c44c059c7c7965d05c53 4762b483ebc34a038245662d1ff2938c9b345ea9f0c43d2b06efaecac6184115 +373500 b61ce82c38d812c1e72a830b062bd3854701409fed42cb8cf89d9c83a68aa4a2 3cb1ca2e543310ff8d22cba4bfa2973e264837d2a4a5052cfccde4de4a4a477b 85177a9b8ee909e6b462a0edbb6bf8fa04fb45c20a41242c60cf9e25ca661a36 +374000 0a2b671cf0c4e82c857482fd9eae13f8212fabc508c3f6137fd3004038d2fb7f fe35de23fa234b6dae59ea82cfeac3259eef5f8d8878aece906a9e71121ed71a 2d73b8297e43e4800b22a92a402fc7fd9298cf4ae76b7d48a97e286d6833eb75 +374500 31b2c402de5e4f0911f5d14b927f38483fec9234b0ef67efa026a3648ffd12a0 80a419a3787c4ab2a27cdeebbb020eca8f63743beceb73559c09297682c46475 b96f53cb6f434570c6f019f74824dab40cf8df0874c43fa257442b69f43915a5 +375000 1673933d5b2d1584e3c923b45bacbae604b308007ff19e25999f5a1d89afb040 cdf2c192e290686651e7f63bbadc54d0d8f7b1d2f7208a097807de32159451c2 c5b8ecdcb1e90452677fbcfcdb638f552e39c9f1b842b5e7bce3ffc104aeb718 +375500 6b35b7e04b2d788de6e2cc8909ab7fc5470b385905dc0e7b7b8524ff57d7d7d3 ce795b401b8cc3db0def999633c2835436348b032919c9123e1481800aaac88e 16d2091d9d7e6571a6a837e81f4000bbbb3057e229a8999b69ca532e068d84d2 +376000 9a2ec84dae6c1b6dd358c57205e0858d987b68bc1e029cae1b8239ee5ac181c0 d576e0d718d3f594ef61eb7be25e4083d1ead1201fe8eaabad00c63938144f85 87b22143efdfaee0e8bcb0ae2c50b0c5b70154d0160e2718f9f6deeb867f86e7 +376500 bca044a02b4bd78ddd32eb668c603f16f14daaf04cf3541d019d3421868a14d6 9abdb75f5d7bccf402e2e02a07b5e6d5205822c4ff20ff5531d29d4a8cae5d4b d006de8ead0065377831d34c519404f011d6543b4c0c07ffca21673dbbe73554 +377000 1b4b732e1f4b18b744aa40196b7bc5d3e1074fee1beb4efc674e38f16deea7e9 04755ac05c88590c66be5b72ea85735df901ee644ea1f35772b82bf18c2eed13 ace5a8992ce6a0e9649e7af13c92c8c8bf94fec2c9b7c919e885db7bc4e84544 +377500 a51b1aadb6f280e7c23ad430b8c59c8067f0b8dc10a0be61666d1da71bcfadda d8eb0789d6088438ddd828d02844a644a2102dcda7614b262daf994437be74e1 504975ecd3f6a7a4d6f76dd29393a289784ef8031505cde3739f9eeb6439502b +378000 82f6ad88db9e44f44c837c7a117802a6bc4379ba9141c4faeb9e7731bec60f35 8c48f7630228d3c0322986552aa96929eba1314f8c62baeb801b95cd3cf400f1 9a8f21d53b2e81d3d6a7d8cd55679ac21a6301d399bbda5a3edb394b915d5c3b +378500 c2fbdc981504762cd306473faab285e108b27bff83a84a1460bf513839d9ee93 37a18476810b603df1cb7efbad84e3b49a24676073397977eda35fb559e7dca7 2a31aed6c09e9adb08dd67540fb0f501ba40d18e7cc3de9e22a0ff619637cd1a +379000 5866ea5d40e02e5c73a1828d3c3bc5ffe23f9702292ba595560908f66b23366b ffd0dffc4b8703364b9885055b427f2bea2336714ad4c5fe567e1efbc8fb7b62 153d00afc4ba8d2b059e818023870686c13b43cb1bfcdf00175a8684f178b673 +379500 2519dfa5eccc5f59b59c89bf35ecf2aa0f5f8b43ccb098622def88dda5177b36 56df546c0e7bc87f0ca01ee62f0d0939810749cd5fe68fa4848f6f302052ccc0 e1a9efad3f09dfd23d883b2eaa6da604044947d3d7edf52384d0338288ca5156 +380000 7bfff4292f5f17bc71f6763e2257fa585c6d56470390648079609d8116988255 e5c4c441e3a8f0b5f55bb8f5ad18a9bf4bf04719a558e2b954109e5c47cb9896 334f5b20d53e889991f7770f0ab58c442dd11a7bb1f40a7c02e95265f290bf60 +380500 386869e1fc8e3f7d6aa8bf28caac3d5a344330e974a42704885aea3cb459e179 279bf20f5fc0c66f97256a42cecb4597dfbee3eda52cc03c01239d2be7ce0e0f 9a691875fc9f4d84829b0569c3ff9654b4a79121bb3cf31fb9238edd27d3a2b2 +381000 86cf8da3f13d65311d707cbdc932a563a44fc12e1c43de337583bc0d113a5a03 733b60f69120d3ba845a388871c75cec4b4e2479ffe31d83c0bfe980133460a0 8f7bdeffa5b735d5114b7632878fe921080e42b1064794843fd311e95ed31a6e +381500 3ddcf06f6b302ddea992508dc99ce57c1a7922d05a89decd38668c974c0d3d41 145aa998b1e691947f9e9c1f9d7bce235dd64fb3101664f2c310b59479a49954 eab537a2ce29dd0d3c7c7154f83e505684f4cf429235453f8f69e362f6ae8cad +382000 5cbf96c1818addd8739c3b0a928605824a71eeae2cff1f520e644096662c6d95 0282ec673961b684b9c2c43f17dc47d7a1c4128a19b4dde559103986abf4ca50 ff00f371acd91a3ce59d3749087a3879ea474f2faa3562a22c4dc51080bff089 +382500 01447f3299aee987ac9c9294682b89f9643f28bf18123ce8114b3ffdb6a03c5e 8a0e1f6c67098b89b81bb0769c520cb50a87299fff5497a87486417b43efb9f7 dada8ebdae71dc3c94c923dae9dd4c90a65e2bf99ee6c56cc19a7d8e0daf0c88 +383000 d5efe4b385b101b754b2b30f6f99c2bf3736e9fd0e5a06d0b5ed3064e7641852 245a1712512d17bf19156fd5288ebf706e85ba49278ed03c2d506364e7002e08 e0aea51d3797945a25c74a6ff6a3ce3c78eb7ce94174af5f0cce318551baaed1 +383500 5b88888d1abb320e7d295c00a15bd74041ab35850fa768a8786d2e0cfff0948e adbbab8c600e751c331a054924b778213bef9b5a5e23f3d9ca8c9e3b877d8b30 405c01bd1f9ebc8c3d667d84b3eba5d07cd070d0215e53b92592f38ae7284be8 +384000 def1f25883b2060a7b02f078b184a1fb50ebc9b9ee8190971a6315386382328a 31cf28e8a9ff6242a0e4c9b2ba30c018acdf9279b8326185516851a41a15535f f9a34cd72e59a3f70cd776298fe2d3526f5a8119f67ea3b09d88d27b52a0bfbb +384500 a08467964a472ee61fb3ed6b622acbcec35b4903251cb99324f14f2b9bba7545 720e5881cab3613d6baeb94449d6695102a1e508f1b456ab03d2fdcc32486ebc 3606653b8ce7719fe8ef866128c203d2c90d4b7be4a2f52e50c2f7d1b55714b4 +385000 d460b85b1ac270fad347a02c19917b9f38ce22c01d8b88e90d0baf63f011b117 b207a874a45789d7b09e0948eafcef8b76c9184aa370a508a4bafdf9d26ebe29 6bff034cc5d7f348e854dfd1e6abd3ca4c093d2eb766e821dbd03196bddf76b2 +385500 abe63c027a3d085071de60832600c63e46d78d244315facbee6f0f3fdbb02912 7d911e4630c29d4daf24ef749a17d8b7276c4c9c3f6194c6b0176b4b5f9271c9 51f3e82af0c3aa29b7af55ae6c7d6a15ce2a4ef6f84897bf464844342fb33162 +386000 656989d4c67537591081d194c31766bbd9fe449159aa2d3037afa3fab0f74a82 bb24425f9ada80398f6b1e4505b1f6eb372966389f0805b22f2e2d8607aaa38e 0bce2fb4e1c88f8403597fd89d31cd90fa38d25dc5f424bdbe13fdab85840189 +386500 2c055ea6793d46b622e43db2f1d25e05558f77edab26f4b1b200bd5aba514747 17499e0c656152df6a2d6096c5dbc50eadc4f19ed4919a04aa3a5c06668f3acf 736428b80f27438e4ea2b83c014253bc113cd7b342cb6b95aa60f2bac6fb835f +387000 b25736d7898a4555b0e257ee1e4cc0a96c1275378dcdc0056234846010c29101 15a65bf7b60e7729a9c9a12883b882eeae58af6b07aa9e1e4b7eab5775de2154 2b9ec63bfdb56932f3216fc47aaa17292283cedd49a7a04cc2cc41a93a67b7d4 +387500 623ea15901831a8ece8d44b5da072e281b237a693fc3524b523f658fc4ab621c adcaaf4a4184c1719060e828a12933ceaf54184d50afa75118d16df5a67aa578 c749b80575fc01e7835631b523a4b934f5935963d5afd277c86ff797d3b3ef53 +388000 91bbcc4c97dbbca8f88c68abad1a68e91c79f337a0bb7e14180bc2ce92eac137 21bc2be4b2c59b991ac29c2266fc1cafdfe59da48e957f3105f8d45fe2284c41 ec34df2e57a330cca8d7620b1d9353aa79ee0f98ca70e3a92dca3df2fb9a3906 +388500 8b9552c05fef1a291df8a1b47d92229429ba2aa1c3453c274bdbf8d3c7c4fc92 f146203b047b7ecb750434bc317aaa95adc82c1fad15f35b22b879325ba38958 ae8444d003815306abd9bda668bae4e19f52160eaf4b4f3061351a154f6abfa6 +389000 8e938a51863daea6ed977f9068092e5764c7dc9bb2491ac10291921725be7ef6 ccf2ce60dd83f9dfae647c30e824864a5c208ed5c8837420f30cbbc7caa3638d b2c27b0f52a80b2dfde788ad620baec4ddd7f933ee69addefe33acb1dbb93483 +389500 7505772f28c062e4751b5653080ccdf943181e5f0419069bc20ee6255c2cdd2d a4080018717b150e0384c0cae9a6500dac7779a57565cad365483cf79ea99a4a 5ab9117677d99645546e9dac7ff3fbe6f7d5da87bc9fb20b5af6e7b958a35409 +390000 6f4b50c04bbd5aed6b57f287a0e6d90a11ea1571dd3635ca9b6ca6ef541cbdd8 b408a6d6415251b4b6ab6db5ae815ee07d0dfc8a8e9ac22c44470916d7d57ef9 0361c1a625b6ebcb9300f0b7885bdb81147b83ee27595380405330eb84ce3043 +390500 b8caebe933d7dc40b9648b530bc042f1f93f4a1bf6e1530164682a1397dc1aef 192645f2fce9e3b4a7398c935db6ecbe5b79d25d8557fc5ee13d1a5c95fe790f 63bf3991947441745874d378da8cb9bdb65dbcca2fb0b4f67d1459e23f803333 +391000 0e6e6686e469e5fe43fe99fdfb377dc48f85d7892b9aa70e1ca46fcba1fbc940 face758288797482e69de640daa24de10d7a35e17e3b575fe147d73666fd0b75 42f1717e6dd23f095bac64c9be18b2530e7d0e00fe093e6fa129a63a7b853216 +391500 fd1e752770b8e555108d7e32c8f6c7e1f9b8dfcb20502babe4cd541910a03b68 89601e3e196aa20964f326b166a74f7a601174815ac89bd1c385a464cee7a54d 8b2f34e08e98c276848f6796daf338c2c08647b7048154327b0e58d4a230b52a +392000 529453ab5db3938d1195a3ef84c286e8103c42b7b1b25362898674a66a48ed5e 892462e851252b9a2ee03c507d1acae80ea67d360514a4c5770d7ce0dd3e1f54 8270cbb4a1814555b8002dcdc92547a98b5913175a4e255c0266cd5f03616a0e +392500 e3a3fd9781e171e256dbee0afe8373a2be01930182de5bcdf501db3a73a70952 945a626198abde6c92ee9304cec95937cb148057692f8a6c5080e0ae930be61d 11cc890a72c56df46f5237f6fd4c2a537949fa53ea0a065dd6a16996c7b22af6 +393000 01db0c4add701bc81282082aacd1fa1ed032967c1ce44c88a46f22f09a00af6f 7b2b867b0ac1dc90aa91e0b88722f474b7d78a3322ba125ce36d0ac755b2c3f9 7f916ca6a85ed98b74f5be9ee8c0451e63ef3e9c91573eb295335c2c27a2ff47 +393500 c045647644b0d7daac826a34e5f7cdb1f55a4cb4cb5500c16ba4791a8f46433b 8985e0f86f19a7a72fbe581cab68588d1882b9a4b1c236836aa1e559612692ca 7361778fb183e94949e43aa335bd2a472885ae10818d96530c5fa6b4fbb859d5 +394000 7336f022ef425203978336336066daf7f85850fd1ca5ce2be57119543211b7d6 6f1a7d270bd2cd756c02d24aed1e33fb78042efa052bc7e710cf37a60110bffb ad66c0970633f1c1b542a1151287d4551e83392510c0a30f6d79b090287134b7 +394500 2791b8c33b59179365cb1f1e97a71a0ed8c4f9dcf98105ca35275dbfde1b8213 8b5c24c27b2fe79353caa4f2d7548591db269b31c1c53b5e7664a47ff1646a33 53d2c4e4243d4e00d6b332c4ff257d13c51190052f4c0c72f82ddb0b06143ed2 +395000 b68a97351f28549882241171a79cb58a1ae92d93a30e7524f3580dfa69bd70b1 a2d0161bea0620be17038a96a9c21a7c5ef08df89362f1e82ce8de29187735bd 4e5f889f7efe01700e2103a125cedff7286bbe6b270fc8abbc17ed614ed644dd +395500 f674116f1af73caf4c6d464f99d55c1152f7529c15b0d28a12f35abc1553f91e 32fd584340a63818498504c5fabc21fdf3feb2a4529a6b5af5d9ad67f3679b20 d40aad5a5333194b1adde906913a50c32448090efbe02eab7e37df4b68a4f960 +396000 ded515c3d960dfe073403b321aae9d66a1dbe4a9565caed08c9314e8f1b1d2df 134fcfe75781458a3899ad3330c143de491b74c09c98b8e95c16f79cac282828 bd15a67e4b54b428e0c74c14e1fea888ffa584e9a323ec86e85672bb3061f7ed +396500 b6745b3e2a46f458eca58083625f3eeab22ca3256087a45aa6457cdbe9999aa6 4124109f22fdfc42c1343feb20ed8a93ba55cd7f65ac34146c3f5caeee272d94 0bfea25929cab536e6128420fff5a11f559648af36cf6566d44bf1e87f116e2a +397000 c79ef7c45f179c76254995bf3c810a62636c40d7283658c3d35f167f9b4289f7 a6fe1a5721abe2a12fce95bc5f5e12a4185596ce991d6af28ad2cb2972305637 487e1173dac8b4afb016d702dd349ea3e9f67d579e36ced25103d8242d2b8020 +397500 d36dcc0090a5585951004c7f9dd645a5a2daff1d97b796f2dba60c78a89d5a14 a89cd3b2d93dcf17cdcb0f7badfe7af1077f916d6ad5329adfc38a6e1d25cb5c 94c443495e8142bbea3d6a22e34cc6f8e9ec838e3cd9c4f61ae6ff170b7b90f5 +398000 2b97743e109f78d910532ee0f342b1c491ae74badc58085ba2a7b9029f9fab5f 7ab0985407419f861b725834b5643d2666cbf5aaef6aa6eb94dc9e35c0f630cc ab4a3aa2dc717532967156a2f29cadcdaced3564a28b3f2a2bf5387b9f961c2b +398500 4df2d83b00fd22751d5fc8b22743c9831701408cb9b788d86bf081c666e389fc 9c545b4c3cac0e1d1f9fecd92ba0f7c61ac3e8a28a8c973ff6026fdcd90c4a43 a5ff589844dbde9cd52951da27d06731785b5bec0908d7dfcf1703a40a81855e +399000 6a00c77818429d3ed4b9bd5211a3cca69cf68c9a99a89f9e1f9e5301c08afb03 44e27a5f4e4c32f6698257f5cd63ecf165cf4941a94f7473f3995b1a3a6bfd82 3a870921ca65e9a9bae895a4a29520a70a4f3ca8178117491427be7642070aab +399500 a6e49cf1def602b4915fbc2b208490f5a84c8a93366582f77ecf5575119e6cab 83be829fea8e1ec65f493f3910ae0f3798b9fbe006e41df4bd927a9bd98f3cc9 c001f8b45cf32c6503760c6905278ee2d55f3035b79c05307b9e446d1f2a5bb1 +400000 641c6a53eaa3c9b94e924327e70830770397343d7927eb713609f14448ea6228 4252f178c0c42e28cce9ef5c0c40f08bc03e3b631a393de6eeff90e7b4d26d38 b1ed7a8cc5c9177b8fb8754170251bca86c728a244cfb54b7c79fd84f025021d +400500 73e034517c9649420d36a641130bf16b8634fd3b2568e58198508e65def1fa37 a13f2b06f4b1b3daff6c10571f25318c3ec8e9f2d42c59f4f19369bcbff62da4 f3788132cb664a0e812910995c536e03da19b95e03d40771fe6a7094afc1ba77 +401000 b249ae5082bc1eb852ce420a2361be80dd17228fd17c709761d0f52e81e8478f 679e41c907f1e82c438671466ce285437ba23fa2c845d8c07b43af0829692b69 b5c351cc2ce12bd45cfdfb989b02ab756db45764b8cbfc5c2214ddc999d606b3 +401500 ae40fda2bd776861208459ccc6f1d205b769de518dd00aec84f87811e006098c 2cb9da6c40cfc83129da322498da46fbb48f7509d66d7e5ad53b6ccf2723ab83 0e79cc1abab489be666493ce7dfad2892c158847d6abfd927febeb09c872671e +402000 53a37e92887f0f1305b937538e060a4626675b361a28d8ac3cd88ce7c16adede d8bd6aadcc2b327c5d2ebe73f48ff2df81310be0b9c194cde8fa5aca004874d9 4d93737748203b5132bb1b9a6bcf4d31d2515b7ada13ac68cdf08615d4ff9fff +402500 54008c3fb34d324191f2e8790f68e097dab91c9933bb83566e2039abd876818a cd1605e18479c4a48bc76ea463608f2c2475d5b3d603bf9ba7555194f6a77d73 f19c359ce0f426e59bf440bcc5b38ed78f44d1f000ac11122d76b49453eb4800 +403000 7ccb2c59698108c6ada2be19fe72a1be124c9650abbad735cdcd1b07fb5888c8 208d179f6a09f352c3ce8c445468340beac166c28398132d642afa58cbb06fbd 54497aba52a3092e6e944fba240418ad695f9f9501e26f147348354ca9b6c765 +403500 4307fac30841a99cdb606d9828cd6a920da0155afbea4e5ec770d2e82da4a850 b6304f7d096028bb882b39de8ab14f625d2ae63e4c597d34fddbaed7c2b9f526 21fdf4bf6cb0121101ae86c775a903512837e720dd1f2ccc1565343ee99642c6 +404000 b7845240f6d8ee0cc32e37d8682c587dbc52d07eef8c1b1fa38f73428b73afa4 326e6eaf313513e4a52cfbdbb0106538065a4ed8fdf3d0e7eb6e00ba46037af1 4174eede9b7fc4e01f1c012643298afca39ae871fa781430fe98890c0e78796d +404500 73ba4ce92e212342e14471f4d85581e85c402a55671db59282110671ede03341 b2af723149653ceffb01cae05de8860e28208128f215e3bd8bc65c7f2d03de41 606f423f018c4abecfd83a7075225f01fca721dc89525e76d36650169fbe8248 +405000 3b3d4f18a6a63daf34505404d27dd936531654047b1dc9d1b1f864c33f7ed996 b6287250e883b8c416c65541fbd8cdb01e7d76f989f3fe3e2c31b762d9c3269a f4241f2c2781ca2575187428bfe71098afb3db7e4a8380b5e3d4a92edbd0bdfa +405500 74fe48ee491e1f7e881a9a5918f1848dbd129b08720f0c9f2dac17dd413454f4 d57fd78c8080fb6739f260c4117e08c2214bd1afa6c4244bc16fdfd04804fa76 5c80a17d894fb620e225de86352aae89d34d93533e9d44283dff3e70788f9180 +406000 81c002e0fe1d6089bc83dc43cd9d616138fb16db20f8ff9dcb039a2bf54bdbd8 7e37f0088205c718348f6f13211a98b16ad8808ed51c824050c1c3793562197c b04710e9e4246dee4dc6be1151401dafba18618997d1b8ae0bf4de1e5b80d3f2 +406500 20aa6245826270b507ea3aa44b5360d608e2d52b20109dc81a63181f9727dcfc 2d722a96f3605f68e844eaa0d3629408e9e20e8d5d095d33c435ea2427420a9a 6fc4b43b79a0b8b6c35ee23683a9e4b8f38d1d766a5ef21d007e8783fded3409 +407000 51c75ef8115644c138fc20ce9af7b771731a1efd11231c881096fdaf59591660 11b150fec2d433d57eee04489446c967a692ccdd64fb6c90f95b150f6d5ccaa9 1874e943352cd0c34a96faf793f3eb4ca1c7be75e2c7c807159f0950fb2cdc7f +407500 6f24e1c00195775eda44acca48e654190b2a9cb22f2dfca41410ce90a067af16 8b49f54e99a2096f0ab8dcf8f22fe21db789b9bad29e43edd3566f5eb7045b5b 6c1f21da50c16552a04055b16753fbe51ea9d024a98fac7d886991f880aa2450 +408000 ce3c90abbc8da7ea5c5df3c25ad6fd3a7fda496b1e0f696195bda3e6dbe7919f a5a21a4cbf89271969f43d9c808706c6cdb624daf4e5250d6690d40bfef2e78f 8759d76d04358bd628a1b6d3ccef5583ac09ea3de67caaa33dbb46c96d276925 +408500 ff9b888f601e151a141d92abe7007d40203e6cdbf107740c78a4c1c715608626 3a6e13fefffab34b8bc11418f83163112c871b7483b6cebaac9f9397b5894976 a0908b7c3a62eef624fb191bffb175c01498f593b7d85f0aed815c016eff40a1 +409000 7f3914a988816ad71eeabeaa91e918ab92df56753de139ce9170256ea433c610 39c9ca62d51e871cec9c9724f12841ded9e81d1b684ba9bbbd118c4d79675e3d 942ebd81ade6be2c6bb33732810c9e2b351d2bea484338bc237156270ce38dbb +409500 e3fa8435841942ec88357b1e3e0c33702412a83b07c68589319064dfdffaaf81 beda309cb0d0295f165e7ff4168eeb205c921f202c3c9524960152b7ddfa00d4 4058bcfec1a3664865d77e828c6b832891b2d1ec0b57f210d53d59bd31b256f1 +410000 3ae6fd96e35b4a84bd063aaf72cb8ce5eda797e213dfa856008516a88039a94d 58e69a89912f506e6f4ed9e89229f9d81113cdaeb5bbd120ca273136117dc82c 7d997c8d8ecb9a4d6585ff3c93438fea372a8896f67b45ebdf524128ae1382e8 +410500 eb2bc9bd04d8c2c4ccfc4096116e390bd407e98f0d81b2a7a1f096ce0e86336b 3a87b4d2e3e1c6c5171edf685bfbd0694f293987197b33680dfd338e3ecb4b98 ba448dee877fa01c76a73f0777778d806ca738030a64d46bef3b9a4eb97d39b3 +411000 a57f32043fdbc1b8eabab9e66fdbb7f40066ea9e92d3b1055e7867faa4b73187 afaf24d67374beb37bf9b1c1f0e231ba901b91abae33f81367d55bdf78e1cf2f 8db864625b2c002339a7c5a7e1a50f596c2c22f6304b0329432fc787f19df836 +411500 ea48060ae79a850a73fb9da920ff9d38245420ff20fd71ee09f5e1411c53f60d 248238d9ddd8abfa0b502311f3e2b21f3e5c5b75719915069a209beb7a1be710 da02af0658237703797b8a73fec8e7ab7f471ff0b312e152c1584720112ba9ce +412000 aa2691852758d5a285217fe3a9bd1c2d29a6d337a0e350abd60809cecfe3207a 5a3ac34a9dfcdc2b17eb45244fccf0fb4e9a843dec6c6f76355c1a81b16f90f0 84e9cd8662d95fe81e421ba6d02268febeea187d3b710fc16490c90eaf4bccb9 +412500 5a0807ca910611b9dc9992060c41491071f17f9b4f71b8934e8fba9cbdf95a69 a904ce16e3399f6e8eca3201ccc7fe5b15344c4bf306f1e63da4ab019e0d9582 3ec35eba33a7ba4d1fdeed451986728b0ff9f9fea4b407362a9016d5f6ef2e46 +413000 6b93d17d702eef90b2795ba888ba49dd4d0d1545784e5d508bab8f3f3700be79 20028cf3dfdf9af6de78fd6ec4f174f46a617f2d3204ba22c3b487d3cc135be5 fc86207d5b5cd24f4948eb88cb46b669fa563894cae0997ad41194a7d747ba24 +413500 1bf2cd60f8c697785716c23db0c3588c42528d3acd6a8427311ad176e9bd3d71 b6e7e1e76a68c20f6909cdcab53f6e820bfbe896cf25a7e435a52ec6c2c3bb85 c48beabe0f4091cb2123d6eedbafdc409d3a6902fd3a7fa47aebf356d27da31c +414000 ca3778a71094657cab8c697bb6d36930a875d3c76fba72194abcd69fa5c17703 02c6d73c2091a860215de5aa0741c1396c9fb5334dad2786f1f483add87f1ce0 2262ec877765e09b6232f90ca1cefb23eba57935ef49a9219b8faacd014f4abc +414500 97f6a6e7e49a245ff3e2acf4c2882ec0173994a21c619f7a384adb93804bfea7 79845ca1a36820aada03e8c46de2dd19dacd64131d91ea5c102bb90df653cf6e 4de40e1303bd9d37f007dde622c1cc446dc537fc6836cd009b94ddc437100077 +415000 e68357575afa23d47a2a7fd4077e14d22e51b786c8866042263c42ce2f6fdda4 4cf1d285f03ccf0ef31333c8b6ba0142b54791b826f29ed619266270c725b070 1e194249fe3404efdf742b982dd74c828448f9429be057e0eda060065cd1d3e0 +415500 f975006a0b269a3c5e89fea165ec1821ab21dadd0e95d2f372428339a09b9476 a2e3b1b7b2cedaaf531168cf85aea230e8a27131f3643f15269cd8b7fb55387d 21938ac9bc8bc929926c4b7773a9a002213bf132592e682772e67b3d1baf5d70 +416000 27ac3cca7b525e4bced3bf89072f6df21ab97f85317dd242d9698a9f695b3d29 65b7175c50d753059f0955541a646bb523b47f1fa35f5d3d86ffec0077e5e6ec 318af64c025936fa7c6d9eac3c43ae98b361eac10481b35cf03c96c832eefc8e +416500 c3947b6b74b100c5bfd70c7cf1baf822871046f3ebddf211f20ac0ad00660851 ee1d3925d350a9da5ee86bd63c792406dc6a1c70fc0d286dda655687a0b83b57 af9acad2158b709dad09721ff0df14576b6d9fa44f6c8b7534a53bce657f925c +417000 cdd42386e134f3cbe56a5b6ff14b08dc50a1a02b70278f20a6982517868c7613 2f7eb3c08a36c3d1ffd90dafc4ce917e3b44fe62e8f545e581af01a2fec59891 a77c8210926d9f7ff84820ef7760888206d1fa7e6fe91891f280232d515ef087 +417500 758c5ed9fa53f6a940eb15078bfc3300f68a45174ad55b6d754de04344db5dc6 9d180ee51efbd082e027e34d85c9002b72233e99014924f3b56955f3dc2ba17e bd9bbb6cb9e629aac281de80994cfdd3397acca99651fdde653c906300d4ea38 +418000 de38ce06e6f7c0509fb958124422fc1e0711c318d7fd1a0fbadae47352ec0eeb 128c492324c57e30449629f7a9d475ccff48d077ccb61dcc5b7f91d013d89337 5081c305aa4c0327fa8cbfb020382fdc0d31b1925a187b06b73059cbade1f026 +418500 52335906771b9b38787ad4381361b609d5eda9864ca2a7d2d22125faecbbf76e 192a8939e510e4b270a3cdcaf4d5ae7379dd0a20e4addae21c2115d0bcad0d18 4002323d26b41013d1ea056ce4e1e2f407ca07bf38061d02c0041e8196963d0d +419000 d7718cb6a671d3e323e7f8c85b013f8f46dd89353a6f77672806cbddd9887379 ccdffea8a7310aadb5f103ae277ad075b9daa876c08f3bc4e13ca1fe85a400c2 38eb759cf7d0b9fef659e9c2640d71387e762d0d0c35dd2d9d02b92a490ac4fc +419500 311eb00a753d20b8c4c073eca48fbf44066e4c97dead7b0224ea65d24dae43e2 5d4d46ec84c96ba390f8d1ab5cd82fad5d412133341c4ec204f36a47462a1633 c08cf696bad8203144615527689a09db37e35b54183571f36a15cc47f422f2ef +420000 02abe9181281799d247884c1887745c6aa80f60a1ceb12693d328015d28b5a84 c5713fdc696198d00a681a1602a8703b724c13362bf059dee081747db8c31908 a2c34ff963efd864a186e1dd9c96bdc75abc145341e129cae1b1a4227d506b07 +420500 f24e5019cfcf1f0612785511437fb2eb94b0a44ae6207ff537b07113a6deaa5a 4c49208f8e5513b0dd1940c861175e2bf7bba04d6373e734cdac63237fc24f1a 2a06b91a345e95c498468479da44100d4eb31198aeb0473d902dd935f2c89f0d +421000 0ebae57f2319ea062c101095eb8c2cde71bb38b0df36fccd23fe6d5e40f968bc 7c50e4dcbe642218c07f3bc8df56974ea197f1107b9b523cc8d984f1903c944c 80200e27ad1a99c9b556577e4a7183dbe9a9d87a89ad2076006ec94d9864cca9 +421500 3a65fa88661cc79145ba391c18d2eb928842a9ee2642c757b3731ef399323e13 2dee8bda6a09ea7ab0349f743da33dee3614c069af8977377a94bd87d072f131 219a15a9adc94181afe5c2b29532613b8f06757e90b3e83ab418365a7a993730 +422000 030b699998f98d4b331ef746f96eda057e7a454f98765a0b695d16fd3e7aa44f 9b2c25f8a003bba7778aa66ea405ca0a7d1b4d1a44ab35c28124d0d147a731cd 0cf658dea39d09846e7ef4eb06df6cc066e8160373025491262efd613e188942 +422500 44dd126ceb8b88b2d3d942246ec2ff298ff07890fc75156510de8dfa22c121a6 fa987f8cf06191b45925bee07fa035ab558e651c1b94d1d518524db426449e5d 8a32b94cb5f773f48202b8b15150b2a317badedd78d46118281352d3ca19737e +423000 93bc08b4a0ce5ef57f63ee483936125540dffca3d9d6aa1a24ca2f69df2e2100 a02f084ecd89f843bf976fcc5f5c3d7b9a5c2b5f549c12b896f4985f3fb18f82 28fe299babd0481c8eeb2ea1cec2f68f82ab85f571d104be8d33943008ee5f31 +423500 4a09df19634b6b11e40263176de979e2aa0b3aca1a95825c3ad7eac2a84bad86 1a2acd078f11b82d5bfc43a088c8ad652ac993c2478fc2469859ee4885da2ef9 dbfc352c35d85d0d29acc20be05bdf46ab6e6772d8373a7f43c73912d1b803e5 +424000 bad4fea158757021f14bfa735be04d0514bc3632f96600b1e4d632efc33c6238 ea4dcf8ad8122d652811cb25f7277c96380f8f3b1c839f63d8085d1aa69f5f89 e33554c749df7d7bd996e3edd93461887d2f891cbc8ad2d8a4eb39604bb40c32 +424500 bc5a6d616947f853ed4f4d9737fa063959d32b8acdd92b11e27dd47b435b38b7 335830fefaaddfa0a3daee3b4ce06b16ac1930cc7b2411dbe831d3c518a520a1 bf4174f8c15c19be02ce4152174b1fea5ac4d471e854c80dd226a6dc098c0969 +425000 5b30049913f1ad030235ecd4deb6fc86120b8206e5269d39e56e6c5f1bdef8e8 40b7b38eead88896d0993db8806af19167c6c2dcaf989e571a90cc689568e9a4 81374c7f070937999acbb9c2f4c59cb64f5d477fd823bc45bf158bc54bdcc9f1 +425500 1c8c6b6e080abbbd1aae24639ad147ce9dcfb2836be1a4d5520ebfb3a9af61f1 c6e3bb5149886a4050a284990303b89355967d534894ec988b9b9be1f451edcb 15249bdd6d51cfcc7470babf6556d8bfd2494c18e57723a4974660afd4af2554 +426000 9a644de2cda849b362daeec3da5cc28e71652c6a2bbf37151d8ec938e728f2b3 a38d8a78768bea93a802d40ee5d92753afeae17ec5c625515512f4284d56eb1d d1c2c919b2a3e3615ff340778ba6d3bdd2d0a177dcc679ed3f27cc28a8896731 +426500 4b3cba7009b8a7e4fca74996822c10f661db865afde3ccf0335607d549db29ea 91b61ada9596f861c6ae77dcb3f1da3ea0f39dd623b58910ffbacb800448a8ca 6538ac7b92c96a890c9024ef1072219dea4481c7d48bcc7728f83a54df8d47b4 +427000 6c5ce8cfc2031e16ddbc1da1b7854aa2b45d1e3a69f2fb73bb14d74a34c702ca ab6ed27075246d24cad1577e05b7c23f081c1be76318508cc5f08aa692ebad22 753b425d2acbf22bf4dfd17eb1a76c9b55e0ca8f9fe4b43b89a2094e91525eec +427500 8156e4220e867b6f1f988b354b5a96ad98b7f7e83774dc658aef3cb7113d274b f8874e6dca4d1a2e74d442999c6f47bb74a49892a0d9a1894c81fb7d1c350f40 93438b999660e155678f757ae0b6940dcef316dc19f7e9d028cd900a79cee091 +428000 8dbc7ef6a382825ff9af8347d23569898d687ffd3743285297278cd90e3cdb13 21978c24fad677e5014f13ed54d547eb96722526cb52969673292324cb188b79 bbe888f9da80c32c1e4c1634d5261cdb85b79ea5626355d5fd8d3ae8bd541d87 +428500 cd56d45be8fc1eef02a601ff132566ef3537c7a69f67f2d8ca6de2fbcff16bf7 f0b9826043f778014106dd4bc0e5429d0f217fce16e401a42ed252b1d2ea6551 b61a9c7bfe67bf1866ff00fdbc11c428663137f8df30a61a4ef4d347a75fbd83 +429000 4aec842c5e392ec18423fe3735e8f9c84203ef54f2b3dc837100e42fba29dd61 5e2a8cf8c42f6cbdcd136ecb5386e02eb993ab5314fd3410354159cb6497943c 3b1e20816a54f52aeaf9990cb09b894bcc8c0092304f892cb59e0586951e0031 +429500 24d33bfe6e7a8694630a848958175d99c8c5a5fc092437ca95edb5e8f1aaee5c dc92e71cbf3286ffc80dd237cc7cf5ed769de81324291bb80548a79b6a12e354 2255d534152b8491818735d41a74246953cba35c63e31e1219e964ec80d99f4e +430000 64e5cb5e05477470b8068e35326c7e6779e4cbb740cdab675f60a3048e15fc25 c622476e2285d634a82c4720d0a864b11332b9e00c3379f7001f28608c1c4817 25f4ad4b2d4d171bcbe707177e7e5d460acc32dc1b9c95374f75bcaa8422730e +430500 c7938907c4845919f2ec22dd7ff432e7e3e2429e65118a11ae5f2fdc1f5d9ba4 5b34e827fefc85f603439e3367c5bcbb63d94aef7f5389c54e10bf41c1149d09 c952e2ef3d66b2e4d422deccb4b16864a66b281227b6d895ee0688a244ff160b +431000 a1f4642fec301e246762ea675616ba729278569d221b83e0fee38459ebb157a0 449b183170ba71bd90a2cf58cf0fa0a61ae8d86fe32075dd4b9e80c0a3d8f365 d7ee3255ecc8c054b8815feb6f0a70c5a5f6ac4a518998bbe54cad80f250acf2 +431500 012e1de4c57ac640cce243e1577db4193427c285579d43614463815932e6f227 c5e13378fdc635b4f2d4dc61ee5d1c0ed7f60850a9de87de8307c9e7e494cbdf ef50f48542781827d015d7b8052f505946f3412b66836e954ee3e0bb9e09d18c +432000 e530822bbe70b043e108e5101b6a684e9b1d5c47a8d0b2e5ace12e44810097f4 211321ba33cbfd213efb8e3df7e7ea774ea25fb24c82cb757e568b756472ee12 9daf8cba2e949ccc6c601548dea3db3b2190503041253d14c27c80cfbb90db2a +432500 c40c2a8915c595ad827fc5097518aaeedb71832cfdc7f3336789fd6ec0fe4231 37b6a9e80f2b789d61060f97f6f7b8ce019ff788339de54fccb2101c184b810c 0de5670c0bdc09dea96ae3fcf25e696695ad584481004b0ed0d0866643d676cb +433000 c471b86324fb2df461084f3b3f91364c8e4e54b9c592457044805c9c0b1b1ff0 c3cac09940b2a846d2798df91b2e697dff55fcac233473d159da02f5d2a8865d 4c5b4f409b7791478132fb3163f1b8de1d962d776681f9d6792a2f64fbde1f52 +433500 7c83482c8fd9e4c57aa0dd75563c991933b314f3f18c7cc821204bc41d4c76d3 4d6ebbf09ef39066a45d9157273466fc6e1b08f246396ad00ca6a533a4d08da5 d71a19094986f21cba0d87a134122b9b739dced2d253bdb86ce0654d5515474f +434000 7d3607cb242e5daa146bb817da979a8874bbbb9abdffa2cfecc546bef9a2cd26 7bbd1335b9852ee4cb13b1d7285dc11f9c2867fbe267cc4b6c1b1a3dd6a15803 5794e0fa1101da3c9a01f3d7887783501007ed3ad3b8e100f1392f8e4ba8625e +434500 0534c7881cc8c3745dcac6942291cfab024520de1159d3cd1cd6fd853a52e1c2 b08a60d232a23a137cb4808f3636128335ccd3dd10fdcf766ae5c20b64d8a926 31ade4612e2b6643beca1290e1b393b6cacb155eb807ded71060f50bee82902c +435000 264a1cbeeed20cb538b71b99c8da4874af707bdf7591cc37e8f2780ed8fda372 f226d8a6d56c761d1f9ebb8f5b06414d1339c17889767ce48317564edbfb337b 398bdd3b22c722cc65c029a5324d04124d341e4b094069cffffeef232092214b +435500 410932e8557a564a226ac672c5578f75653ed84c4669f64b6bc29fabcdd90586 a5c68267fd466a48ec4473ff1c904efa8eeed2124b7e4bab8bbf83ee876dc375 d22821fd1f65ec706e2f4ea674026ae1f266c12b8493bb4ce16d8f1d0e446d4b +436000 c153195fdfcf3938a5dd5ebb0d5dd0ec59692a8decf1184083679c46569b537a 5d8daaa7bff2de12b5d9b428e84e5ba25ef9001e45ab728ec74d6a22c61b269b 11f2341d723906e44683e681f911663b4273f0e446422cfb0512f56d93bda046 +436500 5e3b108e26916d2507a40bc30211948a0bcff8ce4b40117ade096cb5f94d22c4 16754de8c6290ed9a3e8769b8a03375448921fdf847c7f1ed6d627e614b8f6ea 56996116a345cac41199d917efed3ffa92cb624114ece62a086043a42248f5ed +437000 06ad60451a13eb38ac6f9abd2375d50afa00d4d8c5dc1c2806bb5a05727ba523 4960cb8d1571d7c0aaf33b659c0721fb84bdda17daad04f0cc169dfe1a22ee28 dca2b15c5324a29d81dfe54dd537d6a84cf1bc0f5f97265766e64a467da8f1a4 +437500 2f14aaa3e58a32d5a3f17562b3ccbf8edc8bd17193a9a09af65052be99225a2b 8709492c2ef726d995e4a2092a2d062a849450a00582ccf51fd7ce3905ffd2c6 e0853cf80fea64c09107b6e12394b88dc4111c7fa806b65827b5421e75fd46a4 +438000 87d16a339b0ffda31c75b16f3fc8f7c45d0c67ed9de0bb27027524661b1f91a7 c21254cce7d2b9df55ce98218ab9d20d9d2afc3a450ad1f3931e9c7802de8f35 1eb9cf7aca7e18f6a95f0d1fcd876545f9ea02c9b5fcb7dcc311c9a9272ec279 +438500 b84fb753cd672d1622e7384382069066410f1c27763902b5ee2c919ba3f20bce 075834fbe8e33fb3add9426e52ca900f7db370b85651ae10ac5079aae540153a 2fc29d34f8d996a5f9cff1dffb49255462fc1edf5af8f42fa552a5abad79d40a +439000 cebe0aac7f629f59ee1b2928d8ce4340b247c0c619e3ff53b369375bfa71abaa 7e5fe6db2171c4040cf71a4bbc598983a4892689b7b8da5e3cd161ed7696a410 3880d26f0e572013c1f076793fa1ee719f81db61a9b5b2b901479106f0a87e79 +439500 7a70cbc08418eb8b711aa13b0a49ca6cdf063a443a0aace6b8f78aa0c9bdc3d5 c7107988cc60c6c66c2c9fce42c97303bfbe3d3db9ebb17da8416d0b1a918e44 647b6cd53b1ba42af61bf2f6e2c6d72e0d728774129422ed96e16610644d05a9 +440000 7649654fe753d823dc09f3ccd2157d9e9849e534962d5ec32f5a71775ba31fff 3670ea77b7e5a8750d63d8d846cc2e676e69539125ca1a3f66c1d1573e47ede3 e96b220b011bf5948e3398b3831dee3c7e7df23a46b3f68450be2c1bc9eba100 +440500 9ad49b33c96384a916c19e0b7fceecc324d33aaa8fc45b5e48c661aec09c880e e594489948d159bafb11b9a4151a89280c37b8f5665d6d209766ccda296346a1 9876c19a50263b8ae919b6b7c9a0aaedebf2b982c674319b9baca1c3e89e91bd +441000 2a3a6ecf5d7defaaee82b14d7073402109769a5a8c940d6ee1fd35f23303bf95 e8520de1202a192e8f8bc825b528d2fd8805efb774b18c4ab2f3dd153063a0dc 7448a30847d0c10547e0d79519e363cfa2281b18003306968133c9ad2c25e229 +441500 72fbb24c48304e9daaec1801004fcd4bb4b6c0c511932821a6d875bf4c9e6bc9 13850c1041b5b257adf6f51551051abcdcf13bf6d674e075c0ea32028011acc5 f193ce67a931e61bcaa796a46c0018229600837508a693a7f447ade876ad5470 +442000 d8d9a1091bf2e48609bde3ea3140ec19cfb7a2a14735474c6f9ef6105c46c8f6 8879f9476a6a342e58cb8ba5e4e40a9ff6ed0b605f3cd9b4bd9e6cf5dd2dfff1 21e3613ee1ff3bfd0f1461baa7f7a2a5c1d68e6a21106155607eefea238cfad8 +442500 78782ee99be29090c13682ee644a47f85f410c5a24c1976dc047f3249dc1e0e4 b4fd6ca7a0b0a77143c457285ecc982da5b9639a5659c03ba88315432e4881dc 978f2508e977ccec4c29433bab1606f12e4e0b324053e9f85abc6829df5f7706 +443000 a5d7115bce13dbdf436226400b23c30de09f68f6a5137cba50de278effa35891 cfcc7a433eb789185f88cd600fb249d26b8c945d5e5a5d7e978ae3c1c1118a10 dee8a4dbaebf41b33c79b1f32f679a36bc24c5c127a305ca2b1923ba121447bf +443500 f73cd58af88e5cc893f5a5981888e792f6a15cc06093c14e0ed91110778f0312 22b5b27df320f33c1856dd087c8537e5837c0686ccb436961189989d593b318b fb92695de156c669016fa9f27dd174406470b91f73cf3daf7be351314936c575 +444000 7c497c96ad4740eb68993e26ae3127c6c9e10b8625f9e759131574b87cd722a3 e5405706b778afbf261e0b4ec0a7fdca861baa26ec3a65f5e970769a8497ac1d 64c785620f16baaf73a811e570ccecf1c10aca3d189a2606d013947e7f5d9441 +444500 cd52d7101a166f4dea73875c0fa5c494db3419bc3f63d539e57c8e853e96cc6f c874b6d14b66ae740907a7ef12eb55dc0983a4a9ad00b27885902a11c72d8009 1fed952263d7cb5b5ce2525b5e9f9a2adeae5beb94bbcf18fc07ac91079e2bad +445000 30283438585b2c4d3409d61110cc5d400b0abc0cb8e8b65b9fd8619e54dc387a 3664d9de72ce8aebeaf5f1e844e44f5b3362d0faa80415de24c2cf5fdce153a0 7b642814a213d9494bf730f43b90aecc16904f97448bf5e2f6eabc288d748ea9 +445500 a4496d3bd4aea3dbe7cf7d2d5a3f0850f5c01b04662dfd38d3dbe6736251e91f 8cfad175dbdfb208dc40cdc2f03d0ebcbd9f3b12847f6d069fac33a5c1ba5173 25adb001aeda4bd4909bacb421b7d82de30a9200b70f520e4ad23759f7a2e3a8 +446000 7cff0564cc670e8a69315b18b0ee229269682bb0286b5e4b3db25f02ce0c4d2c b5c22f647055dc1204b243da18d999adebc56060e52f1f0c4d35450a9e941c68 307379f276df96f5cc93828b4ba92cccd6d9a2fb5a54d2cfdde7ed6e2197ccc6 +446500 201cc692970eec864c92e5e7af036192a9562a62d2723204366bdbfdb0741fa4 f3abf2331a35c83fb86e4484026fbc40266f5551bc90551b90be2d26b3771e3d 1e0f73f08434857355a8e7f1d4950a3d0ccbb5ddd80f5473f99ec0698d63a4db +447000 c06f8dfebb81f0cb3f19109f662a7dcaa4a023f1fbf735ed81fdd6bf9fa95023 0799398c8a29c71de6027c446de153b17b1bb364570328bf5aea872fa246ca98 a0f76a7d67f1f9336b2665b032cecae3e9cb80463c5679ebc28b7fe29c185d22 +447500 05185f624dab270906ae111fb2c43e838b70a78e0420e84fcc94bfe4fc911dbe f73e1007bb6e28fa8a5add7dc21539c7545ca68c600ebc62b10ae00382c9a538 8fcb834dcb86b9c51bf43cbffb9de5b1d7c2e30b22f783c99394787524f06ba1 +448000 4fc96bd14509bf55922cb5d8ed4cbf372f7ce991646e5be3a086204fea0c368d 0fff78f76cbc925b62ffe927d50cbc02dc83fd9e5405a3a77e232b55a494812d 67e09df16c3fb0a8fac40ee153922aac6983631f99a341cde08c05252fc4e11d +448500 742e9431b2ac6f0ac24e58cb8e6088ac1de875cda8f16739a78e0f1f7c05ce33 d892c34609acf3eeaeb32a384985fd2da70c4f53f59f8c459eaa5e74b3d61c40 2997569447cfd809ddb51792a754d7b497adb3c23ad38b2fb15082e4f09c53c6 +449000 335341c810fdea9e158ba78a542922754fac2e0fece92c27559d14c5c3ca0267 8d6340cdabfbfcddacf2991913176b17513be28b9472b744e7a64b2f2ca13896 b0cde57f64c7794da94547a5341aea6fc5680f24bb3188a01171ebc61415471b +449500 2b97e9d073d0b8922e73a1b1d6fcb7f8dbcb0e22fea6a707d9faa2afa1cddf8f 4fb82487fd05bafd111f032ee92e9864534dc93a7d0cf994928703612d816f4d 1c5d2bcb3165e293bc70060db78a5cf299d42c4815896b65b5f54d742923f434 +450000 a6448ff3de412e8784a4d0590120e0727c3ef1c6e98af7adec4b687e10c22b40 b12232c014cf52f4f8d0fdb4037642bc1ce2a4d709ae37b91d908c9d36830fd2 d0a08ef423f57c6c0488096bc46df33cbf920226423f7930c27c813c9d34c71d +450500 32343305ccca111d5b0396816091f1f169314acfb4974629e7beb8680523cd47 36cc9b37d7962e434782de92543635fb826a4d84fb5260ca0161680523f54272 a2ada16c0fce347e1158c64a85eafc07d49f6fdf5c91d0b1c1d973c3655d4f75 +451000 adcb05f8f053823db604b6278de320da2097890b386fe67c0104721e6cd76954 c63c045a3117df4fef3287be2f66c5691b700b18b42d3ba60509faf162dc9720 642495d66438cd4d827f29aab00729237d60adfa77f4fb3e74640b459b79868f +451500 c3f6f574abc62ac6ee2b65eee953b3386808361f721ec77e4df9bad7811b0c13 8ed2df18709fd8580694387f903d9c31fa4a7c5e3bf3845b4fa4e9a701441112 8b317080fb74b592ebb41cc1902a0a466d4cdeec51bd10f4da17a2b263ef534d +452000 b47901f63e411758d074dd4181d87fe30acb1b1623d0e69701093d93bc505b4b 227dde0bdd2ce1659265ced176e8c5514aa1d7c9c58c5f92d18534141e157539 f919704e59bb5bfe322594e6146c55724c38e493565745772c735583e826ccad +452500 723793ff45924363551d433d63f58d9951d58791f6954a6aa906d8c61f80d535 1a931421c2325c0c2cdea860d128402f6ba18decc20e05279f62f0d0f5940f58 46a8f9f7cc7ad3ada81614675edceb12361c35acbe7922c7a7223d2f7dc89010 +453000 14a86fdf9716b2225cf80394126c1bcebeba3be4a4f103a3497c8eb079ab11bf c0261d2846f68bee936c5ebfb638d9d4e6bffc53519b76ce72dcefa8f66e948b bfd4b0429989a852b9d98718fa499d4fc75245139046162a4cb45726589ffbd3 +453500 4204f92e27edb642343263ee5c8265639a4e4bcfe6743c323e5915af2db0f68f 681663c10b07fae27a187f5512c63f266d4460abd46ec1f464e8744b5ddaef67 5a478160537a5353e374707d131b56e1fe7efc9d5baf224aee671d7ae9449d38 +454000 d7173ff752ac555014e60e3928c1a8ba368d9ecfacec9b302cda79a6c6162eb4 c34bd72a990e253a26ffe68a91553b0b771083a569e512c6a46a52e5c7b6a724 ab445849e1252ba4bef39031ee3ba2f5d874002c669a39629f7501290dd5f656 +454500 df134eb761013d3ba1bd9ccb38d735427a299f2e275a3a1764ae436ba07f09c2 4d9b5dfb6baf847acb9499ef9cedfabe98dd58150569156e5bd692d1f7434f3f 75bce4c6a1817c3fb96328aab91271ebe51ee816a0cb874a4158d72e615f530d +455000 edf2fdc49b76a90ecdfcf0e238e66d574794b7ebab6a4e7d212e1884a21588d0 c40b528799070a1964e73025da6badbda9f994fe3d83cb4ac5fae95aa2e42963 9d6656615f986f128404fd2a501d9361bd002b72928d22f63d9956c264d9fecd +455500 0728ecc53f1b1b7be2478f687881eff7e6ba31e9d565619ed628ea9263b67a97 700384e16447d9873213d70063f468f9e4e9b1f780104d9a118d86b09aab9594 859ce00ed105ec338d519f2743a7b3a46dc19c8e7d86a31d1e4d4b9556a42f2c +456000 fee4d1a2fb2a99260e941a74ab4dc87e0520c28a115ba86c6382791b2f06f1f6 e0487333ab303a6d155cbc61b33eb1b23a3a9bfc3d466c32d8e6793328b3bd8d f9e43e85269d5bb16a54bb0eab65e7236b1c1bc1fd4fd2937776d0d37af7a9bc +456500 b5f05116bdbe8b51f4c1ffaff1a0e0a445e3a0f0c6c718a72d346162820509bc c7a2de5b71c4c7b338b04adfa8fe16857ba3c926fffbfc97dac86b0b75033978 6c99c37c34fd8f4f06be74b129a37bf12b4ee423434b3103205b7daa4a7f6ee5 +457000 b414f29bc13f7cac4f028641c788a54786bc9412ed582f4aedd5df86039a8e00 ce69e9060126b330e010d201b073dfc0e16924a8c11acdaa61c7776f0f2d8021 63d198d0d2d1fe07d46a18efb3ad448ab9ec6aa919b6309a4009242734c67ec2 +457500 c2f18fb64768083a462a48b87b993870ab96a70e325cc1b7ce676a504dbbf4a2 bcf97c78db8bc3b69a377a185a429277aa530aa853c7ea12c2ab06566e837c9d 34cb2719f39251f056d511bc2990386829224280c0253ef19a45182af0efb716 +458000 379e0643c8dab2bdefcc1cedf8118337bc0133f0c938a1553088230052f5cfcb 22e7617308101b51b4ddaebed23dc67e0d1e0b3f84c5074039ed77c466cc83a5 09ac8a585922541577aa4698c7590b0343345a40448b854e441bc724984e108d +458500 5b8d6a2de4952aa7aa38b9a1d403fd80e65f6cefb5e824c062d060894d490946 56ff3b66fcc71ae8550fd0630fc358edf11f7afdd551d69a2ec9d4b9fe154bae eb82ab3d805a77df91f9aded634cc7e9b1d0e197f274587f144f6192534d4c2f +459000 426443a695e4615554b95c1070f14391c199178d8be6860807b69cf2d686501f 40015ea68bd905903100db2ed67d0a0e25510796dbcd1bfaa0b8dffec058ec4c 01cf6151b050ac3c65f8d273b0aa9991afc6d2c99a19b73eb58c4458ea448582 +459500 561074bb87ee4d3132bd22b91af78df7d2cdec1c6914b43b12a4004204094a4c 86a908568cbb19be09a1c70b4a92a0b3022e5d0008ad78d6ed536a9bdb08deec 3d22d3d556bb349cec89c50054d81ad210e9c4d93585b8907192bacf920221cb +460000 7adb9b6d14e8124ab25bb4696bc8afe6a96cdae5396ac2a5d6d859c47236990b 6ea2894408475e17a8c4476b5084cd76742a3cdb97292eba2e2ba0ad4bb17d87 e22e9309202f9a77ce29b5772f411c7ec5e47689496e4cb566b05a01fe71da97 +460500 5cc330e1e985af39a1a24602603f26535df43ea7e5e164c6b654f292bb359633 69c11c20de0f89ada1a65781a2b7e7a1e235f964341eb70434135888794032c8 ce3fb2a64db272c7138e730e433a3adf8dbf7b4bd754a2c1dda585d4475e3f0f +461000 c1c45b5a71cf6ed3c5d9a739c227b68fdd3cb41e8102b7e99c28084776c3d8c9 122728c928e7025fba2e58a3b70cf5dbf448e26389be3606b43f3b014d5f2001 39ce156b16a89759e1827b550c1d56bc9f9b9b45e0c8f0c1c70922220c3ec34a +461500 096479184f5b32532940e42b35c51e50008b8224b2c6d6317dc69478d3d316ac aa693ef567b3b7c4a7091b5bb3d34161b4235e7bb3b573a22e66bab0e622f16e 9e242e78240d389ae4e2b845e3fd1f4aff02b280e743e5a0232c2be5a7d3ddd9 +462000 c78d5a646f9130aacd23a52cc3dfc5a084add7fde9dddbefdd13d5c438e024a2 3242055c63d5e14c1efdba0effc3580106e14c443a3c39c699931a6c4a36c94b b586f9c9cd03b22f452fb7da6fc1f5026a53cb86120ed1af6dc81d77c841bbfd +462500 b464f9105311560ac63c29a94f8a0a5f378bcf5c22cbd23d5818ebe2e62550d3 4b91a857ed6803609c0f1d514e5793f3f63ea3dd37f84b345c3c64c7248f8358 6e0a56c8afc1967c6e3e9eae4ac2cf0c8dc6437035a07dc4a9fa0b282e539900 +463000 ad7d579916aabacd745a9d48122a64e420ba111b8633119f6110a93125eb6072 ab7a1e347245f8d9ca551cc5e89247e18d130aa0180d375673de0578dffdec36 39d7e8e516f09f532c1eb829fc0ed11e3489ef4d42e34a14676e84805d831ee8 +463500 9f647ead66c59424ffdba0067d38a93c33cbc5cce95c1fb19483d3138d9a2924 f9be09f0a7ec9832b7d2e238f0f3841a10e99967b378bb93e1e8ed95025791e4 a0625aa3447319a563d31e3a63f67fe9a3c372809e5e2d2b6eb7ee328191a2ef +464000 8239a8c5704697db70720d8227fef8093751df0e79bc792a4583106c5229d97c 56a2bdda4613688231ea85b9d659f05000786ebd53300466da5dcc474f8386f1 7f2658ce497a6ba01c6b9a8e02261fc39102420f84793b7e16784b2b5a962d11 +464500 b8500802e87f0a3d08b275296b32aa66211d93ba13dffce95a77f4d2ab6ff8a1 87c4e1ae3a488895890a0dda084969a43703e9abb82fa8a6b0fffda090b1fcb0 60056e3e3de9d7893dc58b07cea9258dacfe904a71949f764579ef6f9aa1ee28 +465000 9c5f241c6d7947c078423264cd080eebeb852aca6898b71dec1f2fe0f97f40a4 eef3196b8ab3c6d1e3df1eeed6f857644e50f6a751843e308a86d72e945cc6b6 ecb9587021098efd5e2df880998cc544af71206a067d1f5f5a57bb6b4964e95c +465500 714cef624738d796efc3fb3fdae8f42478924d28a0644c225374b1e5f8707262 8d68d66be9f3952f46bcbe5df4829d93eff2f4501bf422582e8594bf3f03730e 2cf7854558253ffb17282849c66c8db530c422810e2b9a35c1df67c2a403af0f +466000 760869daabeae89da11828967600ecfc92ff38d5eb79326da9fc526ff88e3dc5 ff631213c2cd21307d635337ecefd200cc2b7767c171ba5913ecb785d6876aca 78b71f347088929e48f5bc408ec2a2934f541481e3f26bde43305644ea391548 +466500 9699ebe38cd6fed8bad4e96c18eeb8bbfce93fa6be86c0c364ac187c246d47e9 f18cb4eae80510bbccc360228942bbde0144f6c66f378e0b4bd0005ce35debe9 15e67ba70c538b0d6a1ccb9f692d496d163390975c9c6acc4f245818dec88a32 +467000 6de68cf541236c2b20da6bb789be6df085207919a94074f31975a54250c4d918 0c998a0b617d6dbe4454ad981478bc5903ace25595e5f868c6bbab61f80cab09 2e0152c2e09f602ccc26407b314d0df711ce94d81981b4c6ee0f6dc475232665 +467500 34aae978a356d729783acb130e2238fefadba1789ddf82d73b87c79d862d297f a90873e05bcc6a81932e4562242f7ca201a07707b505f5dddb46418cfc26c5dd ceb302532871d7a8254e16b214ff73614ccc4274b16e9d28943598178483f575 +468000 96a959479e0159621c8660165d2053878cad8adccc1ea5a4020c4a1f63941b09 ad947d10fe2c2fb1f61572586b941c872bd958499342e2e44b545d4c0faaafc3 3eb3bd86f7ad52574f6ed3dda2581091096b326d49d53384fb62e36450299dae +468500 ef36c23495b3e062fd2a92e24164f80a01d74452d2d439a23a38e403e531ffb4 5790fe543b78423f088a1d53daf1692a7051169bbf1e469caaa7d3862d709b2d c7eef6ed2d806de2c40c6015e7ca28d1489a699c56def39a220660511b8c460c +469000 e32fb17dab672f159e97ac45ddb12dfe0dc0bf2a2abdc455beccdfaca5e2c69b 56f4d6e427a46b3467c26174b6a4b66e30f5d962450273ebaa598c06aa31975b 9c227b4d82d86a5603e5b07eb357bcdbd4e6732396b6e446532954b4ac31f263 +469500 3870050849e79e3243d3460ea594ef741a1d6327f5d336f8036fa5e97e0cfbb2 2e0823dd7f7a137a063f473cb6991510a112460ecacfe18aba39094d410c8930 94dd6c074f375f6a33464439c1e6f1a2f7a5d8933c0ad2c3e971e9faabdc8502 +470000 2aeac4abdc914d4ac3fde31a5882b242aa26f1049c86f703fa5da279edad5a7f db8d47e66737aa4776e8cb857386d346d356ba91d0f6212d8aac34c9ac2e5906 c3599f29edfae99bd37c27e39acdc17960c2b50c18c6dae37b1499e2e87e0616 +470500 fdab2f454e5102f44be86a36b7c2a54aea2f5681bcbe811942451827e8106734 cb60e3d4e6620535cbf57bf0f94c5055eabf0ca48052e9728fb28f5ec913e5c9 1af5a3097081200030a5ee02d1bfa703abe356f23003c9985464c9fa1e69ea1c +471000 afd4b785fe4656f48ec1120a14136d133df7059eedf76f407dc2bddb91ab0ce4 0eca3c26dcc9bd50d78a8322c07b18d59c7609bc6ac97258b56b20ac73187f06 0201199c7a9201bc722195289d50bb927fbf05adae168d1e0355a1a519d939a5 +471500 e633efdf19faa95b16be4cb94f7072dc1238342d624bb4d69609555a927f2522 570bc44f8e51f6dceddce363db3b87fc17d9c8ae51ab9266a3d9248b546df4cc bc1d5b7d7b85c5419fbda0ae3517865bf429ef7ec3877654639e6d1120a6a04c +472000 d4aeba089eca88aca7c2b7cc89e10146158dac72fd7643e4c7dada43c8645757 e49b1d22916fa97893a9f31f31bce50f96d49f6a388ee1c8ec2216aa619d9101 7fef7bb7753e24b89110558c1711b0f93b6c666cfbc6e21b2be9e2d7de78964f +472500 a1c6bef24a340e81f3212db55e9db0bbe8135334e14f66839123c21fa393ea57 1b5318294e73812e157fd78c84b79a31d076bafd91aeda00fa49055003be7e91 6bb3a2ec06a00afff5bdfbfb4b4ac00397836a5d1e144ccb39b9c81f65145db4 +473000 c2f76403fbff7b3601c0b2bc71cc00963cf0b012e09d6be5d8fcc12a8f78c8e6 be2ae59d51ecc553798bcd9c82f4e747dfd1782ad18021dadc24e4838c2b0666 0422e26c8a7eb63d5b18dda0c3efe7bc646e75332413430c532788704507625e +473500 5f6ff7d98fff43942ec210bff0555d74768aff3e5fd5ab6e0b546d0bfea79921 b828dfae2a89c1199e2cad79165f815f8d858620d87aefe17630048ec05f0bbe 5c85d46886845128e04460eaf50ade9e4c8f1c3ca6456e74f76061492407c9e1 +474000 2c191256f2a1ea617517c81c3133a47d2fa264586885b2ca6a7b782f9c78a8bf 7d0b4169707e36667345fa68284bb9eb0dbbb726b9391ec0b3018c71a343ce0b e3f7ea82b53a82fe22c0b553fe30c4c5514f5a4df2bda23b6c315d894612822c +474500 50b6c4f4c1da30ee2043c4a18b0dfa1da9aa33000be4525bb07b2462d8cabd2f 9939b0eb461196a4ea22dc6c0e2d3c776cdf08673694e3d5a520bb644df71e9c 5a123ab254ec518a34af619ae78a6caf68f12ab08ea1cf8bca8f9ddcbd5bb862 +475000 2c38054fd7a02ffcac28fb8c53ad84b68d50ef30af030e597414e15b59bef269 6faee9c17b651d220534dc8c66c0345d162426661af23bd6be235d1c0eef73ab 68fd23bcab5583cc821cc1e2fdfbd4630eeb912e69d8d3ce68fe22c0d8d55881 +475500 8d981411752ee6b44f12860a9975ef23df0c7dcb5b5c621368be19033de81de2 23fd87f81163c7f0580a7eaf5f74b7501a868508ba60f47836488f5b72716608 2efe456c536da42607c5d527fa75633d20e07ed10e8d747064e21e866f115e06 +476000 27aaae6fc04f000f25a467ff5c2fcf62a6872b3ea96a3ca445e0947bc912d050 061c4b35170cf452518590f1e96624dbc031e5eec8b9de1acc81a477bbaa18a0 026f245193b14cd91226fb93bb05307b3f84c121c3b4cf979eb48a4899e2329b +476500 84e8616d4259371a11abc9625c4f7d55ccaf949881e017b663f249d29aaabf70 6e6418118d4d34c06bf73284c95f2e3622c87c42ebd4a8e1380939e6abeca428 de01d9328991d787e797992316e87257c9925542e3b8d15a992f185f5f4556e7 +477000 d459f75729583c8259ea66e8dcc7b8e1486b0a30e14864332dd014757bac1f5f 9316f02e5bffa72a4ea6c7809be57001db28415e75048320d33dbf23c3a39e86 6af818c2d7626e65486a4f77f8962944a3fb51adff66b53fb70630225b0ca9e1 +477500 329e7c98cde787901a05bbae8aea2a10fa244630640182eb9fcb80e83ff47cc8 04fabe2b506d1c811471d88cb7986d2a67a988e0e094936d398af0b20dafed91 2ca5bd042acdd1149737878821deb3ac9ec658d4543b234dbd4ba50499567e8c +478000 8515a758d83284a93a354e91ca1389d0dae0914aabde4c7069180dac0f88ece2 0f9d14354952b22318f9909502aaf188e43c511ea6c627724bcb7f0d14550233 9f16c907bc9e804b8d89875191fbee34dd334d0398c5d10f02ee4669d85d6fa5 +478500 e0b6428a55906d115c2365630e7a748422b1309a75df0712730a018e138f8ae7 75327db1cbc6d65c203eea4cf697e0e8674ff0cf180ad7730c0f42fac2cb2259 7bb6036c936214f8cd8d4fce9355d6892e7ea2f768580f890a4e09d0e9c3b5a1 +479000 acdd6bdcb3e05e00631aeac70db0beacb5ff7339f9efffe5d125a748e050cf0a 2f4a8780e4913da0886b73e399430b0a65b84e906eb7b47bb14ef6139699e222 6d47a71a51d8b75b6949e5b95088de3af2446e78cee21a33e1ef090f9429c04c +479500 173ac0f8bef2de4b544b42c3506aa887ddb348e6f719f2b4fe16beb569b6b9a9 550714098a237e5f2a2313711787f7037937081893315ca43450ca64c071c798 9b628260e5d8678c6d02155837bd823d326a33c57c01b120f2b3a31d198760be +480000 39a37003b75d37e0588e177d5d5566dbd2cf4f1ade343067de439e4e60d401e7 e90cf6f99b06ab2f396192723accafe62f0a7705a8795b39371238dc660881ff 2f6ac37efcc941311dd89b57197c45e684d33750139e46891fd25f6d0c7126db +480500 675b1ab9b45350f0db5814692844dedce30a416b0c5a6b04e3ec778de1c54476 0cb43e9d578692ced5b3c43a067a09dc8e582a12e46208e1a26841645ebbccf4 dbcc352ee3e2b565c678cc858df6b3ca0898a6ee07073ae621b1605803aee606 +481000 c49b18c02ab6cdbcbd1380535c394567b0fef261db605ae42584fcfc5657292a e45920a96e78f6ef20be3f24d9a8b1accb6ed9b0a9ace38694eba826aafe2bd5 4e13fb32c6795e96ce1576e5b38f2874d22609f4fec41fec3a63a8f1ac98351b +481500 e70588e89d0a3a15d7de9bc26e47768a94964a14edaa0355853f5629a500dffa f623feb088592f1cc01e94f8984e5bd7f5469ce71ff7645ed81648dcb25ecebe 8004dba192b725abd95366b8f0dfe62ab4a75cc3fee5c1c523ba12f765c33f5b +482000 bdfa119169d8507d41720ba8fa40f5ecb75267570ad0ba58e342f4351fb74575 f28b44f2e70183e19deb6562a107d204531edc8b46d4f5aac76884d7d3a9e750 881e217cb102b28ad20cb8bfba39b8779f7e857a9bb94ccfd0ed5ddb61a1bdaf +482500 14e2be2612c4290229084f2c1edfefd0e432a91254abb83ef8ddbe8d7bf2e661 aa012dfb4ea0b0d0a565fd8f2f55692135969aeb6a9d3f34cb17b31e32ab22c6 6eec8e5808b4e00484134d46ed734f238f979fcbf3754d9017f79d718d1c4b6c +483000 8cc62d490274477579f93e8af507c07b3816d393200aafdbb6b68755b763c2f8 3bce0766356c52720491791bd9cc5a6584c48a39d620bb185f368eb7dd7db697 aa99ea2b1829fce8adf1831a2416e7bc33a6859ad82269d58a3d3a5f023df47f +483500 72c78ca3f93bde96a8afdc199714ae18e9c15b92526ff48845c050047343f548 f4c218fc750e8b31e2b4f56ea5bdd7f027227b58920c7d08946d193bd090a366 c7564a5ba5a84fb5d02ccaab954ca67b1a37d88c7b78cb89176fa968c40fceb1 +484000 ad5719becb74523e16221adb2353a4786de357612d9e2ae86753be7035d1074c f040df388303fff9b7c97bfd38d55a94c1701b82ff4f2d594b1f4637fd8ba964 9afcd022cc235297c99a8b00e63d94cf20f89fdc1532c41d6012e1fd42672caf +484500 a143595d89e542b00901e959c20b1bee243c6b7f2a8bd930401a0a922586308e 1c50e70afe27a5026a6ae968118f5141448e69955b431f74c2b94af7bee31ffe 76628ba63114b144c59fca247c50c53f4bdb06cd34b9b311473d078aae6e7159 +485000 ca0faa2c4b601116d3e03c898bb6fd6de955e9e083910fcbe93303702522fecb 98250685f5d2fc349e6088d617a7986ea28204843abf4e887ee121b3f89a2b36 9db6d0fcaf950249c2dcfafb15777159cb589101637f7c76752c04596588ec2b +485500 1d2f98bacec2bc91b7ffcd9e760c49bc18183ddf1bfb4aac8145abcfe2f91adf c03ae99bd105f3c8154bed1630bbfc10d56a2aa4e36a85d4a9fb2e629920e285 422ad706d5de44123c1e68becdf8757022af0aa1d64678c7787eec828ad5d214 +486000 3f9896825fb06766d9216cf1004aa6d2541642253b2980c59775fa720e1af9d4 e8ff26003f9db4ca25d4a5e8f22c615b6b376f2aba0b6e3d3ec1fc54bfd3e8c9 1e16510e1f176a888727956adc3c041bb83fcc512425f57a6c3f558ae2f46dd2 +486500 8387046d6d520535e933c40c8e7a9b253dea20d1d4fea49c53cca41d13f87b5e 29e01fc49acda9fd49203e03a86fd7fafff8dba947e907ca41db1b6e2802081c b68d45a08f6fb2acc92fd619b0dc8498ea81fd57d3c5b971d5b31803afa79a6e +487000 3ee4cfc2068bfe1472bb2345900fda4ce7d99aef724ce5c35e8dafc97472a163 84ee857e054c6f118f897926d53b546c4fbaa38576d66eee4560d88f90f2ac91 1fd96fa809024f42da38f6f5a75fe6292b9dce007ce635ed1aa865a5fc20a330 +487500 7802c03efcb4298fbff0c05c7c2a2670e2b5c5c0a912260fca95f5ee401f9fac 9c507f7adb01fdb9fe8edd09d969ea7b12474cd9f317e6e0c8d1047f720cfa01 f271dcb04df54f998866b55a7d0727e691c2e51b6c1147f668cb2542339b99de +488000 6c0026aa2c04a1ab5ab59df72d9ac017f559889453749c95937e01230628ff22 89cd039f94be43a6d229425daa26daef3bee7688fd591dc954ee503ebe2f3573 3ea3b7011c70b0d49b9f36bd7b83265128b7a1c5ca9f69ceeb5ceb933cb959a8 +488500 ad7a33c68b62d181fe269bb58ad9f00b48b4b19f77cae3c68407ba81af9e29f5 e26367c609049d5cd867041787aac089a459ae2a39e420b791b778f49c4222e6 1978075a6d69518c80dd58998a9f9636df40421eb6af7670dbf683db894118b6 +489000 dce5e567c4502e3b3344804468bd48900df890568521360b198e5b7e48c4a7cf 497cd478db672eb3f6e975b722a162b26d5f0fffdfeabba6dc28664d4dc76bb2 d1d75bf13e39e9c5d4dff8446d5092619012d2dd19ec4f53a886946b47772c1a +489500 326013c6ec37ad623eb9c5a35a51c154447c8e180d4efc381f02a791c8dff517 81c2d130a11e3caf98c5d4af0ae7c05bd5d79099d5c959efabe7766a211c87f6 27814c5edf60b9e069fba619805454722fb7357b50bba2dcfddae253611c4a99 +490000 b0ddbded4a9bad235b75d2dad597b8fd87b80cb721d2c322bde82e9bb3763d72 5abf2e1aa1273cc9de5eab070f0dcd5b082cf7459de699a96e7b12dae3311265 8a5c2459345000c6403134ff5743329cae055dbef1466abc5cc078187e8fb304 +490500 40f093e9a8e074fded5c67276c85a0261d15f3e418e492ab1452e340da3c0469 0d79b5359c16640713fd6b885d6327bf67971e99395eb633ec71edf9f67a0649 37231655e968680404305a8056c5abb98d300996f657362803b1be28e6187664 +491000 42ff56a78710f1d58f555a7f55001a1760c7090441dd2657f959a67b2d8a8289 7a167a1f0656c972aaaf079ba002f35ecb7d47aed4c72a7da645276ee21f9ae5 68151c99713577c18520079cb48c0d1ca1b2df2de1237fd16a153cacebf98b2b +491500 38a42670dbea9a526f90e8a824bb52398335afd259b0d89f287687810cb3a268 c4f01d0a2b59e7cedc7957ca4dd510eb692cb5ef4c257a76fce04c3e51487e20 831668b7ce58262b8741ac9bc0a07cd87ef253aa348af5f4c5ef54ae26428ee7 +492000 1aedf52ef4f42d0e049cd6f2b564a1416ff737cf792eef860c4678cf4b1929f6 a6c9e1dee9d08b510553bee2acf0d1b8b2f0bcd202ae4d28110fff8dcedd85c8 c83967d6ff555c205f808f7d9f632bd3460e7e5b88fad92e61770c772eb7171d +492500 d7c8c52fb1f9138293bdf0c28ac68aa8447efcb1246b8896a1777e5b20800ee5 0d6687cf95402d4df5a9115b6786b1fdd27493c88b0e1fba921bb7b722084a88 462256ef01f138f31dea3dc2e783f733c65cc02d6cfdae0e71491e903bc0fda1 +493000 e4265d17c243d4e4dcbe12d216d7dfe7e4e3b7da161226203881b0c007f2936e a6f9daa6f9635dcf4a2cc894a4b459a8aa5dc2ed487d95d733bbfe827aebb0f2 7a1c0950c21786b59d9de46274908bff4705bd18cc0b5aeef2b41fdd27ec3c9d +493500 9c3b415ad45f42001d88e2dd38748048ef9f40223e5c1c62caf5eb7912d78b42 e68eb0e1b1b95dea2fff359dc5444930588ef743a58da356b8d33d8e6a0ee1b7 332360bfafa171fb3f3f7333d63b494e7a7e7d6642a5d1932f9ced9df92dfa13 +494000 e78ce6a76a928e878b6cb5a0ca25c6b9a8cd69d4e2db9a066e702635c11ebe17 ea5640b26510140f3abd04e611f124851c15338caa163bea3a5032fd0d16b160 517147f19ca77c35290433c196ad20dec0bcb92db6751efe04549dd1f9207971 +494500 cb62ce4407ef63b81d3afec33e7b57b31a6e7c8b3e0888b8db96f17e4d39756a 6600b14d7f4f7bbc0f680587684f9fa7d5a7acd26cf9d103ac31bbedf9d6afed 9a6c67d7bd9fe4f9fa89540b33d9db8c61db8154018f6ed22b0c4f6abb1f885b +495000 0e8a7e8cc89426af75740fb8469fc9616a8e75401fc785a8e686d5ec0f4e5732 0a1ce34d16dece7d7bda04e5b9bcce126b08d7e514e0fb37c5c1b0871cff4cda 94539c965b7c4e0272e499bc3eb27ca73c2a77321813c6c9a3805d5b99dd51ac +495500 ba423afca93230eb911c2f4dfbba40b893b938a7365cfc2068e1ecd3bc770b5f 5720feefb7971397896c9a270a6318f2adc667cb20f2cd218b2791778cd50680 a3e540aa54bc1cf7419598be27ba01dc1b7b295fbd939b9ba74dba091169ea34 +496000 352a1fd91dc52fe0cd78e2de4240e75a785420049e7b95e01adfa3d1ac4ad512 781da1ffa0ccbadf08f451c290221fbef9b440c52b5f7ef5bfa3dfe51562de47 63cc34ac782e8fe5e1e18aebac8cac230295662f93cff675909b338c9899fd7e +496500 d0743556e112656c069f2749baef59ef56225b6bbee44b2336ff106773fbe965 ebc3df7a34a4a4e9d8a60151f4a5bdce4f40cc8864851520f5161abf9b9e6d51 dfe11ad63217c9f1b6fb08b45a4084081340fb5bb9d284439d2e3276214e0e74 +497000 1887117917c8adb81cfbf85bd4950684145a964a12c81ca89a44fa107247c275 e48c07018555f1a8be3ad71f6ec7c31932eab7aedfb414c99bb793715ec36e4a e29b08fff1fa075aea805b5799be10d3dbbbb23afd76b9cedd88f5fa2555ffe5 +497500 2ffe736439e02d764f544aa4f86a125b1567ab7d24a9d944313877d2d7c39d14 a2b4732449a3ad1488478233895bd8ba26b72f14bf839a33d5fc0f2934bcdf2a 524c1cd19b37aa1c9d5cb5da2733d04ecaab6230db6555143fc8ff1d02657fb9 +498000 0bc8b494b42efd68080fb3d3d83cc8156b56439c10fa789814d751d5c4f7d9dc ea1ad23e7f85ec30d138ecdf527a5ec5ac6d925eb888ab061b9ae24e48e60b2b a9ff67fe494fd28395d671744bb1d60b38ac89b53e4f66eadbc03c5d5dd31bef +498500 5440fcfb2e8888508c4fd6920d0e6c7c1f3f1095813d45b691edc3a2a475722a 4c2c9c60a2a43f9786004a9b43275656b60a70c9643d6c676ede104b9f0cec12 de98b78d64b182ef34488808079e358e30189df43bff459894d14b47382d85c3 +499000 d84c475656720900a0b3765c4ed57ae1f0ba17238d34ac17b1635c6c95064750 236f102f6f2350128916d138401344233a7483a0dcb1eb39730c6a5fa22fed3a 88c61322be07f9b75d7a58001e4e7460dd34bb2a72214e949d28f184007d0c97 +499500 8b9aabf8cb60c29c4b60a942812968ab80ec48cad4053de2624d42372a547756 540651876cd6a44a6de24fe75706bb959b3a701ef281c7b8a3ba083d6e329dfc 4d743db021924f24501d20e27564a7dc2276c5978e0000af4a97eeea092703b8 +500000 bb94f21cd879e992217888fa56f0cb57bf585f8a41f845fbb46872fd7ddd4a40 541ce9a7c0f8771a84281db66fba7cc2dc43fa636a39a840fee5bdf987a3348f 254e33a659e25fb647aca414051e33f03899a896d032fcb7d307b90c9080d023 +500500 d74c1f7510c4307c942906d4c66ce5fc542f2a1944659c1ad37a0eb82be11751 976e8ed703619833f8d78889bb8a3a71a06392e257b093a01f7a1b7036d22fb0 fb7d68808d45544296419dfd89b69540cdb6df0917827d982ebd72adb3042843 +501000 3383f0c0456774cc529b5b0633a947e0708156bc873180f56fe3c32008c8bdac 69c86425b5c47c2bc3a9fe3669b0a80aeeb72bad8179676a55dae6445b7bdd36 22618e433ce9b9fa9bafacecf096c50bb49978a2fa883ea1dbcd2211075afee4 +501500 d076738e554cadcd99a14287f0d0af18fca6f893e6ab519fff1a9c987e3aa7c9 9ceace4059979133e529e2e33930ee2ceeb2058633e06c31efecc7d2112a2437 78706172ed2a93a0610e3f40648b1817d60fce479eb8d39b12cd99527a069090 +502000 03b70f8f87fc995b1f25c5979cab284b112e66ebeec690dd93e6c1f238ab616a 5c4442bcce1ace2848f3bbff98abe5776b58af7da464ea4d8ce5c681ecb99261 83307faabe36b7556ad019e41b11f1078ed9f42050728c949934b0cf3356910c +502500 99130d7f62752e1e0a7318ae3a933b638ae37528134af7b76590d477bee107b5 206bd50bea02399a5ad897c4e1190e96ba7c092f83cbad5e0bd65955cc253219 a858f0c5073b29aa642dfe18243bfd3c1a488c2e18379e8029ca8f6c723ae8f2 +503000 3eeca5fb5aa1f44a7a86e9c2756add708089ba817e4ebe983da92bd815fd51da fc3643c494c343939f26a8237b3df02c2b96235e034e92e199980834ed4a59b1 2fb413410aa7b7bdb682e803b2c3d4f17c7588a3c2ec33b17853ed85c2dcc299 +503500 8034c879f7596a3d9846ce1ae028fa596b84c62313f9b43564ada16c3e2f547a fd766d22b34e5e391c7a3e8c1318ae469a763ba6c49b75d55b0f928c83e5f992 1776e527de48623b8a469082e8bf087f40bfacfd4ccd1711f14f7d39f121e8a7 +504000 bbc5fdb678ff466da54e09ab29562e16a798ae2a05eaf776d97edfa35c839a85 b6dce69571860fa8d6db1cae19087b3232b06b8282f5b905a6ff462528a1fcc7 94f9788f4ac548a410b0a32abf35971813f7a3cf18dbf06e3eb70ed23df7a0a9 +504500 956aea829d066998cf96a8b8edb9a0323dfd018642692dd7daf59d0be1b31ef5 f90a6f0b96ed84327fe33e6edf930a439d1843046154fe1fdcd65c011aafde2b 565c856c4321080b6b270e3d385f85ae3cdc3b0a2134f4a0a6b32a8be8370259 +505000 0a3445456f4807eb2f234e51acf42870aa7b6a2eb96749ac3cf764979d3aeb14 f6977bf4113ff5e28895c0f148fa0ae812a4dfed4ac0483419d08e3493c90e4d 32c3920d7fb47fcbe62ea2491212b56b8073d3c570380bc5baa3d6237794169a +505500 fdf15fb92600803d9d99b54b13c028ebe2a39d0681e7cb751496a155b11a9656 6fdd6b0729448d9a5dbd5b5ec1198c5f89d0a437c9019c94e0cc4b0cff9344f5 631072ba472ad83e323cbcd05121a6459818c95c77d08d40bc06f19333399386 +506000 94533d7531d5ab46aa3ad4c03ad71b8a6f78574805a683be4021d3648a56b0b0 7c1f8200acab1aa87ce1ce548b727d3c47239045d9dcb6d80ba58d908af43c99 5dcfc85d934f268608d9a3ff0efd0a6b0ea46c24c31da5b41fc9db5bd9f417e2 +506500 0f86a6ffdc4880c047c73dc16aa8d0bf27d1dde7700c2fd77e4cdd7e7d926cd8 e9c9a93746ec3a17feb362c2dce6e9a9c51a0d9f0d9700d21bd8aba906602e95 397c09bb2457cdeae289fe4bd827fac0056e60cea33a2a2616007bd0a7175811 +507000 431e08381fac05624f905ca38d18e788204823803e0607106e147bbbe8bf688a 4ac228d8c9c41f4e3d3a3c4e320ed04c13be367680f9fdbe8f6e5a7ab2a23f36 93d88fc835441329dbfdfd0eb847f44a30391a86945ac792211e0271ea4653c0 +507500 a227a08c0b6d0818ac30280e4cc9f422bbb17cde711c371acb7fc19c8a642276 6dd10139c09a88ed1692aa137b788336a80ccd60753eb237e90687a15ec987cb ba460e1c6e185f402765688792e23bcc17f2411db8e25eebaa4d43fd239fc9c7 +508000 ac9eed373dc35d2906cefc9e3ad2c8044253e75789f4d028b84a5acab33f8187 d4fcd4e62b88c4ef4e9609e8e5c85ba44b15b999dafa68a7cd45eea0b9fee193 bd867a112c5c29790dccb96c03a55ccdd2da7feddc5d9a3fe946bb8af6fe44c5 +508500 82837e772818deb177c58056f9b8eb8c42b42c75053c206ce64d4cb0caa569a0 088031bb4d6c8d50690782746dae3a2894e04749cb8073703758bf84403f65e9 7104cdf4ab6dc7991d885ecf65601fd63540005c3b90fc40d356ee5179559484 +509000 46d4c946d3305147e565ccd6bcf5049931048ab9fa78fe64a45fcd29df7edeee 0d2fb9af0d18a37f8bd0d90677391033552038c5d24a58db89420c355342bc33 db50d238011cd3ae24649f78ed23cd5e597dec6c269d02103488fe12d55c0d05 +509500 dd8574ebf8743606a8b2692ca8fe7c406487b6ba9a0eb1194eba2631c7ce67c1 2ff727ddf8cb09ef0622821c1886cb8270d4401658d2249c402f48a6ffbbbcbe 3a14a7e0da7f1e829a3a42aedbaa7d19d7913bfcd235a8c62851942dfdd651dd +510000 8b496633b233a6ff9deba1fc40f3e1ecff693d91d8abda762bb165b4f10933e9 3a409f0d90719857a525deb2038518acc44e2e710e3f51830c11f3a83c89ec22 29ecf4fea155a00149f0394f8a972cdc29bb090b20511e214e1db1ea2e3185ae +510500 1052dbabe3ecd64ab6a4b0b05f41c6c4131f5beee2028096f688af8da17151c9 0cdd930cbfb6e609de9a22d029c15c5106fbb5603222b8e470a43594d1ee1dd5 df8274c837ef863b3be71eeaa914d08a305b8080445467986fb0d082e9efc681 +511000 e1718d99ca8b8c0e1f84663aaa6ac9cd8c369e9118bd6ea5919856382019f5b7 8320100810a7678c08ef0003dd4f057369386278d95ac3d9b316a062b1cd119a 2bfa8f88541e9201f152753e37a77308212371e9ee9637f6ca5494835375718c +511500 df937a1ddd9ab676d6b958c03e97b7789fc0b486d52e1a518f4d4e46d22db830 e5b333e553b5a4bca5ee6f4a3ed9d83ba46d981a3ce30fe8fe0578788a400f42 a28191834653d7ee866bc1f494d2563a209e6ff3ab47481b98fd97200dd52be9 +512000 38982a86cf02da0b76412cd5bc52aac39854cb1d000c7f24e6b66061c9552820 7b4b3c77c94a5b9de5a7ce479a1c15ae56663e655104b0f0efb5f3adb971cd4a 842759a6fe200e67aae64ce6726e5ff2ce631bff7094456b4b584dfc985a363e +512500 c668fd92e5ab8abe4fa8c66022eaf0b8387408849349453ba8751194bc9ea391 aebb86a20afe467e4959eb4704849a076a8e02cbc51c2dfe07648562e42f9f5b 23e62a8921ca4fc780d6323c4a18d14eb845f3a1007392e7b7bb76b18e503c87 +513000 fa2042f44dad2c0e4b243fc07a60172d057c7715b7d7f73e9cdab068df241dca 9bf87e1bf1a619c55107e28f3abdabc3bb3267a0b0225855695ccae2be2c8492 242cc6413f3e77fc4612f2dbbabd708b8053589e852776a2bf64b49e3e2865af +513500 3ada907b4eb50e027c4dce815bc8464aab74eebaa02c3fff63e829fcbcc06790 1504730fea3476e4a5a65059e9e45acf9fde314062f93761273d0d47ef900b5d 55f328b9a86f6704d88149b0a26c708e495ea614fc7c5874d8f45cf4e1d26350 +514000 b690974d95cf519aa561d59afc9812bf23f8596633d4e43638aefd0a645cfd9a 53527239f3915f67eca6a1f57a5b82564ca7c4c5344668140b960adb23246528 557fae97a12d934a1802a877e722fbe2e61b98c388bcf5785238414582179dde +514500 4efdb833ed17ee35a5c830945a287adb464a23d60f16c1f1d6d3488d628df9cf f6990f581fe79ffb9d1bed01f84a338213c70bc996261e07507624df42c528a7 d3f812637fb609e9c825929ca166e72fe21804ffb2d76b081ca43e9c6fe388ba +515000 f902ef1df4acafde6dfad28852fa03b1961241be620aa057860c9a70a0fffafc f8f7c7f68536f87056eb0a199f0112974f80f4ca443721ec8c1d67c3cbb7fbfb ec115e6892b1887bf0c592c1e8f756c40dcf0a6f7e11898940d20377ed9b56c6 +515500 df363417aed948a08fe0c6aa48dbc5764fd5cfffadbc7945f1a6ae310a9a1d50 d55f6e43fa28f97008367107abdef40ea271780e5d19a561db5f3af215e60ae3 e3875a934a00bf7597f8a4d53a768e9174e1ca7d15c460c18d76bb761f99dc77 +516000 6af0f998e7b95f5928801133f52c03133ca1d706f044f545812d0e64afa7eb56 79daefaf210fa29d3c633094944a6ea814f73589d3d477a38fb6d68f0380795c 8652c12820f235e18f982ece7b8dea102025e48240aa6ad15f33e3c83928ada6 +516500 c7174fb637f35bc6822a651eddde06e842534badc1d7a4c2d61090e79510b970 ed427f81415ab5bfc57f4cfaf8461c18a23a2ca0a7ec9b48002d694c70137716 c89de38183c186ea1a1c82c9fb12b55a96d1fd66d71b0220704278a240c1bf14 +517000 f4055907d0bc72d6e28eaa1b566ab77904495bcf286d0dd6d7bc297b8fef7a63 74104317e7c69033b643afb089ea06cafe18e13f125bb7a2f381ac88d362eb63 66a856aa315f78489bd05b7785d0df90369e3425f1fc15faf09db747b2b4eb42 +517500 dfc6759e8ed2c1078dbf08a64b71ddc9ab2a04fff41fbe9a5c82a250cb3ef4a9 5a544c7180a99ca77684597ca3cfb1257ee0e3fccd468e3771c55e4fd9a1152f 1c5d3934a121c421245ba556b78779072c690c8acb7ca76c5487a04b4f5b8aed +518000 3f867c72bf194f1c257f1476aa4cfd18cbe3a5df52e374b1f705e496e06840c5 36fc1c6723e3e48773e1bd8ae04210fdf0a9d22cce523387250deb28c3793a8c 7426d712b994a6cefb5f5103cb758d3df26f63462a6b40eee0f909068cbea6de +518500 941b4dd50e5124b756a381e83ef95106d15522461c348d5e032c1b61d838e50f ab5d00a5d8df0c54e297611a063ba4357b4686259473accba2b139ee69dc4d8e 4be2dfc858d43707f1aac833d26a1b451367b8f3d81915dc68db87366f90df82 +519000 2136325d5351d77945e009193f054b04492a8d8f210eef016a51630313a17c3a ceaa807d0b581d95060026f8ff02c392db4fd0ab5007a86053f9e0b93049aae3 6074d6a72d358b551341996d6647c7ce0f89acd0c3fd38d9b850e6f0c19288e9 +519500 8740a71b16e0335054adba609b5df4dc066d157dcb0511442d8d413c2333d883 216da33354860bd3b2b44d9f217b89d2a203836e5f0c04de39381776c78d43f1 c8d27f5a757e018ed9f5e4ebdbb9b97c92f45e15ef33cc8335c9160bcdd7264f +520000 21557c530c9135898351f2625779248d5c5ad1fa473d8989e8795cd650f3b036 02327cfdef960f127b2a99811b52f651fd5f84d3064dc10b2b8c4c528a362c2b e44f6a53c416a47a1f4f3ff8fccfe6816a9042e7ba588c98f223c2da74b0c906 +520500 fdd0b3a9a08562ab9256162fdf1e8aebba6589b585f34ce26ff0ac20f3b35715 cb7b802cfb533b7191e892348f4076176e842e2a598e373e6653c92b62b4d5f9 8312f8654d973eb58dc5e3a9565bbadb47312966a776f619c9f8fb4dc238dfbd +521000 4d45b8b34e350a098a5ec1575639465783982db7710d4ad07f7a299a19b860b1 587836bb3390bf2dc472a0b9e20a5e643cb270d85ed4286180f358cc8d0dfe88 b3099b886e7d7ee570dd7ef18190f281d69cf8af4b9222ab41dfa51fadb786ec +521500 8357476f03fda1bb1f346946484bfa6cc9d80a89b508255c3c4b583c71ead128 2c2d08c950c6437e2f9ff89d0c3b0d0467a7761a0f19d421e0c0846c2792bb62 ea7c47406b51fa4fff9d4dde4cf1a312cb7f9bdd136b3dd1a0ee772ee56a7743 +522000 a12936a6677badc6d2c8e83d2058abcbd2deb580e5147f1e742e379f0ffbee7d 322277c4d49c9c37e94b84c184e09dccd63cbf0154e61e36b497369c4c7f3fc4 2e88c7b5e944e7fbd2d0a39f57e39fd1f467a7e85013fe3e3f0970dcdcc648a1 +522500 f0770540ebe64a0de99c169cd1a7d9c8459eae0e67873510f1a8dcf4841131a3 25ae4d82a8a9089095bc4583c9842984d53bb4b0e6a162d369a70802b7f9476f 2086480119c6dd31340a4ad53b39d23e2f357551ecf188fe077a4cdac405caf0 +523000 72d57e281db8b4a79f566fb587e448883bc1d1325c9ffc2931f1100b63e5836c 00fcd8bff8a5e19824f0e98fca489d02ca2d27fa2b4fd9a73e410d935a1b93d1 cde20a46475c12e517a4326e85632a956c9f5a2a3af22c84ac9ffbb0b088366b +523500 97b2d54ba68ed4a14ca1fb4e4b697b2bf8f7d0332272af4531a72c94c35dc932 04d4f8ef5ff03931eb5c0eac18894a9a7ac8ac7f6bc0b34b43420ae9d7802a1b 21b276e5d11eb1a8331df44a4cd05c46d1868c573f3f82c8f047f67d3858a7bc +524000 f5c96b25808ab9cbbcedecfe467e163e3bd9d771a8efbd3cc414c7adf1b7d380 c11e17455d687b0dbee864879ffb41fa6dfefffd54d339fff58dfa99790a78f9 b2bafd7f61e6485200c761f5ed481e768563fef25f82469c0c67ff1d1cb988d5 +524500 cc5a17d877467df92ed0b3462d0031003c642f64896f4019da641d1572d693e9 7b878f323c00d5b6d0f73d89cff64319ff2299d310a67a2d046084a77b411101 8f9c19111567dae6467b3d76132c1f786e278a040099af2ff5354f81f7c1cb6e +525000 1b009804fbb8489d23d5512262d7536375873ef933c154a7058ec1c934f61892 d583cc3f0f7f01c67294d2e98d28e83c81824cee30d1252816a7828c0461f350 f1cced480702a35ee83501eac3168b6331c2a82ecf69f2387597d21eafb011d5 +525500 63de360342a1abd256b2f4a3f1a74da8e5bfff409282c8d06cadfea596220f9e 124aca94373c78ba91a8f1c01d89d5bbeded60581199d3b12ac66b76c37c112f 35bb495f4aba29424e088ef8b4ebb7b4b10e69902ca07c65f83057078bfa8561 +526000 25464aef8a123b8bc5dc4b9f6b83149c84511a88da41f7b5f6ddf4cbd340dd30 ca911108aa51b78a806e58f876767baaf341c9844f31da71959ed4ea2f87d62e 53ad3900a8a89b100539e325e86c7a7a515d77ed8d7bd0bea832a1196d8a2c0a +526500 54cfed1a647b8513e845b57381456d983320e1f6dfc26bdcd4e97da73f31bd60 a5639a2ead728587161e02add9b047738a8534d0725a84c5532bdd054e715ee7 c5756392113ad44704a3691cff97601b8d7d4300ac2f0600cc17fd83fe74d0cf +527000 d601736c31be7964de7a76ee1fa2c4771d804dca1c1a268b608f3c77971893b2 1831200e768d735e9bf8b5ddddb9119ec19c43e22b966bd969346814cf454d55 29c80fda0b25d26f7a5c2aca063a6702151d2f6af47a8af74ca4b38dd4b935fd +527500 dbfd9c8fe9edc773e210401cb7341166fda6e1153a1fb47f866b919dbef91d31 5f15be969fa28b64f5250f0787876b05adfcd2c64ee1c2c72eb9724403ed6dee 2259567111129402e6f857b636fc0b58b1f732b522738ca1fc458ba6208b6e7c +528000 92d74a8d4df0a8f7510fab8b5d02692442d1fb8bb9046cff981cecbef3353585 b67baa2dd73a4061188c5cbaf13ed1c063e29193fedcac0b5440e042d39a45e2 959f3a09311e382c55480bc857cf511a99fe3e6285b66bbffff01e97cd5fe527 +528500 b4a034b57dac02980cec5830c0718b0ce4a89bd3ef3f5f36e8b4181c1f42ace7 de92eb4a468c264b4a9ad63eb75ca3702af7c023481c829041f328797d2e3636 2acecdcd0c7fbd48c8bba8229d6f1c0a03568ae5fbb77f66716a1c3b574c9ce1 +529000 a05c9409ae06d5bc48284e5c624f8d6f6b001cc6f887d459043f442367e5e1e3 dcb56fadb166de779d9d0e4e5e4d30dd558b0ef3fba4f9afc8023ae5715d30df b8c359b671bdd5ba67e8db94b747bf8bdc065f4dfd40ceebaccc0de8d7513f31 +529500 f62867ba72013c202a9a61da49b6e4eabc05e6d247f2ffd98235b8e4d862e795 915588450e5ec1300605afdbd6dc47954df1fcb45a6a10953db21bb54bba5797 0a21fe5e0943df74d2453e053ef4f5005db902996d852681c5a2f9bbb5dc85d9 +530000 35c57a8e961f11ffe1cf6712861b43b4e7d3cc3107c28d6d8722de90506a5b54 1c060c7a921b2d8567acb70356957e7aa044d8e37abe1923ec1ccd3f0f7191b2 b4229e26f05148844cf0d38199e94f5dab81704af3efd1de77c757b5b0a74d66 +530500 0aa4f3b5419e0844a7316ac4b76e00f3230781c8d320cdd62dc1dbe21875dbbd a3bf6f2508bcf7bf8a6fc19b2a75859a8c2d3a68858d6dedca2de5a5c687b94d dca35a1c94d6ac0857f3cad6f04b3ded87442aea24717a1b41d075c559030a8d +531000 b65e6fc5a87f8d30ac2203e13e9e9fa450ada17650d6c639fde4f71d2832062f 6c4e276f9cc20e4111c9c45b760cb529b12e6f6f9d984c6338e47ecf0d1fd5d5 481ba258b254237c2af95e840b28ec971aa79f07255c696aca3d9212de6fc74a +531500 4fc020cbe21507bbfef6eb1cb30c11359f8ba8ed0fabfd67181b596859a11fee 736ebd1d9d616f4132934784dc13c0ddd6382616a501f11f84071f39bb794a0c 396f8f1b3f89cf10e886890c8b5b3eadb5343e7df8df1ee9a5030fea95ef1dc1 +532000 936bf25a71f4f427a32035e860b049c5e0ecf36b0dc007608b31fb9a496b058b 9c412485687232293357f94ea0cf8a76c84e8757046eae59406f5ee225651a55 c4c17ffcb5bab52d1d4c4de9b23499080682f8a0846dfbd3939a6ee9c1c27e8f +532500 51b5d1a338bf32a3273b45d2dcabcc8fde6bfb68f80624624b8a0ccecfacf751 81559753a06dfa90b7ed984962a88154310cefa89233d47edce8438601051981 c6cf7a820a418397881aff15b8da6023e70c44347cd440ce3c470ff56dc10ec5 +533000 d80bd2b8d148cc346bcc49974171c998a30bad85878c6e508d16c728098d5418 cd8c0e674768e8afa69fc6366c3e2aa66ee31b8a10cceba75d3148857442c30d e496a4c724bf9f997429bf080e3fd5f7f5580b524d1e6c30639f8cd1cf7096bb +533500 06cddea66b25e0387bb678836918cca4be53f245e84c01fdd8194ff147377a1a cc77c89ce8bc38a702e21b00df5e4e65f2217fd7e3d330aeaea89e67b2906d7a 21f4e346e1ca43a731c5a0b8436f2330a3208906ec3466f50549e8aea4a14c96 +534000 0427f67b170428d1d33242707a2a8273c6447a2762ed42e49580526cee35bb3c 66b923b19b1dae626b62a5c76dc9710d396b9436cb8cc549b87a4878f457e561 f15ffb3d566f30e326febac3bc791706ad96b2a04a35a2792eca301bcb0e5c83 +534500 de3c914cd38e7fee1888806ccd3d4cd5d39b81cdd22f869cc5c2d5335fa29533 77b2265b37eef1e316d0d480f28bbaeb8faaefee270991fba6bb5680a65f5298 43b3d5d782029b1db91507a16cd1b8fa86d02d86761ba0d9e3a310e80d88a0e5 +535000 b4c2ed2b12c9b6ee617058231e9099ceacfbb10e344c8060df631fc42cc276f8 1cef714d86e11d17fccfa377f5550acbdf781a19f272cc8917c3c9886b99414e 779c713030d24a5f0b3477edce23e0ad33d798be1c5f70bd65cc5c982ad1f480 +535500 9515324744b14c233fe0463842b81e99c1c7bb28d99234d0c2126ecea9a3250c c96091825c57b11639c7eb8ac6f6c76d48c4507af32c1fc95a93fad60e5b1a78 e7d3dbd4004dfd8cf66cef4a21ff7acbb71c07cf50f87ba69de6a2834231cf2d +536000 ba4a67d76d58f76b3cb47b9f89792153db68285c94062df446d924e59ccf7b87 6208b177efeaa145f365051fd3d5f9e82dba8c42f1d0d2b67635c4a908b7dd17 ede7352ee474c6077c2812e5a598051740e885e16288a5426ef9d4a25f80fb87 +536500 865528966307aa0504e45931d75610ae56b4c4490c763198c1570a66f75b1f1a 09c2e4d9405d693c07371d2eae527aa1c2311db979f6d2d0abfdc5467b81cb65 d2d0a63b54ff19d1117c4fdb9d2f11368c1fc79f251ac539c05adc085b65e04c +537000 c3355c3c49454bb38156c96fb23c13fe9e5fb73129bfae6c61ba4e6d1e46ef00 29ce20cbec7687f75730f0e4be6c672d1fcf96baa9168eefe3030116e7f06b63 818cdf33ac00f5a623486e47a6d74b145e5c61595b57055c3cf73041a111eb84 +537500 895be1cd157309627c65fc37e677a72fd82f27d0418e6b43998aba564d205369 d5e4a2bc8d014079e205050f18f390c776f5b45940c5835ed995817dbcfb9da3 4156fa1dff52b59ecc3a803a3949a5d2a100791e8390e10c10199d93e278f15f +538000 99248aee8ec1681099e7018b3f27ff7d48023639c7a16f846ceba99bfb8b6794 51589b8c95d4c555e3e85904368362e86c1ca65ee73cf4b3a56348352d48187c 405b2b52ade6f4c8b82ef01114817f7d7ed72fc57cfb977ffe2316c62364cab9 +538500 8ed90c82d16b675f2e1616b4e6877fea7d223f4c6049c8abe24071ed0cf55cff 0952515dbe216e7f8705998796c926f16186b5d911466f31d36255852c2a1740 6b7c8f5da9b0681690e1f9e2be83d1b7ce20a9cd4a2c060ec17c7dde95464d26 +539000 5eee066175978a2e04f8070ec0a1c5e215afe79e6342f882f272e3ab3e5088d3 a8fcd0b0db8bf7fa522a86757bc674077b64491860fe1e1c346d48b5056c3625 50e3d3f8ccd7d7bdba7aea9f18af6b137ad7fd5e4291563a292a43a650601f1f +539500 1fc7f87c388bd6e524b114ae6bd9654031d2cede075e50c5070d5f7492238b49 86203c750603c2b64073e488e635049afd299e58642bc90cfc7bd562fa1372db 3487bb31bc0ae1e79c810aa261000875d1364fb97719df7e5ee43b72c28520f1 +540000 c7c3d0e72955da1daf3ed29a7f50e39bbc72a97a7a3b9657151e2180b297bfdf d8789c0edcb9150d9cf88b973a2fba35c0e8a13a79e9f5e6fe67eb527f100dda 65b14ecc122d122661553dd1d71b49450f843080dba874f5baa6fdfd20467c4e +540500 078244b881a7ea8079cee149a21afb1f3e12513eac743435b26fca944d1f8c0a b0d2681f5339e6747da87fbdc8eea0947f09458e9e121fe715050d97d5380b1c 117d776ab41d5019ec163153f0abef5c27f093f6b88a8a278c690f856f334cdc +541000 c1fc5936f601dbe88f86537a73e3082d817270cfc534f985e6aadf1e69017c62 c5025d93f22d3c16cf3f1be03756c8a04da4c330a8779bb156b6d6812b65db25 03884521ced22f201c1a1e326eda5f100a82101bfc943109cc364b7ea7ea0ea9 +541500 f06fc398ee363680986ea85bba8897ca25e7d7398defc7ae5dea8950e5e10b9a 6eb30b839ec9f6b85ba6a68be9a25f4ad0d72cddfcbcf5bd4346e61905e1ce37 275cfe4e765b4c188cdf7170de44f22c15b868f25d0d6b12767b748a1b6513d1 +542000 f1133f6d4e5f03eee2ab13868e8a296ecb14fa9a0fb0074e5fc3cc46a1f7f2f9 b1827592124a51a20ae293f4e824c8030eee78ee82ea039c27e427fe4d2da5c6 c656ea7ef821db02521815d458246f5f692cab0056c7b754fcf9bf610916f4b5 +542500 7892e32548d849918dd9946be8adab0f8d0842afa1e9f62c066d27924a96153b 421009927f9b4183293a0e7a57882322f87b30137239b6db48168b25d1fc5ede 93910eb3544aca246ca379af94f4d0b102ce68aa282f899386d656059ac38370 +543000 656da82150e03b0f6920c13ae9f012c768ad1db9da51f3cb36cb08f597c944ef 3fdc935dccb715960e745f505147ea8508aa5ba7c7f2a657a14ee46eec52732e 0ccabbaaec21367052451bbce72072144a79388d4ea4af9af60e0bdf370632fc +543500 9c3e877261982dd30c2c1c7bf6604e64b22fcb0ac6f1f31d133ad853e8b2475c 058abb454a8f38b333a57e220049716ddcf596ca81ed33fa28772cbd87968bf2 8edb00afd9e9f985db0b5e3a2fa076945cec714937afea659a981a36990c6662 +544000 1ecd239bf3296b13b04cd7aa240769324beb8a9de6e35f10c193ce60adfcd2b0 7321ab6022acecdd7ec7526d7fd560c768da79151c01e409de85f70e8d9d9bf3 1f35ff2be617b3d5298aaadb9cf600876c300bcda68dcef1c271c2a2e1fcef1a +544500 ab6981fdb795d866908290b102477a670822935da8f8af9c6a32ee740d69bbe7 c1eb309bc65e67917e1c46e7d0f232900974267e048abd48a1b04e1d4a3172f8 960d00f60661be6b528eebefb975b8901243626368ea7f2507748e9c091a389d +545000 00257b2829d7c11f95de86dee675a7edb80dff9715bd2ab64d7454182f213a0d bf13fcbf0b1247b11accd940ac8772789e081f0bf1cb70b1425d6288c69b1e76 8079693ec5c445cf8ae5b353b0cda42cbdc95a417fd85f7217f98d2b42570e76 +545500 ea64a39237ad3d242cb2db3a1faebecd3b20c682383b014227a3f230a3345dd2 09c175ccbaa02745d5f72bb6f68a9b32cac259ecc88aa1f49bb30d336d79bf59 f2cb03e606e67f0f17b73375d215ac36ff167765383812b927792c3789d92c13 +546000 efaebeda777c28c7e35347e84da7681aaa14c502d53698838eea8aba6e55c1a4 79194dc97f5c84f2a55ca245e93b69b5caa44c6bd5e581044e2e26580bcf561e d937a59618f4f848d0b4e37e1bb1239e1a036858240f70dd164615ed43af6f4b +546500 bffd9b66e5207f5cb60bcdce5dda495ab78fa6206aed6981bfeb3ab4961ed56c 2e133bc3bb1e140288f0abd4ac9fa18fc4e30ba6fa672f75cdea8fedbcf093cf 157052919d1a72c7c79ae5494d54655b76a4af0aa63cd2205a819cdf1302958c +547000 b7c08bd8cd06070b6b52aafb511d26a3e4dde18e15ef004576de6c06024f2a30 6aa7c21876ee2145c6b97d41d858abf162abee2f179e94e354799664f38be6b9 6d4eaa24d3d7467bf302941fe3210cb2702ddb5a57f6e1a79aab790c72bd3d44 +547500 77b94303d50c7c640f68812f0dd13cde9cdc2b43c5f6e3fa4c99621be61279a9 31c6dfbadc919ec783b0bdada382c4c3e1204008b245b6455679b08aa7f2a6bc 17987eb01c4bd98d605cb76a32be640687e8ec900b36680bf6dacae55bd32f3b +548000 bf973366b8395a897b56bb1f9160f8144c40ba17934fb14b46d2bdbb32715fe5 a732ddef1fa97dee750cea03675a6eb9557af9ed6314a162f5ebd8ded9407698 d78fa85231b0fb69790e643c079cb7c34d1c114fbfa8c1d7712b01ff71805749 +548500 c2f20ed6a252cc714238efd5531084bd5555ab8ec65169a86c9a0ba97b2a7eb5 d029d1bf6706c1b298d9f7ffdd53a26b17704433c42683bc02718ef33d2d70b7 a2464ef54773a2cd6dfdbf05187ea2b0e1723b3dc22e31e1480d414a4bd13943 +549000 7e07ebf8ad3697390d81f7381637048377f461e46030c8eb1feb17eea4c9d3dd 1f2183d7618eabf7356a08a0486675b0163aafe13e6b27bb6179fdaa59685fce ecb2f323e8f843183dac9fda0ddb68aed54277bbc0e5de60b2ebd0ab37a0cc95 +549500 7ce04ee7a21eaffbe862646c3a301460da80cecad0e9a66a157bc1d0c335a18c 989d7ef547727ed49f342ae3681e86247ee5b6ad009a863ba0dc517e7977790d 7745d4f12b75c63a7213bfed8d46bdb2d0ea5f75d9765aa47ce7a689a456be59 +550000 0b717011e4c14ba25388b6be779ec7a7fa2939c68a49ad5fc8cccb32a3fc96e6 d95f6b2500300308ce3f44e53c38e6f0eda793b3e1d96f698cdfd8d70888e277 1446f3a94e8fcecd1819e47eda64932ab5f7cd161f4801b96d751bd11bd8edf9 +550500 b1388fa70e3a79143b985bbe2587a8a36a3ce7f90dbdf93c312bf375b04204d4 2f81d9add40226b4b3d3f2466a2330e412de80bc31cf3242e0f8e8c1f45f1a88 2e0c55c354dbfa29d8ecc9611013fd969f5a843b8413aa79d4b5676d9a79b7a1 +551000 b0f768d89c0f0e5929e41afa3e9711a2f6dd04c71519c718ec5a4851f13ae4e4 2b1fb05c01f17b3eb7268d552a99acd306e4dc0107985d6020dfaf4443dadd73 4ef4d4f9a0fe87fa3b1bc65c582fea5eb43b00e4253b97bd536eb342a3dd3457 +551500 891da4a1108be080247fbc0089c4cbc2922d25cf2285538261195b41bfb48747 e5f1700d6fa46e80db5586d1f3261b758d374d43adcfbfad70ed5112bb1bf603 a7d24449924bfee8b65e9f093a2bb9f91f104687d03bf464ac13500b995ede8d +552000 8a4da9058e5aa3a483af0775ddb984048bec5a52dfefe711d620a0d179856ee3 333c9af8ca1f58b6185db26d60b4fbb955176320995ce208f18aaacd277b4f1e bdb844ca20bec8acc9248d5af27b3dcf24dcc409eb510831d512be7ac8edecc1 +552500 f290fd729e75722394720a4b82e34da44d640af62c995fe6867fdd9167ba8335 e85093bef089d344639461c61bd1ec7819d5105b4f984d423041d035335e24fc 690cc872111b3dec9cc8a048824d722043ac13ef208e12d83b596977cb444569 +553000 2558178ee645f229d1b39f11e8bc8e423e6665ce3e7491ca195fb72d8a13034f 0a823b23f9e2761e8f32e42f7bd569ebb56869af3a1093d7a170f792605be7dc 16413e820e03f1fde3817eb61868061671bd12df892e47edd173c9c9184e7455 +553500 001c1d53874f0032ac25fabae2f92deca9235bd409eaac1aebec39bd798830d2 d36b5ccec99827a8a5d775d707a82836c0a10d13bf9199e25a3c31bd17f66370 29bde729227b92003a7c09dc8f78dbc155f72129129c2adc973277ce578323ae +554000 e2710db357675cd18df933733e23992517017ab0507fa218fb45bc9f5d812224 786326555bcb406ffe22d8dd499684db1b8b70df508572f1ada7dcd6eeae85d1 418767697d50c0e474795dd78c354da21c5f71eaead7bfd37d8f74f282b581a9 +554500 cd244e1a5feb9d4f3a6c51f92f1c9396b8871ac5a20cf587092abb68b4fe2eec e7a78e8e16dc73cdf9064f039df1a67996bb3eaa744f2fc0598bd07519078b24 9782647f3aa642046e2439c624bf99de6355dbdf5bab50f74ca65512369b6b05 +555000 1a6ebd86249e3a3837d8a1eff644e240333704c7f9c48515e849578016d8fc8f b5da194a23915c042e044b0d3e5e1856f7640ac8344a013d7a1c459d967d6eb0 8a70c7be79d5edecf987e4cdcabae2f6dde5118fd8b3fb967ff40fc054197ba0 +555500 978b357011addba581355b92d3faf71397a7c55689ac4fb0d4a6eebd8409f714 519677a9eca60cabdfcd5e888ecb570d09275bb7e2585e9226a9b664ad0d7fe4 675bfea85793acff321a1585195718624421451f27c0642d964ab066a1db35e2 +556000 edc28b6ce373cf5a5d13e86ffea09ac385d8d2bd251ea07617b10abade558e12 7b3f6c61707185443f2565ad2f228bcb006302a1bec5a203f143e730c681a9c2 4e04bdcc89e6827779bfee9bf287c347c564e6bd2eacd870b59e22fb6fa0dfd7 +556500 95ae0bac1e11d4df7fcb554f665966b3bb2195010c0cddf48d07803743149578 1c9c7ca6f9c8b40134151daca7a7cd1b7cc24deac24aaf2f3a450b34b74730ba a8e00ff92f14de5e42fdf72a2f432c30cbbc9c0b4ae93b6c44ab753e272b3c99 +557000 a1cbf8cd746fe3b27616f6515149cfb57408d82b8147c19510ad13806b7845b6 2287f21d56991d98d17edc545f93a85d01b7919fde25d726cc9cff6f62d97461 dc13f0a7ee84fdc2a585797efee7a60066331d73320701861c538e9233ca36f4 +557500 1cd1617ae1474529b7b4f322db9442763fcd418410a3c3e918e17f13966491d4 e71635aa05a9aee0ca857b41574d348954419959f8782b6aa3b7a3e0d3b6fb43 1a0b713c663485f64881db18ddbdeca1fb0ad1804e79ccf3508b95cd57a2e2bf +558000 ecca0843b0d748735413e34ca513454ce2497271cf04a9d12455f0bf07c09f22 c3a7537c5ee0d6615a53e3e30cdcc6433a554a120756be6247f3c3b703f023c9 4d1e23b9f0015f6f61e2dac4b1cb9eb95b57e341b648a17148fa52009f76879d +558500 0bc0b2dc367328ad409219afddf852412ecedb43e048ee73449cdfa5e152159a 64f4cd8ebaf6f492c200b11b080c521f4efe87e777818f9012e969eb2dc0fb57 e431dfc02248b71de80ac7384a53e01a05ec14e4b4fb45bde40887fcf2704978 +559000 ac95a1595559d38fc68c9dc48d9af40b3e31d71c292a83998398af38f09b3fb8 a65b3a0e37cadbb31f367a83edbc4c70d0537633af498c9ece211c681fb9f671 2b96cefcfe13308712200f32876b7a6256bffa98286c8764450ea1a83a442067 +559500 06afcb286229def7721d7a5bfb22cb59f1b25c6aea819bd26456d5fe0baedf74 b871a3c694108b366de593c52d6a1b3c38af1849b0092e5474275258239e6088 24417d305aa20fcf134683ad23b967f19e186a64252f3bae6eca3e4e4a3ef57c +560000 538bfca7649306c7ad77eefd31a7cce9b81ee7ee9d20d97322e9f785cb555afc e08954b12673a8e87fc4db6f848c2129d39286fe856ab80f3a11480a82772963 7b06510d88d1fa90997ef87420a1d1a1bdc5928428203a648429b628d781d717 +560500 05fe497d72e403e9753264fa5d4a7348843e07afbd260e21fdcb9898d9de63ca b538d81ebe3d0367d4820f155315debd0b078100fe17f3ec6a0c1b1d989fdf8d 0b1da1f2ffd782650bce992b478854978c6664b6c481bf27598afe744302ca7b +561000 b80da09d4fc326223399fac5659ad647dcf37232eb63546212c7b951d429effa 014c43fc1995d966785af2772de5f8d4738b44785a2bd81145d32236931bc978 d14ee2fd9bf678f965b7ef6d3f22b032a66ca72f433ce8334d2845190aced1ca +561500 998927d54433d0ea4fe19a4ab0eb8e08ae656e8cac608e3a824bb084967a37e4 a7709319ad385d1345ee6171bb57bef2d0a648278e6cf763068496eca01d5315 8e3a7ebd7addc79667a9a8373b6c599ea24a4ed13ce6a936535a81eb275691dc +562000 a005e7c48077a108e353402f478f0f3cdbadeb95f360f6d4d056ec8aab302f7a ad678ad8a4b421f5211b5953c3080ffde18f2a395f5f77a467a6a3991e155b97 15d1e5baf244b9c32913691d2c2c300104b18857f5cc173b53a4d9306c0b8c55 +562500 cf4a618bbd1d4eec4f6ca3993fb2b3ce901592c365c2b7526c9de2d0c98cb74f 05921bea10fcdc426b73459e8ea0ab421c1635c93b60ee8d950cfa0efa91a126 e99c2a2cab3e0d393929fda25bb77a7d21b9660e78b02f36bbe6d9a35ab67f9a +563000 ffcd676fa825e67eb4832cc72b5767f50fa306f1dd251055ee3f623d9fbf4d6b f3fcba9c0dafd172664da1d0e692cb1f4e898f23eccce5a265104164a5ece2d4 26ec1364d9b1312f0adb2908c1447cc89c4afc51db4b238217b763878b353532 +563500 5f96af414cb11afbbcf48a7fd1738fc1c8ae91dfe58ccfaaa7149264ce34c5d4 54756714dd75d4cbcf87b452238296c5acbece0f991ff2cf3b239d6af4b7f4ee 5d10e1111c38741986dd46de80f42c6c2410281c518c46ec13810ee566f6082d +564000 0345b35925619ae8f774196dbc6ae52b2d065ee4ca6f9ab87aac366307e1512c 7ccabfabcd36f82cc3195d587e6b530f2e303525e253d84376f02b907e1bf611 1fc483c4037a1e0bc2d4b5f638e53c9ab8cd1c1e0743ad3613797c307a0cdbd7 +564500 478fd153799b8afd93360f4288321ae7e82aa7bb5474f13913274834bd4b1ba9 b73b7af475c03ffe2bd0e9b09f32a966126d650007f991cde96bc8ae208d2844 2672f60ea8969e06815e56c9241a79ef6249cbf7be3bea3752394f008799b8c1 +565000 4bf82342209df889c321571400c9170621b17c9b88b60b609a7a9a31a4e6879d d33e0ac1f8f8614cfec0768dca67ba99561976ef142a62171bd596ca26265462 d638ba536ad22a53e0a2768f80102d958b1ad4d24205a4d617d9cb7d082e5537 +565500 18ef43d2230a09c588644154757d4c3136a0dcebbd1e7169349f280be113ec99 d3cff22fd147792fef86c9d94f7b8553c555a925e7038e738bde608c83ceda53 0b5c5018ae69065cd19e245914afce8cea9cdb05f2c26b1cbe6c5ba0764dca45 +566000 178cd3b2773545e457ec933671f4b7e0cfa269454371789d79c4c73d879fa497 776636ace5ca4a51abb4f04c22d5a2a0c51d42368f43b8b776299b087d1bafff 9bdc510f5ca8f1205df553f32a927022ee88c90f7d2c69b4379b06c4b62f40a4 +566500 6e70ed03c1ade6968a6f18aed75a42130abe4674a9cb3d6715d5320474a310f0 9e51b370f5e5b6dd65ffe6fc854265dc071b7dddad6a68e25a6082d60a4573e8 c7f964bba1c9b43b1ae9018d55f6b9da0d900c503d266916ba781616e67069d1 +567000 6a0b1d677c5cc0ce3f890ae8495c70403ffae874414fec9e3ec8b3aa73bfbf12 44a2fd59a3f18b4d59d7bcabc842bc21681b3c82613c95038aec10315bfdc050 382a6656d846da8d438bc7223b7461859732ab1b06a80b454d78fade676c7c64 +567500 aaa507e4d8344e885c748389b8812c28ab49533b13fa635bb345a4495be34850 f0b2d2e0f7477c8703fb6c7ddaf4d22c17da14d6bb1be606d96b4fe23932ff61 e52ba28cd8136cad574b671e145507841135a991c1888fec787df0d544932e1a +568000 058e126ea94bbb99030e2be4364db58bbe0703c0fb4c3155ee7c386e19efe976 e68dcd0c11aa8d9b09161d9fdb25196b0b02017743235c5e77c83314139abc6a 49d5e2d66a782195a1e12691f6ce53d9a07e338eebfce99008c280917ddda751 +568500 369e444ff13a9ce379c2c98e70e2e50e18c823b4b43d51e57224f9d7bf7c2a82 e5755456750a9a92ffefb86ebd18fcb6d4f790bd51e47f1dd92d5d0db8c60b7c 400e3e42c56872793b2fa5cc0edda233f746bd4c13f7a5f89a02d07985170c8a +569000 50685dcbbd12f30781fbb546d1a4cbc349244a2d6e14ccb1530059e4073fc0d4 5841f99c2648c1075709873b22b8bc25695c01fb146b0e82291b6a0f5cf16fbf 273062f388221c9d500cb7532dedfce411ea6129fae1ee2ed43d54de4aa6751b +569500 452253574aa43c9f3ecd39f7122789bcb9c83e343843540860b950ff27d673cc 2ab70f1d2aa896e8a8495df628e675c983e45047d719a9e8fa0804f34a8f82e9 73e5be387bfda500adb062cb6229402555b29d5b9a83a928aade50443e17c68f +570000 c1b6627d3100900dcf795d2b684e83d11a797d2302a3bc058dab61ba109e5d08 997761e1d03f77cee9256dcf268f308a14899d00386cf1cdcd9df39a57ade810 781e60d9004ff259f5c679728c36e1824abef28335ff874b89d5de2a02f40eb8 +570500 7cd59e7583d4c4878b1dc3171dcbab4832d2c4d61512d7f313ab88782a9d9336 0a439cac39577c5f0188a201ff1ed831ed2fbd5d819c6682d7aecb2e4b77b7d8 51dbef7173c663e33c223a0e5cf70cb857efc63c4cc9175f9ba9b817552c94e8 +571000 6aa099647512a9654c54e730e3f1d4a1fda25ac58387503932ded2817e5b446f a629a59a6420e7edf13f0a7dc05a918f86f9fb337459a1f85b65cdc71b301d92 1413e4b5c9ac9c379a8c558e0e20eb284818837e07799e4ca0d01fe5d53429a6 +571500 a3d2f0b075cf3e735e586c69c3eeaf7a07cf0f391e1a6ecada1327abe8ab8c8e c97c75ac8bd884337edb7011ce4a68f31d1a06f477d821b9e473614f871e059c bc488c752c8548cb78aa967bf11e8d2f8c23c6f011a4d609746ff18f27f0f3d5 +572000 154d5a1e996a34d40d3aaaf2244d5df055de5902201bbefdff166b63d440090e 38fafdb36a68381be6d3a3f358ee61f1998c8647949eb6659f8794c5d84646f9 34bb1f2f2e84acad99d095f9d37904ed8aa9a72cad03f6b6a20051184a53639c +572500 05d47c51813cee5f42bf7803a627ade017772b7f4e734fdce5a824edbf480359 ce6eeaba07d4a7d43ae137f3f66d7bd2c3ff0b55b973c0e87283011f58f94fc8 d5e8c7f3eaa1dd7e2e9e86c3f904fa18066afc90f19f5b09b5119ceac51383e3 +573000 2cc24da51032f6db15842996a46a0f01e17e7c1fa178d34f4d520e57a1dec5f5 814f5511a95d2112e9d6f5ff9147e4af6d2d14c674008901888a59d77adc0127 97cf19530e18aed12569602045be833d526fe06530a6358c515603de77834b91 +573500 5a412746451823e5fe7cf63b331c59b6b1808d176c1f3562631755a1aec62267 a8a55f440729934a987fa7bcc21e4bed9ae4cb4fdda5bba05f328d33c1c93dca 5c9ee5926501ab49698c54a8eb543b5f212b2a65dbd6b3d71bcbd04e9798c411 +574000 4e71a21262bee73564eed3938de4c2a673ae763450fcb183bab52fc3739e9307 f5fd0fbd347c9146a3356914145926887833b394f0664b2e5d098660848e8b5c cc86ade9b13e059ed4015a5481ef18d63069f67a52d67749e4abe1ea165d62c0 +574500 bee3161612969794e4cc7811c35fb9fd844623da6a5b5f2dc38f32d50728ab90 ec00c96d649a6290cd6b929e1a71251e4519498493fa0ee2020ed494012693b3 baac4866328b40b281dba068cb2d3682cde33b52ef2101df94ce1883d61bdd9a +575000 0560ddebf2a1fefe36dfcbf14c0b9e2101445b34e79b4d2d2f7c329c1dc5c97a 58a5850806bdc8a70223873c23aa3a5975634c989d8ef4f4f78fc0b71c025a59 2cf5c97d7e1dac4ea45e91316928d92e4b74440d2c059bdade7bb7c1cf1d45bf +575500 077c9db46dee33b8fed0edbe55dd09ced1c04eb22096d9a7f0a8238b764a9005 a527ce25eff18c724535306c76670e1a44b010183ad970d41e4168c7e47e8ef7 db44f4bd7201dd8e1b9deb53e77c7a93787e9a992ad6b9446a3eb12f28bebeb1 +576000 f9762a0e8b01efc84c09bf94e0eec3168852cac22bf5e0e657957ffbeb857c08 41b866640d3804e09ffd386d7f6b0cfcc5e95c65991fa0b753c875676eec7c37 363b120084d9530ed7d17cce535866b196dc4d39aba6ba1cc875778afedad3ee +576500 fff9ba66ac3dd62ff0931e644ac522896b5e86c2a23e04bb4f2501145dd96b75 def321280e76f1a8aefd6607ded8cb73769de57f19c641b7c6356e60105d89a6 c8f349560443ad0a472731d00b20f77881ff0000d4e429d8272b13628d9879fa +577000 69c48c7908b7b71bde3ba3aaacc99951cccbbf4ca98fe699367cda9c2101efe1 da1cfb6020117eb45c262bdafdc11ef962f6156c0c95e68cee1bf1a2b7b9a1e5 b6f18f6a70537b73dc145452ef80a31555c131c5edca2b7815a5b9f7985a07bf +577500 9c563371fc767b2343d7f1cf6f23e4cc7b42aabb564e94a5cfa940cd84330cb2 33aaa085f7076d2841dbce57b42bb7c61739c76f041c130becc350efcbcb5138 045c19b336f55e018042905e862fe43b2b2dc16a1b8e4adc317184e91768251f +578000 e5b36705e126028107e070cd6b748d0ba1820ef3f0b7cdbd8c60a822011afbe3 b2797c8eec34eb94ad7b5de3c93144e6511d79ec389cd2b3037abf705da704c0 6f8eec5d3f44c63f9f3a3756b7458e19608fa7b2684463a59daf70abe2e08a13 +578500 0bb4c3b62c096285827dd7079f91bb367f08fbf323f01cc27257c6ad1b6b09f2 2709c029d1cd3164ac618ca33d9453913f52247ca266755995eba29516fd6693 00483a8ba5971f1cec76a0d4981b68ebbab3cb8d85081f517afd5fb6459b9357 +579000 62ca69f749191230d6588250d41ff452312e141c30bdc253a4ba473d3736c8fd 9690b50bbb4fae4acf7114beebb9c8f012328638fbafd2f54c18db4983c019fd 2d1d6f2e164c7f52e9d62d9822d503c15fc45afc1b5cacd362adcce8c11f989e +579500 ef36ef78010479cc9664a2e7cbbeed19da7b60b990ae1d6ca1c62815b74e4ac7 dedc37c50f5ee81e9697c49243e55aa6ed5c5ba8d1d56305c5120b308600fb6c 46275bf5cd6ca0c8c1d87fabf04278cb022408a213e75a118a33761af59106b5 +580000 439f43597ce36aa161cc2c4cd7c25607edada72003a7fb681be2f6d8b714d14d be5636a23710b20c61b3aa181bd75a4e0992dbfc1d267be7c66a3bb459ad10cd 055fd581f041fb63c623e7a7405d178da44d129f6d854ac6e3627230e177d688 +580500 c6b2c13db62622a7c3ac9e8072840de5d24c34f6337fc3d8f826933501245deb 25eba3116b640e04a77b843ad79a25847d31c2c5eef7da98952ebbb526440eba 6da7cf2ecb2cd071163c66ffa5e8eb3b392b48992ae3b8a66070394cf5d0e167 +581000 4dcd0d20d94245063d630bcf6d8079cbc52dfc522c0e320e39c16ca18853cd6c ee3c988f0ea99a39c2cf69e88ba22aedaa2710f49bbaccd1ea0b2c1ee65648d9 58291224ca13b2ff40bd30df8edca325b0e3ebc5564b218d472efb7c50837a6f +581500 44b084102871018a5db5f990085f3177856a38a8b727a36b29837c34e4a8ce59 6d6899031aab90e68c34f4bc3c1458960c7debc0e5e88de13bc0d29d9a4f1406 7f6af65874fabff02aa73e1351f90945b167255db2ada7ddcca6192a39fce9f0 +582000 4fc26f1bccf775fbc7314ca86532fffb93b9be94bc6f1bd75fbcbe688eb9dc1f 07296b68ecad02d38df4dfc0c927b430ce4c978fd42772740cfb185d1f73cf08 2149719640ce63893636f94b837b785d177c0823c548b7fdbca39467cfcf43ec +582500 fcdd7ac7dbd7a3ec5bffcf498ca341ea6f45eec4f07fcf5d838805979c154e75 1fdcf21608195ac2f0076e8203f72e8468099613e8edd350440efb4fa495de35 8f746c3c260e6c70bede298a49413b678bf3c5adad82adebf03c73efdbca9dd8 +583000 d32c77f1ee2542c91734ccfbbba36b35dc4b76db17374b52d514ab45e03031bd d7414a5f1b9e801ffdd889f95d91b381486c2b7bfd718907df3e4f3c16f831aa a786bd1059f0d53827f3fc5b95f44a302e30da16bde84a9b9f6b635b0b57f1b7 +583500 bf8b25a2a0b19d293bc739d63786a6e5be7cf111d60d6cfea462dc2cc7cab22d c03d273bfa3ebeff31d43a7a1fe34b51a5c968676dab85910f61691ea66cd879 9880b1b9a9f0fc497d0116b07708f56601a9f0d617632b4300327e8e3e3c220a +584000 b3ec434425ed197a317fe360d7f2bdd065a7f167e5c57bc9623cd150df2aa5bf 42bd629da8bdfeaa2aff0cbd4092f1db54db6da4e4487a7460ca7081849b1d01 985da906d7a0a79f9960993d47e5627543a6d53921c96f687d065030e3fbdbea +584500 f09dc804f47fc9fbd5a391883d0be1d3ccf5b71a69e9c2571ce1ff55b83422df 28cec5b73ebea11f29daf62db2ac9a594a7497ede4087e0932881d39343d15d1 fa2d4b9a933dcb66f6e57dbd7a13f7c2ddb67e9701aa39a77a520f14586159c0 +585000 5874d180e9c48959e292587310dd81134eb03197f0257be1516c7c50248fc3b5 c5e42637b4e90535090b09f2d90d7ab90ce46eb3255ce6abad941ff07ab5e0cf 403a7015bedc6c32d9390a083ac82f7b7afb46aea0a4a83d5167ec7a67c2a447 +585500 a6dd4e58143b11d190e168b1dd20fd7da47ba2af0d089f70bdb5ab423c8f47fd 134ef498a9bf87099abd879d68ad7d67ef4dc45b63bc16438aa0f95092e34c8d d2ee92dad9d11746f6f8dffbfd0809108733f964b345bbdbf7694a0f6e88a17d +586000 5fc5f5de827b01b620304dc74ea53a0fea4f814bb51ec5fe3b6c74ef560a5917 e1d0845de83160f08be85d114882976278106adf7a3c16ce16ff6f08caeeba7b 9d3de6f846271f15a037a646c6332b33fb288dc3fac8dac4e694f5c903543b35 +586500 2d1270ba120a5cf1427736d7f89cb05c42af508e0a0038833c9445dfa9c66fd7 be7998a06e1fa3910cf77a7cb385cbc6933abee919664bc52a52afa5388c5b0f 8264179f305f8c60ad40a69140749aa1353fec67ee02e3fe09b0b9f51d5c1d23 +587000 47ae47f30d7d51e5b874e5ae103aa38208203f2a380b624cbe1ba122d222f9e5 81558ea382a62cc93ccc002e8ba9d88058ebfe683b05be16fac0d84612ad2152 8acf0fe6fd5d74dfcc4c012fcbf80cb0b93b7d212c1113b6a3f5796f9f54a319 +587500 a558bd54422bc5d0a90c20310f81d9901a9d3956f5d5505a5dc50b6459ecaffe a8994820ef7c6f2fd8d9b6d710a0f83b537ff6fa1368060418cb00ddf642f357 746fd31278c09ebf66550d76a61464e1dc2dcec233acd70ced2932210d715156 +588000 fe5749f9e8ce47f885f4335cf2b24a6659913ed62e7d5af026ef0470004d4983 87e2b4277260305d5bfbd921b2d4592e180837e092f2acd3896621cffa5228d4 46bebbbb161226814d223a33cd8e0a172a30febd134800c2fc583eb62989464c +588500 4c798283eb8cbfca17647b16a919d49b77a999d0bd319fa624ed665b30172e21 a4c43d466e6429ac399cba93e1a594703176f7d1d7f86990936973120554c72e 6b6f4b3290e47a69dbdbf251a00df4a2b7afeb7adbca47a41dc590d3a425429f +589000 f8c9ccb89cd751d66c9e2b053cdfa670556f6dafac1e67a12f8bf06790c9fb93 ef76c7bdbce08ea6dc8dfbefec9d64b2bbf3180dc4304ee7e39d8c098ce3602d b69b5f0e54c78368bf62eafc60ff13cb2ff8489f8421583f75097968784f1aee +589500 0971e83e6a813fcc290f352ada5422a0f48b12e15628f9522d1ce40b2fd01e85 cd5ac7829f9c4de5b606b3a5406383ab2634f09661977f867c47d58f89f16081 31182ab94364878b63c1a91f2e0f939202bf757bd02ebd22d88ea7b555d077c1 +590000 cc8a0c71618970a1cd40ecd78572568e8522faf1c6cdf597def52feaabd15eed ede2c72e45aef2c244f56183b127ef08f9137effd46386eb8013f1435de42f08 3e67a14b9f791f361630904de1369a3caaf2472a593ca037dfea9e0a5985eae8 +590500 6c876707aa719eef0d5a9534f9961ffceadfdfa16e75a4a8c7f5c7822f8d9945 44d6b98fec0842acf25460f93ac90ce132d3600c752bcfb18d3e4bea90b9e052 c5a46e6e838d286e58975e95cf4a8e300db9f1485a2c8e1b1ec5fcb853ae9f6e +591000 5c5a7be46768f7b29d8912feb8eacabb2c592fac374fd8b1c9d74124a5bde94a b725f0ce70d650d386e7fae730da1d44a308d2517c91e0f6d6fc659316647202 0877e7e5eb963694dcb43790291d82c01af543e18e14f4692a01f4509f7e3f54 +591500 4df0cd912fb5772a508f9ab6fc5dc26ebcfc8e5fda9026d682cdeee3350f7f99 1a9e6cf241740c2f4f615bf2017473e6eccf52ce14ca3c244609c83411749374 90e218efcba04b935ae73a7e1311b084051c3c2bf61f811a248430377237deed +592000 5a9465ba2bf3034272ebb1a8b742abe5b66607193dd04f838bd9a2e9525081c3 c36756b7c0b4f7577f33bb7a6a2cb06d444e5bfac823242a2208a74dfa4a5264 0d5e09dda5e7e93d41364001d41b24b7ac3eea27c446208854aa5636a0a65a32 +592500 8e712cb434a6086e1068c5a36a70ac8382f8bd2df8f3328e869b5f74c4d3e268 1f6f8f8c7b6abb35e1bcc30443a2112a1cf6711f020c6474ea2b987e122e2710 3294921e4f70a5a69efbf0c3133ca8da617007c78f066f630af08aa65bf2a38e +593000 5d4b59deb55edff702d98ceafe7e74fb2c27a9e82b3b8f38a747c0013210125a 397321c39e0255bbf2f345d8c410a3a75f0cddf11f90b04e1fed22d57313f436 b040ad6fb241b404d089784c592f8459a34cab1d98b45604e259f97cd2455979 +593500 efab77d82b76d1ba1f130c61a5146828ef22808cabae00e8aaca746c9701756d 5ae3383c918a2d0de41ef7e68ecc81a14448ae6265fec8146377b88c14678583 5edcc7b13d4dc057c9ec45bb9092d9edc9059ca7c66cec27f98291a40e514839 +594000 2eddcbffecddf8dd19c6183606ed678b8d3c80b3d18a03d1f6c98de436465bbc 313ed4476687d320b09ed8f775c84f848b315ec7051a819b7b5db928b06b10bc 85ebdce92d77627fb4f70f770b45eafb2ec031a0a7d5462d09ee5935aaeda4ee +594500 17c2823062fbd036efda8d7a6cf9f02177470df9ab03a1ca6a49a4feceaa813e 967817ffd15c1eb09ae18be9c89af301d4faca27bd1435a4c1b016328efd7452 1629667a82436cdebe1c637f4b12892d0ccd4bc70506da6c4d8112d75508a8cc +595000 0b2d83d89d4bfcf2ba0bb0d6f4f002f83b33532a9c72d204b84c3624b82d1d12 ac1ae8086c27ae5dcb5491883fd2c00dd1936ce5ebb753bb9721795b51ac427e bb234d094a4a1a1fe506aee4b5db427ca92a0b608841d82d79e3bf83e2b9780b +595500 94e93ae2421b77bdb8eebc5a889e0dbf64bf0af3a9d7d718b92c626186186adc 58b3debd63420f3503c3f813e1fec6e2dc9de31eabbfe6a5517eda797c5a1381 a58374ca77ddaa4242e2bf68a540339e00323538759b0bd33ca68f127fb8d638 +596000 e556867900ceab6ad0fb7923aaad1331b8a44fb432ed5479bc8255a9f9889db7 5608f70ec745d7dd10b0d6650661ee7db9d15ead665ce8062892cdb60c51b81e 5bf82ecb4e612f1a1290f08f79b9a17c4f6e705c54382d79ef4828d8a5174e2e +596500 e07b8c8db8312393c02cfe1bc00a1a5ee6166083702d2db0fd24297095202f77 3df091b27bde63d70fc8d0feb4da1e97ee21915b24f6be2a60bf702051c243d7 4c713e21bcd71574e8ff3d13968e2c1ff86cf69348872a9319d0d879d0462236 +597000 8e07ad6645a83dc63b311fb7d39bb583980164e40032a0821d0acb50953b8ef5 96c796666a2f4c215410baa022874914fd9c04a430313d38e98f6c5b743b969d 08f78b239d3bd3b934efa4ab3eb676dca0e24e4c945416e22967d6bad3c01a74 +597500 6681cd271934d16f89af3d71bdd886f5d3d50f6ef9fbe17c4d95eefb6c770974 e7909149c034c8ea84b92f77b39a9331560661cb4c158edda770306a4ed7cc9b dc6087c2c41ff738c099a11f2dd7e2c641f97f6bfcd2c343ecc372a0b78e09ee +598000 92b359d658152c31b8c2f32c4509f3ccb1cc18b4544745608da9a230327c109e 3f75a2b9ea70de0fdc330ebbc5f83301dd507c4e0fe536200402cdf30fd28a12 5788ceff503809b984ceaf32a496e51bba2374ba415e3f459590a1655cefffc1 +598500 be474d552a4f17ec673478af48534ad3c65eef1752223ed3012534dcc4274db4 9c304d0d24348fa013c7223f1e05fc9092a773e6da14920e628baf05669a0f08 67e9375d6815cb71ebddc38da5965a779ecc8729333b33bef2c4646bc611a7d4 +599000 275ca25666031af015670734cd4fa02ea0e0b099921240991498e684bc234940 83b44eaabc822a3d26f168dabcbb175357e1a37a025813fe30d5e6560418dc4a 3d2abb751cfd15a5cad35fcde5b52b4e82b32c11a567fa0860a25f83b69b5cdd +599500 f20a2a85028e0a3c65f118e50296794ae25821fb5dc0a59f415305d826a827cb 937a759ca109521f0ad2dd2bcabfbdcd08508b97d2928a81bfe79962c59f6e27 504abaa85e6013ad139e47771e947acf3c858fc49e0b99c5236d7f84723f3c6c +600000 fde9cb0677887e2f966c3be87d1780db88353977fa2e426249d9b26b01be1db1 74fc8f58d336eaafad2f515f0b5a5eaa679c82160f2dc54f35fed44bb845c395 3972038fd2bc0007c3ca205a21ae11ecb66096006ab3cc9ac2350e2da7f1c506 +600500 ed2fdfc9d3b07cd7e4d4fb46b5cde484b7ea5cbd436608698ba0be6407928d45 78eebaf2d54a3f5ef9c98b58e75325a263d7040a85d2757eaa6fcd9edefa8bfa ab51bcdc56ef14d0313de8553fb8ddb2b9f8d08f8e9fb42ee67b2365e2855cfc +601000 3a7b3e53a5c38bb7d0600352a71701c8c7b961a9936d319ec1f39eacbfa317ea ae8e3de2cdfe471244ac6698534f60a82a93e59b36ff22135ad57f5ffa9eddde 131208c6ee4f9db5dbcb53f6b21d9de4b1bd8a4ac785684e91ec23446ae01489 +601500 9ac84b004712eedc9cb82e4eb4f459e92634ae20ded19ce2a01b5039bc9be041 b1800a6430feb20276c6d1f65b1042d5da3d547a575d7aa8f8515985e793cc8c 0534f69dece37746712175d940492ea534954520282a439fbb88f81e1460d4f1 +602000 e584426ba4821ce97899bedc37ebdc5667d94f796853b5dbfc8597123f61cd93 670512bb3eb55350a01e55a614addd9a1936e220c349b5fdf83ff85d36ee4762 b9e225817855b7fe034416f3c8f60d6e918699f9fb0268d5bab870ae293f3fb9 +602500 98c1693b6c94cebd5e17bed36779a7c1498f43d83c3fb9f833ac42eb3b1f148a 4335ab6f363d6556b820a8527702f5b224789aae810a9799c40289f088d876cb ede7bc44211f6e62eed8f645fb0f102572e32287eb96203537ea916a60d28838 +603000 cc90f10fadd0c325018a7f5b2819ef126eeeceb29cfb1abac3aa4d918dec8ce6 c323abc97d8ddde6d935f4c4a3748fd5df141948b855062c0d557814b6c57582 22b9244f3382b385b197696db2b875e2fc0c12b0964100a33cb60edfc87e1840 +603500 88a282051002196bd7e47c2d4d05acccc49be9e0a1958c608bc8857b0752d805 4a129ae3447c19b8a4ca1812fe819cc571bae08dcee26b2f312bdb2292e7567c 0f0928f3ee33d03f8656fb4f47003e700e63cd4a1f38f0b395c04ccd0bf32589 +604000 8423befd6cbd718339237b9fd01a9bbc7de101525a01e45777cecc593795e76d 10125b30e2a5762ca8991b3ee699bc69e552b65457759c8b0a85468f52575c2f af73d30590eac4ce33bedf0d830a2b525e1831475360baa1cd1b1e15313e6b45 +604500 5f07bfc38f07c663a551462ef3fffbbe9a1f01d54e4987727649b2cea7ea3716 f17db8519ba7ab7e3cd0442a008bd05dd5354ddbfc696dc9e2aeb07385929acc b0ac0adc0867e94b14759e51d7e7a5e217acdb0fa27b5637e74befbb77abe463 +605000 691b12ae780daabc6228123ba85e5d4ce2c48d1f6084a428ed5d310d644ae101 15ecf51f40220aff461a2662902a91b0ff974c6b5dfc6853a37d492ad0e7c507 b15f1ef422d7205ea9a75e2a755bdc9dd9894167da2b3714596e6f72b961dca7 +605500 52537e09d147a2eaf5a3e843ce45824f3a0db686f36cbbe72f69fca61a2b1c01 ab643490828905c7be3f1c8afe6f7755a27c4cdfaa5c8488fe2441aa6afaa70b fe93785d20e88a156d61e58fe667cd7d88b799235170892fb73a25021f9d6900 +606000 945062759b3b417205cfff5d9b2e1c29d29fdc235efc71971a5c930ef5fac2a6 5cf40892ca34be01dfa549d94b8784051375b2949ba916931a8addf7eb3a9216 7632b191ab5c86f8921e87dbd6e044b353ac8448f26ad1d0e341b6cfcab681a0 +606500 284cfde9bc92fc8a9a75636ed0bb98a68a7d26fa82acfdba09391939c2e9acdf e0d8d1c85bb390ccf48b59af60483c919c08df0f8830de5befe65a43a53a99fb d354e0802e7ac9ac517c773c45514b91c3e8fbcbc4f159ccdd842e52236ab02d +607000 fabf1c22a50594542dd8cc8e0aeb6ce78992e1fb97dd46f25b1f766392b8c466 c42f95954963685fb338b1ebf0f0de3c8fcbada7fa53dbd4c0472b7cabb75eee 8fae72ad94a28231f967f2a8856aac31fc33f5bf9a062bdd59faf431ee62745b +607500 a2af7276cb9398592a0f0d137875baf3d9291a606f583b269540f9ac44a17ce4 b5170fbaafdd9059ecc043f1c4ca714de50133bee7054f8c119e0eed79e20ef1 da9ff721da89780eb2f19bfa0540368764e1867c09d9bf979229ffd3b9dc00e9 +608000 6a78949783e00a8ac3d832c24e69a2c6fe028f110e8f1a7d87d652acfd5b6b63 01ef19adaaf1a1d75900879f2c7bd5366ec4a6811ee539db16e81a2b981c192b bf5cb7827f5372036159b01293e6b4f8a7e6a95136b3a809007f99330ccff831 +608500 1941dfc27e96aee1848d5fc8ba94bad2507ee14f8a24235e4b35af5dc0559f05 559954098665a3b7a698445445daeee8967c092ce38be59cf1fe78ce354d221c f137e99fa941b0e0170565f9e9d853c421908dadb65ac79d59401791ee909cb6 +609000 ddb824a17fcc47e7312cbc0b80838b8f4fdc077d1f8cad5b08008aad8a25afdf 528daaece3c6a912cf0859f93018845f781575fa67f27479ccd56480f40b8c10 8b95320442ebdee812dbbae0b254fbcdc0923130e39406b06dae60016d37053f +609500 3f80a004163aa45d2c9d2a1c8bb238a15b9db4214c8b0ca08effb0f37697c40c e6a2eb1304a43261fa54127676cdee58792115ca1b400c4a08261f1e170f19fc 530edb76f0368d187c0312843669fcef70f6f53547d58af9d47eb3d99e363db3 +610000 0362121a825d39875de7eb528be247603e5d93922f21f738f255ad44171f5edf 3b57b352f45dde9c233dae766260ea380cf6114c7682dca95566e656e9be1511 ee0cd70b32d25b140cd41391341494bb74ee64d0aaba36c8dd66bf47daf6efb5 +610500 d39319109dfd619800add37b85ab545fe8832c50036eaf1aea5489348e749f18 14c16bbd895be10be482c66ae8444f39cfd67f9c3c244f86bb3f309f3f38ea3d 23a66b83736092b91886d548614c6ccb4df931deb591ef60b795f3b9ffd59353 +611000 274d0b2789a39a2808a69e9c7d4fa6b2b34b7be5ad55d541785f6230103a6110 610d4811e3da6b704ea224ce3cef798b3fb9495609971c09971691d88b714885 5ffdffaaaa4c37919493ac9e80821fa240fcbc2d006b16544b0bcaa2e932695c +611500 c25930007a1325f971285a32257362f90f6b5da474225d3cdd19b9053a55e6b2 c052c3e6c7b866d2212ecc66d4956d8b3c0a9b97381a822ed203ea796ba58581 db4f70e0b89e3b0552027680b9fa09bbb3b65a6fddd5fb35fccacee1b069658e +612000 8dc46e21fcf1b95e59d6be6454adf1db9d141d9e78d583c0f4efa47e0b2e38a8 538c9ffcee5485b309bce281d6913a254331647ab43d492250c66318503ada14 66bb108ff47b96dbcb4ab0e0d49a2136a263c1539f67cba6cc5dd699b2da393d +612500 48c70c688ae362b4ce2e19325b0bf5335301f45cd6f0f562ff263d5d57324a2c 06f90f226b98bf0fff455478d39513800ed400dc9dbf41c3a6e498730c883e42 c43d539f28c942ebeb575494bceb18356d322d6465b541fb1ef6bcb14d1d1cd6 +613000 a05ec2324bead1349845a8000c76ff7705e0ed1f958dfb46c92eaf3180f301f7 4d6d1eefb176cf04b6cc0e9554cd81bcfb00e1f737ffe5e25e752f9eacfb20bd b4c6888c5232096a5f117b09b1b577301a45b99636d8556dbc03a833805ec50c +613500 6d0183915fa23fbe61d2cfa7dc9ba9c54c164b246d9f3ea2bf28c675203896b5 e233a4490b16a593a62853877efc01bff2e03b4e5017027fda754056171236ee f90d236bd564360e3964d4c1658aade4df26dc6b185285edfff8b7fa85ba7faf +614000 dc4d72e154553d04502271aeea36609af31e967faec981fdb7aa7686b194ef72 a20198e44d09d5a45d18b1b2e20911f6d8840ae7618e39f1805dead4136ff220 8e805b125d35cbeb91989a832fe0573c60602778acce51c2e48647e3a9f44807 +614500 401187c2be8053257741c3c78fd751d5aa80b74239ac1a5fd7c2008623b8056e b3d69a8f679aa779dcfd6b03d44da4318c10241e1a87c8de46dc2067879e7561 a7e8e2c3fb0ac16f1d4dfeafb173fc49e6d1dfac2e7a6dbaa750e27954bce7d3 +615000 a7edfae28117b555c502b1b0866e70c2e45b2b53095b0b3ec0518f76a3250e96 180c90afe2385b2149b5622d702e1ae33e1908e03fc9ac457f18cc86e3453813 f2883eb378e2317f4c587e7f6094d2c87d758d88f9e55bd202027cec5b0ddc13 +615500 247cbe6b3a28a410c816bbf3e344fd707f5b98c9fc7ea74a653e55daae43aa7a 675ffec485147855367994e9f3ab4ac5ad7bedfb39a35959ced78034e9a04318 dba0d9a788c2a5097c8bef58f8dcd1086721dee07ef94caa587e988d0b4493a9 +616000 091e39d1de4719fafc22075635a0ed10d1d8b5636a21927557b2baee8bc453a3 5cd5dc9688dfccc2024c771720a75202758606c6c2b62b3317eaca215338eb9e 8538647a15cdeeb27b070f34e3cbba6bd910dd6ca30acf41f4e8fcc69dfc2a92 +616500 245d68d439cb7cc9d17d41d8748be112448c1c3d757746c28c32e3531a23a66c dddbe95e870b48d8e1d3be72da7976def8a5f96e20846bee2ec8d3644de876bf 67b7c47a006895547c671ee3e3078f5c4de5d8b54184348240c7ba7ebee7a49d +617000 9a08546acd2859279fbf0a140d792be72040b3b5deccfdfcc3a40d640c60f35c 3fa1b0094367169cfe3c3047b01a8bbe5bd1179ea5252153da7113477dda7bb6 5f9e7e0db3ab571d518ba8918c74b343400962664b97339322d394cc431a6f0a +617500 ec4c7a99f349f9b610a1c2c94f01fd8e37bf98d8feb6a68874517a47b27a199f ada5742a01ae9d78a4aaa0fefcc2542633e90bdd178f540e802a4e5bf96368e8 d0b9c218ad2796ce4d4ec1716498d747ce2dd9fadd75ece154de1c50932140b8 +618000 30bf0bf59fc693f06b630ff38f55f5788f24b27fec1c171fd5f63b6a75729f83 a4d0bec878322f07128ea1f7318a28c492a27649b4e216332589628ddd9053ae d66ecca88efc3eb08f52e332fd0fd5fb8ba7115b815bf253f0e39eeb514494f0 +618500 095af87395d73d93df9f2531ad54c6a486b0c98fff5e59a75d9f468e2317b989 c98bdb9ed3f618281b60f496fad0753ed0610f95899058a5662a45bdc30f2c2c 75076658902306923b786eb552a2faa289486c9ee08172538b170aa59ba109ef +619000 53c7aaacaaf469764119760051cbb7be6806f80d51f75099d8096831443712aa 8e52bf819476612fc0943a9b56d5027935ca897f9a5dfb686cbedb8dcdd83bc5 8d76699c08cfc5eaf88aa13bc8af9a9b16e92d6e612ba3580066f24b15385f46 +619500 7e55322d59a65d0ff1be11ba083fccc9800550a273a52a77926d5a67c383f429 1cde548b5fd12717415c6f8ab191b0a73aa77acfb6c8db2ab9ef1f374bb8fccb 8173cc803d6469a845493f73a951754b2cfa9b5df473772a4a77e56a104697fc +620000 ce46ee172a243c059752e237dab267c4c95b111745b808bb9ad1f8e99dbe84cd e14873bf1154683503d0b3a1d0180742f3eb790efe5a968845a337a4877f9cc8 447b50d4296c156c2a3cfd7b4c8694a143361f7d9ed56b1b2497e81b01462e5f +620500 31fca5e075086e3ce312c78e4e67a24a245c48db04b7d07688a46be3efd12560 d5c066fadd66b4053f35e728308e8e1e9594693f9afe8f930e342f89014e1435 9e53b050cb6df8118681c205ce2a3beac7952b65442e2ab7247a79c3c3c75702 +621000 c27deb337c86fa6c1a9c967c1c0e967d66ca91c3a605ee42ca9ecaa3c7801715 4bf8d5ac8c9c275f434ce687e9aa2e5bb0e1c1a8634ad7dc0380ad74e9f2a471 47e53749b73ad12c2671c9c1d544bd4758d8c0f7b0b30c00f2c4610aa21fbccd +621500 6d6de5c0c183af66e09203c1f851e005b11ffc3e65821a0b0c53ddcf0577a86b f8e09ce62f6793636184630998b1cdd6e513174a268fedfa3c23d1beedd6f127 933961fc62855e5241d0586e32be4460534b723fda2d7d0865e089a1c4324bc4 +622000 3bb4c331c1c410066bfc9c84fa96f35f008d7ebbb8630f35616b07d3a8f6bf09 2625b34fe7f2c205449f2ff67a4bfe036ef5f479b520c16f0fc16ffc43e5e713 328d4df64c5d59c971737f12d125a3d32d4794b506132e08a09a9043b0907e50 +622500 b69c590df86c64c53eec4355ff7e4525ab0ede7c40da8cb6304556c465708619 ea025a51dbfa831f98ebb1597cb43dc29f34d18f5522b57ac06d7e19bca1ed39 e7339a6249253a6fb0337bcf5fd188fd50bcfcc91fbd7c80cb1c830d711516d6 +623000 248e12a541844945c6b91e45f24d7f63db3dfb41016952e628c647bb82562c91 d2dcaa98eed5db5e34581c8bc52808819c5cf98bd564661252e24fb7f98218d4 2394ef40993563da36d854a0f5f06c0af1dce3ae7274d3a3d6655264d8e1da54 +623500 0f6332963afce6ea94d654d103c3604c724a5a6bcdf6e32bdf9a708d10de519f 80f5b0685f010693bff7453273d0cbef3d878e9753b19e05a5d2fdb4984f8a0a e7705c345164e7069e9529e3e5d47c12222a3df70d0f1300e39f12cf6d361337 +624000 3a250bcfa462ff8b750d0a725962879d47832f0c77b46dfcd27e3eb4bf352257 f75082779f75cba11e26f60eb9556caf48daa15221abc2b4a83a1cdfff9368f0 7cc8074a65f117e7942ce910dfd07339069627e317e1d4a31106ed5847b218b3 +624500 6a0ceb40f1277b4289334b6cbd593aa5bf593160ea960b4887e40afd2b06d767 cb0565ee88160d6c0a26057155cdb2f9e2b94217d229cdb627fbe0aae9aed145 9802ef2c8e15d18bccf977c41463ad4cc0ff9af9dff0a1104194dd4ff18ab9c0 +625000 c28164fd18e1087787d2e3c7d67b8349aafcadfbf815fd7547fd7ae8da9e7937 319cabe08b33898fc3421e1cfe329711de03a92bdf21828a59594e813e71393f 894a1464c80bf83652ceab26af7dd40661b1f157f1a1f77be34cc57fe01f0505 +625500 00c9e51e1237a00f30562f40f8d7696876a62523a7888f3019103f97d27c2afb cc7d1fd4e2d9a95e3a9a7e23f44a96f6840036265a29cac5b4a364ae1ee1b806 de6b94caf4e70ed1bbcd7722a4fa7e0cae7b2490f07a815eb2b4c9278e0b3600 +626000 452cd22905dce67c27114fdc0b6ca64f4127abcbaff999b7aed68be214fc9313 c969541e23ade41ed8ab864eb6fba11ab9ba5c6f29374e666af4912c2c076de9 1c307caaa8f2730c6bd3c202a15e94a9004ab2b6f0ae24d58ed678afcdbaaf00 +626500 7a3f9fe36cb72b3529747754309d2fec46a8155a6f297bf5d9998336ca26ed2f 9184cefba7d61de4482fb57cafe1420eaaf58e3f2fe370e9c22f2dc235c26763 44910dd207c9b780f4295ae81102f25cd2271f810d19de06cc914409a6fb3756 +627000 d8f9b2f906265aa50c5eefed906e89c06856dd2c25bfa2df52f402fa029b6c6a 1c5dfbc7bb572903d6eb6a400fa50df3c18c87cedade5b4ac63be7037f050a7a 3fe4aa644342a4d6f4cf92c6e15eb94151d403a521b58fbaf90dc0ab2228d530 +627500 711651d2f7440f20927ed66e680d833755ffecaa905c0712ed31e1e06a81a4f1 6de06425cf412c7d272841f1b3de2652b15d3300902c0da6b7c1b08bf4e14112 c2feec57979a5febd4e028b999c765b3b127a5c9a31154c2884633149a276485 +628000 1f04acc62ae096325174e8ae11579d88e65ab4f435e3bb8c41896a1cdee6e231 c87dd969f7dc7a3a356d7935a69e4c8a4487c72e7c623f49cf0f60cbc438aded 7a91eef62edf2d9c9752b0c433fce328a8fc4d23595a151c6ebecde64a55435e +628500 f55649153110900f0fa6b7d2f9dd6c293bc44ed7911a6e4d52ebe5563eb3a4e5 de1bf3695afd590e9ede9881a431abee861f4cac9ab8b42cfdb8c37f0e02e19c a02b318a4219df923d40ffc494d44c4fe0bde49a03743c588f816e99ce01b0a9 +629000 8e7208c5c406f95dae4ffd540aeb30a111696ed10374f03cdc186db66295f054 5a8b55bcbfe3fed8453499ed4c4a51233f65626132aa23ff6acae30dd5cb3800 1ec2dca991d021138b1b9d70a4d1f4f39d0dd4af1e6741c74fbc84ec2fe02552 +629500 30b5177f1554053efca360e8acc003ef0cc4ae26820331715fdfeeb2003daea6 f7e5d1c5ed411c3afd3a51d63abc4f29fed49ee8bc2f810481491c138cf09183 aa3a31f783a70cfe04040c1c0147b6e4f31820bfefc6d261378f62ededabf4ed +630000 9bbdcad95ee5cacc45ff51ca8d627ec7a971b1040368ac62a4616f873623cc79 306b7845856f157aa25e14e34165e75ee5abdef7337cfbfb9611f628287b83b2 783038b2a1ddee91c807f00c7cd9206c7bc0209f70cf8fd93f9e87df6adb4ef7 +630500 cf2b412c6c992847944b1fb396cacf61bcd03aaa460cd810e3f42a2866e8d729 8d2c8d7be61fe16d9f5c0f5ea155eaae7f926fd8011209de27e41cc67055f5a9 a6c409f611781e61ef4b35ebe5fd1e3548bb181779a5738d423ebb2f9bc75156 +631000 ea5e4b4acfeba1f4a69c63647cbb45147ba1dd101b9fe58843dbc6fb09f7c12a 2ef37567bfb65be1417d9b5914570c55bd88da0bc07f7ef7389e6324cb0b528d 5549746df3b12cd08b070e6aac9a3001fa63b7a4c5c407fd68c66aa6fc12ab94 +631500 539334450cd6eca49473d63e4917725250afbb6a546a025b57b40e4ced8ce63d 865fdec23689d881dac49ab8fe9a20c5984f42b4be7cdf3e94118a4baf4fdec1 9bbccfea4bf635276eb9d1aac8ac9e0f4de8e9be30d31425db85db1f0a8104c9 +632000 dfdc58aa41d2ebe7751fe2b3ff90f0496e602cfaef1fa0f1c25181a3be4cebf5 8e3f86b2b753e8f342046b61d84ed4d2e9ce107d7f30a47361e983aac874f448 376df1c3dc60d76149265cf188e76ab5bb9f90f2d87e6e42927586c7a5e3d277 +632500 54f71b9330b758d881d325e8f3ac9e0f042d8ea1222e52b580a0337a3b4f3fde cc0ff7cff02212ef316bb6fc2a131b018fef8b6dbfac01b9e2eb275c9008c613 18ed8351a297be31c3a6b1892bd51312d42fe81ae28e819a978c5a97f337489a +633000 67de40386baf1179b74ea2a750bd20d6de8f6ec3cffe5100aa3307ec81bf3a4c 7d69bc05bf967c291b2156c18c0851caa853110a8ee527bb9872001cd8179b34 ad0f698fe88881abd872a3c74332a091fc1435d4b2b986a8feff93ec2510ddd1 +633500 4414265aed7c038b6f7ce24cc86619b0596162ced270a87c70a59ee3089165a5 09970b09ad4958924d24703ec56fcf49a7526a0916cc7f0f841ed9796bff86f0 bab8a103a1151cce8a253688cdc8c93a700afeeda79861febbc767bf4a95a2c7 +634000 a55d577e338fdde481a3cadfea26ee6c1777ddd6e35e66040a4d99455626d9c7 5da3e590cd7190a473f7d61027754e5bc50545fceb8867db96006d3773a2b746 3e66c1867ef38484dd98188fef38caf9097e6f29ba8719e902bad5187d1d483b +634500 571d3172a3095d0a34747c18c2e2cbaa4173a09ae3a351736b2b4802752cd9b7 6799dc3c2b9fe39f72a22e6fe27ebf46308c887e31245a5cbcc2a55f1060ab44 8509597ffc90e9faa61e2f11dfccc9b81388a9663d4197d9154293219653af26 +635000 6786a43fee0f379b103bd594943f26eee0f0ab3af9dadd36d6afee547d7ff8b1 60794659a5de639280735ce3ece1864a66e5754bb1608b2aaedb9874a6c34d51 e71885bf66653e463925be8e6a1677b27c0daa1ed1f4c23f12a18af7ba58f8e0 +635500 bc5896373cd6ab14f28a690a7d59366ee57a625cd6291c502d64a3a9a5969a96 cf6d7eb9c0306f24bd7a47fa0660804b633f29fbfb647e79d03a545518d5ba17 e0ba3988d8f5ef59399453d1c2db9690ed32f25b8d06b718d2645dd770b0e277 +636000 1aec8a1d1f6f5abb68d49597795c24102bfb767822705205486829ba50940cb7 348625a773758822cae41638d27628bed89a118fdff13dbb773ba28471ec914e d1b089ccca6da98d2f12777e9c39bc730aa0fba9eac004d9a09627dd60dbd566 +636500 cd844ea294ba265e14ea515b603d35c2dd13c9c402a4a1a13628925634e81f23 2c881b78d84e98a3a6dffa6d4e55c347947053f184c22f2a75bf62cd779febe6 56c67d302587bd787e1737e66c7fdc166f4b83d2ed88586c08b62c04d003b3b7 +637000 7f0393f05b3ebfd7838740f3030dd915d2125e9546e39f503e288a20b14d29d0 ffcda35e368f4784c75aa0e6a98485a2b84fa1ccba37f7fb5a6b4d4e187a5033 5cf175683ac51572c2fbd9d3ea1135b35288245bfce82ab8b20d93bd0d56a7d5 +637500 7453182caa6345472aebc820d839d70e916b8e01527e69d2451e68df9f5fff94 df9418647903ff269234df3583ba76f054c7fefb3237b47206f7e25d9ac118ac aecfa9844364a499e2c72ac729128b46b93ebda616fe09898ac8283a62e4f800 +638000 2917816bff7d73f4b4f03a31fdbef162ab7b2bc38e2539952648f7e9b66dfdff c7367a49d181f9e332613c76cba3371c16cff94c10a6bacf504c8ac404358b74 c06bc407d795e6252326bd4d1b06ebe165cb853f0038ab172a59f9d7846add38 +638500 e10674d6c53842c520040ea608584860418908244a9203ea9e726544ef6dcc6e b67a32293808e06725a391d616889dc4a438c8681893c17646896d19411e1cba b04d875cf1633f696fd0167d6567f117f0135a6f60ec9f3682503843b5931925 +639000 a4629de92adb7ee055af0b7a55a0690efde637a84e9c19fd423aa74389c7ca4c 95ccb5ef5e2720ec5ce9635d8eaec7d000b16b3abe24936fb8daea2def31b681 6cd590a9251fcaa1b3f807a7bc4e408ae0e826cfc9ace4d08f0c9e08e3b1412c +639500 dffba976bf5db95ba5845ee2863a8f60f855391a80d3a59cff38762f0992b38a 589744adb3b63b274b63d7c83913c65d121c13dbd8399aa7e0f317d4b37b5155 051f5245a3d1b1f09f0411957ae16eb2eee1116d8e67cc0a5d8c25e3c2b60583 +640000 d5c3942c19dfae03595dbc0683dc712467c00e5307bfd96609c4a728eff4f586 33aee46df3a2c807e3fb8961929402532d1f1061a5e1df2f28335ab40002096c 344191b74b6c5c4374ea484a87b81f881b4aa24e72f8e3d55e7effcfc672a724 +640500 2efd0a03b8098ebfb96870e4235206b8bb428b5aa568aab56db36e3124c98c04 e67d6fe1642bd591df2f838f07190f8477622358706dce1a631819c828dc4980 fdfec92daa00d4402a8a3368a31a17784aa85b10da7222e283df9c7a0641512e +641000 91beaca7dba7afc17cc193cabc2fa7c34be665d2d367c9f0d17a8385903c5299 b90b505393575a5869ad32b498b2fe7ae026db5e3be2ae066ee4c8a4e50ccd0d 2cbdde622da75fc20c993e7cd8000470b627ae3dbe0531ffb156f1260496ae0f +641500 52a2ed25b8afbf07e9bcbee8bab225af6bb0834b500ec30114697924951b9db4 0d30d77943438dfd2b1d85adbfe26de36a3f821303c50717d3a7e55abc59cfd5 fa45abae09484832e3b6ab1510a79f1435e3f30da6fb2dfd5dd3e2e611f028f3 +642000 24cc44ed0510958b23b614206b702fab53cb7681905d1aeb12fb532fa850a415 05e56dc42c34c44ae0c67c45985004c753588fe4588a4060444532194840e5a7 1c5f05780ac875c2e6d90507d6f1ac2c62bd0a96ca5cc24b41ad28282e205ad7 +642500 2cacb3c0be5a18667d5972d99182b87eaf485c724ce81cb59f3417691a920977 1d5689874267933eb1b72a5696935202699416f5f064b689e7221d6dd4a2c3c5 49a3abe7968ac7db221603d4bad3d8f6f47e8b3dbf034429c335711d3a729a18 +643000 94ce4d9dcf18b532dd9f8a490fe270dab5697c14f49b7326efb3e3f82ddbe7b9 f8466520f91a0a9b5136c8ba589bf7fa7a5ddb292516ea1dcf7820d3ee7c0cbd 83d0fe5e99e509d48e6f8c9c0736d98435fd1cabc81f7e5a4c70c31ac4af433c +643500 e3c751b8fb071c5ef4fd1e7ebc9e902d365b88c3dd5a90ca5386d7cc42813b39 fb799e659716a37ba6e9982fd09e8848d637ef1d85555c61af74dc996e1c6908 d312f2af49d0d8b7cf4959454a72c004f42dc06d5347fd311da1d484441b726f +644000 2873489104d5b817e24659b1c91e0b4ed350c388563670846658b452e279a44b bc4bee8a1c8a2b98d32ec490a31632852f7935737bcad951d741e789ef99d15b 8cbbd8beae20c883085e1adb6f33ca13eb867a2166acbb1f948c82fb3540b1e2 +644500 2996cff77ae12636ed2da94137e2dbda45f5db09c968e13d9002d9d5e8d1bc8f 1482ea5ca89d761a9b99c8e0a5791d430478b289ecd506b3b1ee803d90be7f94 b87e9b5e245a76d85dd89bd64fa4cef1ecf892b39828c415c76de1cb04385788 +645000 db1d293ab843d88849874e33883a8236a8bc4bff1d93b7d9922cf1f7dd3d0803 b13760cc8ccad388e7a35b3fa743b2c07b1e40cd5604c3d4162695d02bf601dc a3aa481cd7c2879b8dc135f770e3f611288e8f0a1b9188ddae6f2476a7570d6f +645500 0c98834ca2fbd0b1f4b7e708c5f9bc9e820370fdc2b1126aa50eca16a46813cf 95b1ca36aee7f85aa247e91eed0bfd17f8ea675c5d9db342d9087017117d73c3 f12775baadc6645e0f97bf551074b02b56fbb7dd4d33c9601f254931872c2f0c +646000 dea1a9883f1c3af496fd37570580c5c9a1e1ff7e8822d70188737f7aa45df488 ebab9f3327181450b58a388214d86b56c395f2e90be9f7d595ad7ec863e6c1c0 f1dd6f32b53db9b62e895bae55320726b8879bd31da4df74fd26cbf77bdc083f +646500 5cf92252a010e2d62030e5d74d6371e873f7fe6353a010791c21307d8236a3a3 392318738e04bc641e4375f47820bb59664b62c88a0f62a3f1bcc75be023b3d9 b5ee3b8caaf574e852f227a55e690159cf5c89d2cc5575d58105abda3e86ff0c +647000 b0a00219234dbf1942eeceb7a31565ed117dd8a8152f1d343277433fb3a19233 8cd4d156025aee385a9cfd46d38594d1c4825f52555a703031c99c005adb1513 3be48c0c754c349317f07393558b718ba29f5fdf3709334ec95060fa3a912aa1 +647500 8cff85fb1e3b4a7218a58b6fb2e7d0168fb5a4ce4171bf3f0b7f1e7a5f214d0d 50dd61b46e224a437159c8faa7d18cd9c100d1e3ff75eccd770d8debd7723410 91207635925dac923650f6a18ab01456ce08a74ed238608894f2f0179b95f51b +648000 133d2255f56a3c2737eb94f337c9fac97214a7e1f54e8ca9b4bbfc6e056443cf d10ca77595aabc294483ef2fd07975ec43cd2e0764d0df38786d3ecb5cdb810d 4fc0a58c1832f9d5ca4992f030e43cddca4d33b9ee9028903e347cd2a5b672f3 +648500 37691423db6098cce3ac61dd2e0ad5202cd08d37e2a810a4b7e259742b50f561 4fc55c6790346c316db4b0f1a35d067052bbaed3932cb8a369f8263791b9e749 69958cdf79d3bc23a0f7eccc268248d1aac3948ab5afda1d409ad672f15e4484 +649000 e8f43ecdb6979574c66b478a2d3ad028145349c43ac18f67e089f6948a48812d 7609d55e10c1b40d62adbb39792b58b5c075f1c34c6f8676cbbe39e91a7e504e a388b583005de4a80b25dab466f64d532aff83273c495e02fd89e94a956f0fa5 +649500 18f631309a2acc38dbd4d08322998f0d4fac526eadbb1aa2ef1ccf75173adbdd 83794a76b25f0ee49153d50f9bf6d196d1b78bac25dca55b9d3eece5c8c1c3dd e68250eb6a12a699b48123095035f869ce12acb5df58bc82ba22d7bd79d1b261 +650000 fffaaa151d0634fdd830e104f884bc05d30160640eefd126e0e01b43bd5db5ef 7ef1c36f637320886b505c0ad5847bf0a345c6abbf4e92432d863b0ff517bb91 f8aa7d420f5288f135088e929258b2af97e9a9a569beb546f1aad5da449d3dc5 +650500 bae09e49248acd64fdbc94cefd831ecb2a957c0d5aed72644a3607a198c77740 f1ca4b8b2e74774fc3d86ff3f2b5e6ea8d59e40a683b993fa638c6770aad547a f2e5d622db2bcc3a30dc98b50087fa2d1b1d08f4f056a0cf95c64089873188ed +651000 5d9f45be4e7d558b3133ab3a7d01a96db73f6a16604f4e348fe04aedab48fc1d 38c0484fb001d8039ac07895bf04765ad79babecb93040f8b45e18629c1fe566 6302f913b0ef7b4ea4363f185260008e6a8bba77326b53e6ec21279b8d1d1632 +651500 7e12af704c44d001d842767b49709eba23ffc53c8a20bf96b0cbda7955168521 3e563eb1f016f0b9a83caf023067785be15032588fb1ed9d6dc2e7d47d7df8d9 1b2277d903daa8ab2a72e3039c5c782d3936b27776dbfe11894288c5aa34d3d8 +652000 6577afda5b1a2535cf30f91faff821b56dc9f969e590d406f644518ae4dff6ab a6aa3534f3f962041d6c88a5c413edb0860aad04ae8068ee31070716e552c03d 5ff9539f10d6522936100b9b48090d278bdaa9cf418d511fa85020b2c7aa3868 +652500 f60863237c82f26f35682a510882c8c8b3ddf302e479fd201a5532fe02993d3a 623ee7add095d1a51ccbeacebe34fde662c727a14ec2ce8c856d2da57ebd1537 7532f207a5838a5053a0f396c10b086764cfe595456a80571f043c723752599a +653000 6d2f869d3cc7314a06868edf43473c3eb2a4ffc902b6866b2b6d9ed8254aca15 ddd54a91243a02e778e23135881e1a17a5829d6a698410cbc91c9c70047f5463 c74489f4dfb0ab0b6edce234f2613ac2d05840b066af94bddb47907d3aa85673 +653500 32d04fcd783380025ac2f7776d0868e44808c446df33e7790b9eb06edf1a13c2 9dce2c2f0200948be45127d74dfcce50bfe2787f01a1f62cb304cc7644754999 3f8e85317fc99b79ba87df971a91bbdd0af877a37228e8e78bc094fd441ae077 +654000 ad3da7c147ea7020a8854d4768937b46b2e9ddca13d786a2dbcda5fd691aa264 15baaddcb66534aaa738d7370796b82234bd7d1a183081ebd7f452a33254bb3c b0827747fa4b8eb0fed8ab0dfca523be4cf55bb6d96557e2cd9c5c844d4b2992 +654500 b38fc7f77f763e12c55c816230cb83453e513d7ffbc2f71cb18a4b970a30b6dc 8b8acdaea52986089352c0b17b8479def4e4e01d8f797609fce1c737e36f4314 bc8c0e523f860ac258ea93eb5e10ec62f9f2ca18eaa053cb02446fed76634eb1 +655000 58642d4240fc44829a1c5fb427e034890ca40c5097aaff77eadcce464be04701 11f24474492b2851fa79a42ff8d8685162e2b4dd1099722f3ce9ec4d5686cbfe 85d330044b1e65610ebba62ee60be75dbbe7dbdda61ede949847d790c44763cb +655500 d71e2ed94bdc78741559fb4c58bb944dde0adedc05e7558d7de6ab254c332fbe 7bbb488685c2ca7c84d98149d2383b157d88304c5b34aa7679ac24ad5c85b006 c504fc50c50248a50d4a94516c198cb7f74d6a1b4ff7f6f5fade4ac30e4807c4 +656000 c1d7426dcfe8733c72b8fae49fbbd127a6e257ccbe4120600f8454287ad26105 2f8f7af5f2ec8a3e0333cfafc069bdfca90b0ad6b99ca970b0f458bafb0dbc3b 67342b5de61484aeed62fdaa4377eb6df94b8fdc49756aad0a3ed6989475b5e0 +656500 c4f911e6a72381235e92a8c58ebf6fc654e35c3f5f4b2851f7f8a9ed3949e047 3d157f3d2c8158bf886bf994e549a6da2db2c092266c7050b831c8888d62b205 d20439a0b162598ebbf5671096b2532ec909b9a1644cb13a3c2f727087cfb59a +657000 da224ea959041cf5d98fa040a10ddd7a1904725a649ec84f2ca403a8117c7f5b 9b9b9bbc0221a24b8642fadd26c1157ce903d7be532aff91519f431e886f9ebf d4fd3b6288248e117b86a9f9274dede17ab390e22d2163870067b3e4d8d92d42 +657500 61cdb241ff295b25fa6a478eaa78f111e8d7ada328853b0af54bb1b20a2a427a 482b2e9a549491f90026f8e50ca10016dcc78e4c3d2064e9f730b23ca9520a2f 0a5db2f0e89291389e3f88013e6081cf19dbfee7217626326ee90f708d135b47 +658000 1c4498c323201e26bfb8a8955f29cdeb66cd43d6a2b2befb1da4a6c0647d1c53 931ef1f4868a3c5b54ef4354bfa791c3ffe15c02b3c704a6a281154e2f5be98f 62cf96eed491499f2f2a8e734efb3ebee4cca4491fa6ca8e57ca32db6ef2546e +658500 33dce694605303583aeadcaa80db0d8569ff712b588875d48edb395520a43981 6247bcba2c8883551a85e364e30b4104edb0318eee718e0317dc42f2a26c7451 c3c8ab5c1d3efb616f9e90d79cdb90009c8306c18a01bec6c83de9e0539eda38 +659000 339aa922137edb48aa37b841e956adee6c9222ae9bec106ed49ce5843b179681 ded7991d424229bf67cbf220dc2a5a5b223b571374f52d14bc9e83df72ea4753 dfb79abf0b25756f3b77e701a1612b433f44f18ad96e3aabe52dc4de4cb73206 +659500 38dddb9b6e5dad4ec1f95be3a83a156be12c5dd9d5e74a20bedee990b3f511fa 7815a077c5c8a265fd122b282139e3a13ef5951482f6d550a566ad74ec2db369 ccab21843b81bbbe14e77170588ea2b2f0d74b7c312ae5ef155fcaf844d07e34 +660000 5562a936684fa4976fade44cd5eaf6531bcc844027c9ca01e33516c0c87be6e6 0af9d5b94d513c095d2883a381746ff79e47d5179cc95165708ad37dd0615764 9b596d92042930a6c45911e3d8c837026a2d342c5d326c4fe3084f4e58511088 +660500 de362a2665571bb51834a5e8cf65cc0b436097d1a640ccb9666fb41ee1694713 b7b39581644d06d7672965e189c645b4396f4d50b223eed99080a122b22c2f1b 9dbee44c5fa617a8a911d2271446d5bbb614d5820c260b7605038f37ca0d7b82 +661000 7df5c95f34efbe842ac26e4252440f4f315b342bd66e74a3d1bc3c48ca0f3844 0a4f81f5017d079725470dd800ffe7e955bd82df18b6e8abc325165537ead1f7 4a11f1341ee66c1588979ed0721d87ea8729579c5a8752a6d756932bb38180cc +661500 dfa40eda9296e76deebe46ab09b9d581445d20814c44c42090766c0015162e53 88b577c05b1a5f27b2aec225732da967a44e30dbb463455bc7ed223bfdc76025 7b8df039fe4a7d90c694b545146afef89db880d378d0e20c45711a514008d959 +662000 7cd8f5daa828803f06d2ad8e7899d4993999d0ec37e8a37ec52555d1c64acd8b d0a6e4b8cc44620fbb80e061a949a8fcc371fd1f2a0b05138978d234a99fbc26 96040f6351e9a1dcd55787e4e2b20b912037f2024e86f5e708583c14b0d63940 +662500 057c9dcdeb7375f51cdedc28740c881bf6ae644ff17c0aeb77ed796e89db8672 c749272ba9509a09bdb7697c6197f132c1de0c58de5130e8c3257288be94da8e f8c160085e3a1d45ee033f8bcb723f059352995cfd90f96c619eb7fc3bd353c8 +663000 d9ceb13692d03610ff6e97eeb643407840e27d32c389404cd3cdd14733756dcd 05b1659e97dd91ccffdf180d8da3a35f6b2fceb9676091bd997ad363210e2f5b f5fc3da1820b598d7287f36a0f0e5e9d34e61d42bb8dda0cea45b86217ade9c1 +663500 cfe8d9435ad14423479546bd4d6d1e8dbdcd62a8214ab922402a86838a8fb3f0 cf68cef0e01bc5856468753c4df42bd16f3d33dd68783e012c1b012a3cfddc48 2e3b740dbf19349cd135c765330aab0d6060250d2b884bcc7fc7d28f9049b672 +664000 e18e31c640bf36f6cce981521fd55f42761fda24538dac34285fb02e69c427f2 f237c6c072f16f524d90aae138ec3a9176c2fa8f3049ac9ec009ecbb678e4f77 5984215039409092af394adfcf7eb210753971e61de048b0e626a2ee64415b53 +664500 2cc31198ec6c3fe6e286f01d98f097e19a5c23d3f478916414e83f201e724e19 1805da29e7f7e8dbb2b5aff1e712b3a447106db48671120732111884e0783b5c 66387d00229b4429c099eca4dcd9ceee1a889b38365d5b7454c9219e30bcb40a +665000 4b332fdeb19f5d2fc8108c233679e861bd40df746262d5412b8a6800f50ec073 b2119ba9b25aa2a5921c7aeba1759395795989824a5d6d204592d0ab6ee8ca12 76b874e1bedcd17be5ce3e206c8acb04123e83f94910717def66723ae8126633 +665500 3f0705d552dc4294997339d7015a4897e55790353236540c775e330c78cbb34a 9595abcff6a155b8b995057dc725cffc3b283086ca65a6213368073f7f5d2b34 c8118d69d2598bd2c6fb0ad7b57b1f859d441a090e152a4875691e0486dd506a +666000 df535e0c312494f9f1a288cc54b72779ec7ba745bac09f7b952191c5a904c56a a545eb072527dc053c0630dbd820c51a2c3a22510f31a389abf75294dfb34911 7dd43421d30bb27da111d5034dd3a6e104533fa5c0dc158ddbe17e79ea46d747 +666500 ce6966c65ae25a88bac2a35c95d1943c482febdf7f9c28efb57eacf2dfb9544e 4d6fbf4b0b9c493ac96d63f97dee48afd60c2c847f9aba07110791514b0f4e21 2f925e0f1db7403d712a85ec861255352dcebb1e770acb878eea6552358c778a +667000 e7a271b35d3fb008b6938cb618fc6f57032c92aa1e09fc50363cb181ca53e2cd 0f496a3a120f9644e6e3c5d371e6e01de4afc4a85f010306919bbef0aa323942 3a8150ef67e892d5ea237fcd135b0c903e03e1e0f087732dd7d8ae6ce25aa9cf +667500 783bafc58044919edecb6e3938f0ac69dcc75bfc220bfd8717d419091bd680d2 b22cef79cae030286f2fd4b62c409c6d9a801f65e377d66d455fd814628d5ac0 f438fe81453f186f7c1b1f43b7d906e489cea3f970352fa1da36236ddfb0b5bd +668000 beaea7bcbb6c4c3a18e0c9bcf6cee525f9036796157c8b4ce5748819c13c2967 a81cfb88c97c1489d9193801faacea720e98d21981856d121ffd5e75f7ab393b 55cbe60a2b86bd7c1b4e2e714b07f83e2438cd7ad63a8a27d26b2a01bb221056 +668500 393c647b49312eece8839452c0874a2e82aff7169a3a7e1e5326b1993a5d1af8 212bf73b67feff4a971dde4a00c12b32fe82859167687a3cfeeb03a93ccdc14e 9089b9443bdd360e32feda94a28ddc9e33cd427381a62602207f0fc97e5511b1 +669000 f24c2d105f11f385c356455d460f8b74d466885118dc0e1ece8bddf624cd5246 d91bbe1649788ea71e0574f15865868289b28651ab7e28455d823a515492ce0a adece8b6adf69980fb7c00f59598c1a43be400612cab0d9a67700342f9a9056d +669500 3dcf0b942af949fb37bdc61645d89efd6f72b13c02fac02a96ccf1375cf3cc21 81fdc3a3d66e72026b4bc01320881275584a05be5b0a5f8edbb2a6f334126024 5cdd39a3dd6d4911e9e6058ba1d0357937124cbd0f8ad2d60c1069b730d4660b +670000 e6d5cc2dd441d4b9f08b05a582c291a01927bd1a945f1a43557e3bc70cac59be c82d3be4f90e23836110348e66a9224cfe135ca4408363489f3296dcb8c33f2b 1e45718efa408302e479fbf9478f8158fb82b7445ae2a40b7c3de67e0cafc261 +670500 c420986426267474054b56073135491ad4381376c64dbba0c57deab84ef61846 b0c138c7e5b8bf286b3f5b6ad0a83fafa7ba68d499fea78553241e741a05d183 8a71746fd8b18bf6e792a4509813c920a3cf481d503cb8ae4cf1c6d3e637b586 +671000 d21e66d96e08adbb61bbdb75a7e8971ca9bd45a4906f3ce23dbd84c2e5e8d161 ba60c1936b7c35369e31e9fb6be2739cf60fc4685d210a209c4fbcf341d5c9f8 833810b0f9d5c89970991f55a0f07946d068ca8faafe5afd64d48d4a67f01d1a +671500 f7bb538d49e99ee06136105edfbd282e2f370d3f4f4c6d2f20b75938aca43040 9c1b787f1413f483e72003c0ca97831ef1e616b86fc3165423cc84e878d487b0 da656f45090a6bfb6bc6959639b25a1a26e0595ed00d554eabe1c5da8e727f20 +672000 8c85db8531cb0e6bde769d488b6c6a639f4839a819abe23ccf88f3756caa6089 598752609771c022cecd036a0b8aab8caf8fa3e64724dc20815a827b750daaa1 7c8d703d1655a7ee2462c82f78a4e0f2f8bdb370a6dff19f28d98f8b1cc839b5 +672500 efd3aacdf98aa1fc4fea20a2f4cdd9ea3eba6dbe03a63a149610d842793bc85e 93df0fed7bd2dfd8ca6293601d799ea9a54af7b0d45997c821e4a8a7ab7d1f9d 8337579b8d6bba63893d3aaafd5661b224a808aed129aaa36216f583e29832b5 +673000 3109a32670b3c1a796f9c6cdf5f3744848e8ac3ef0ee2ea891fac0eb69223ae2 baa8971d22821acd1fee4649f702edc70cf1b072517f4b69d6bf4060cefa34cc fe51c93dc781185d8a9fc3efe07271096264f598616d69407d0d85ba17ec633d +673500 8064bdf0c36a535d5d7788f901ac0713b627e2f8b80c4b20d26cee0daf02ee6c 5548c9d616e98ed4fcccb300d3e35a78d66e61aa95c6465fc66a98c1e40405c2 b5aa467ee5592fa80eef3af90b239407d7e31fa4c6cef603ef50598548666cd1 +674000 b409ec86b27b1a828acc7f056dcece326a7892314cc5b0d6682d21c06d4e4cc5 a25e0ee6404f9db371913c15348e3aa8a9ad4b3cd99cca3fbf1e8f95b6e152dd 5d62ac697208e75078a5f465f2feda182ad6a988ce953ff4909ecad0feb96e0d +674500 0c8142e02a8e0cc1667a81f4c4d08ab7577102481f73d31b9d8c67589874e970 0e31001e8d410c86f7a525b201f135bf6902048a0a4a25d3f283b2b1ca9e0b63 ae1ef0b9fa438940e44e4804ba785686e04250c675fd4bdb76b927156bfeb9ff +675000 f200a64f03ed78fdfb3a35be9133cc144cb7621be76f0a470a6cc451d31de7d6 2dec2d8e6cbe5d122786b9c571751d54ba1d597e23dd4aa03ebc50212c68cf8b f841d17cfcbc629ee12bda00e988164571dd7a3b8f9c68951620a62f378050ab +675500 44927533602536ec6857a62ddd2e7ca31a05c733cd0699a078c5106620da51f3 989564e602ccbd682fcf993e4ca7691f049bb6adcb099860f9577a83cbe436bf 997061d34d9e259b99c7911924177d59e78f2c86d0a57743e5ca07c1f1495ad2 +676000 1349301af96fd291f3f6cac4d6a6a94779a2015ee9d63989d79c813e7bf3ec81 c196991fb4a511513fcdd4300dad73d556daf8eaaea1411a5c4b0d0382e96d45 e332be471e67a22109327b11ee3002dd4d151fcc0ea5355d6189e3529bedba04 +676500 7a7071dae50a8ee6f25b289f3e9d15d53661469e5379b56278f391381f2b5ce3 918295a1444f694e137f7f9653f87f1863884241462386fffd0037927c3779c1 748aef72e32a43e6a0c050dbb046d7cf06a095fda95ef0da741e704337667525 +677000 a816938aabe21e8efc9c41ccbe0e7de2188e0bdb3635541e05b9cc8e61ed3dec d59c6134dc9539b3cc6aaff9870b30ba12676fadafe95167bf90bda3f074bdde 30ddfafa528aa4ed1e213e7ee40c5a1d10dbb5c2b8aa5d4a980c02c6b16f717d +677500 d06ed31f2f1a7dee027e76fd419c93a2c80824f31e5b0bf09e85e10362cdfa8e 30baa2fa7e5834e442e8445c81d124018eec1ecaaeea695d4278263ae60ef134 821a14af37286851070ca1113303366d270a1f2a492fab4e70da8a65092ad2be +678000 356bc1b553016f0a17399fc531e9d5a86bb273ef944843e8aca16d16480f1e1c 74c26fdb3397f25f794bb15595b8807b7d4a4500ddc941e7461bb106a69daa62 274c911f767c18dd29f34d01a8ef4d35d2fd39b5935f054f287f98674741d69f +678500 e7f83fbb9fef902caa5ad499746100c3422842f793424bb2b17f9431b0a3b6ce 5177927957f3b258bec01be88d817c262ee5a64cee44e04b6d78b5f227e44442 4332c38deeb9febf6fdd3a3b9641b7dd8da1e7f7b870604cec9ffc4470549394 +679000 1ced7af5a996a7028c63fe45238dda8c540295b48d082cc278614f68dae0e249 cbc8a6d5c9ec62bd0d50ddb90e7e1efc4b62dfef8d7aede6279ad95186497f7c 2e75ec964a78a7800b7eab5ff9cffc0937e157ed47e3ca60f24d6e200e085201 +679500 a00fef7924aae620536c387899d8628d4eac6fb45bb1954447e2de6a4fdb2ab9 69b47a27d041a54b0be2406df7be07f3fbecfafc0d58407a7946bbfb0f65cec9 54a2dd370abf726f06c0fb38f50a2ced851955467d7e935101bd3f8b092799ed +680000 76831117aae716df313e1e7af8c4c8076e2b7d37bd7239c827962cf903afdb55 0ba660526d75f5b1765967a87119f6bb67d33a496e23b13e58335e960610b38e 95cd680073e4611d1f8eeb66fa540ad018f933cb2a943e533d4f352520ea7d25 +680500 17835aef913aa41dfe7a49e91fa7bdd85411356233f5cdda375771706b5a4e5a b88eeb3ef96d4ce4adf49b87f88a5c835bdf4ff88aa3a45bc46d2970a14533fd d145a5ef679bf4a4142614e122e5128852b20271e4cc77dfa4db939f4e2c7791 +681000 86ca3bca8de152e4ddd4ac3171ed463466dc040afc5e2f38eafb7fd0ce49dbdf 55a9a5b5ed90ef00ce658b5fe52373ec23b37e7ae1c477decf0e8a41326cad7f 780df69883c475d6c0eef972e319d1fa9e4b6c9e29b6f11008857f0be445f7ed +681500 5b31112aa2d9b190844d109c44f8a4845bcb0f75e567055bc1368bfbae9bd427 9b695ac5b41310d05f09d0e5265f53b4ff475b10d2b0e27928d81543857a1f0b 3aa9c40fcd4aa12184b3d201806a0437f23c0976423e576223f6c891144916ec +682000 0f036f94ee9dccdbb0ccfd4dc10663890af3c2b7da67321baf4919f8da0ef388 a9d70e8df288e875c0361d7273ff846b54dbdae0d6d6459831e71ea4a41397fa b38c91a8d98c4586676c2aec47cdaf95e9bd7b8d752bd41f289df6b89b44f5fc +682500 18658069c688414684b22ffe62a7e4d9b84b3f27c28351b57c8c5763aee40ac8 c4ec9845b905ddf71c374d400faeaa649ba8b08751f0a5c6b9780d4c7d497fee 87b2f2714cc9131438ef6de56a30fee9f1639269aad00ede70c922c67ed519ab +683000 ab2a4002ccfc546d80417f9c1c66dca34d8de7df714fbcd4eee134659c6b4261 5bccf1dbe0d677d06768a02a5bb6fadf5deb0075582a97e4524e2128a4fa4363 675687d470bf255c4244f6e78d4d70e7fbbf5c58a0caa7f998f2e186179bedc9 +683500 5b302ac27ba940456860fa752bdeb27a3c8494c1fec08578c6d204588ae18420 ae3de94a6481c28aca678f115b73c830ecbd163fd2e11a9d85b2c3132911c3cd 77d7f359371b5ae66ecea9019507163255c1744f3aaaab043096e5856fd1dc27 +684000 15fc8d38546017ea2ae0e0b4387d74bf702a396b52cccfa879bec7c415a164b0 9a6e35b63f814b6837bf67d897103f320a25e5cb15dee8e5524d9961f53368d8 463822c866010eebfc3f7fb3d71bda605c22e62a78d00aebe68c1980454ac87d +684500 e40472171e3915e9518f1646a3ca09a46154b226443848605a4d8c78803c90d3 2c7e33f27973f6345dac95862d63006b4b1506d5979f60d8c52fec12b74a1b78 506e99d0e80bb6429b76bb4cf9f33e7d97d6b40ce4459480b1797952c1347a89 +685000 742e161c4d772ed9ab9b2aa95ab7dd4646e7fa71a7b71d0062120791fff3d538 7854ab499956e6893c2679a3393fb30e450f2cda76cfbf08bb3e77b586b10599 95c2ebb16170b750592bdd409dda3ca05fbd9afc895d6bb9dc4ceb249a146864 +685500 697224d799e123de9da2b93aaf6a3f00ddd507080eca2357c7cde1ed1ae8f189 1b02e1bbb85f1e71e1a1bd1e58e4eca588997cddc1f545ee293b17267fe5fa50 fd0d4596fdcfcce21bf7a49e3207a478679656f202d54f3244d8803a70e2e110 +686000 7a7fffd9aa90d0d9e7309ccc0e450c7544dde058085bf4bfc9efde0cf8fc7b3c fd10b3c2c0539bc586cda1dbdc454a1597f4acbfc1d9e7e7b472e2d3547c76a3 eae66bdb96a86e3fcc78a9cf04d23120bf80908c41a188a26dfb0b9b26a6a6f6 +686500 3dc10029047449d4411fbefe15a7f25864007511102972f14697dadfb914d5d0 8064a285a9ebb460f864525434c5bfd94ea7c437f67c9eb6268c3f3e4737b798 b81d605dd67e0b7694f979043719ee9b5411be3bc6fa73ab1ed224cefdf4ac90 +687000 2e2c774dfd40cd18616a82d3e5769d4f447a2eb5214bd8783a5084cb8ab38e20 52379664d91e53a60d1b1a4d64ae2005e6549972c45af11ef2ecf2f2faf82ba3 2ec94fed8848b9b2e94ad24271c6e87c223f85d092755cb9b3dd2eb75cf58186 +687500 295e12eaca70c7eaafb7cd25efb6b461f5aca68665832ab9eb652e6fe476d809 43763991b8beebed72f3b7215ee72a2f074daa83a27c8db1decca52bbfca7b15 30007826e0b6d9e775b8c9743c2d8fa70ec45190ec1269b0f6c10b3bdeee32e5 +688000 88efc791202d8e4a0266dc8114487847252ff2497c022ff4ac237aabc6602406 560346aa44e4afaf2fa9a4e1506534bce8c0e113efe4b19c6aa26804b405bb11 ed8e66e7265bf0879d5e0a656eaf6151281760412b6263bf0c5802973b535dd4 +688500 8bde3d0d7f23d76ffb10e59c43a9a2cd4121c3f5033204c4689fe77b860d616e fbc4d97609351dc9fcc8f4e08b5a0c79624c9e81989b684e219245878ec2fed1 eba83125c427d7e7953d6e91b82344841b5c59a441310b893011741f00165790 +689000 01a706323f362664abca40cfecb4c6efa65aece3270fb1240e238f1e93ea3ca1 e4672adb018af124ae848405442ca5e255ff9af3909d258bba12d29f3aecfae8 2b3e46e498f4c7befa001bb3d16d177feaed83f08a83302e1b46f0761a45e297 +689500 3d25b5834362be1296b92448e3d2ece79f8017708479f56d7e28d602817c82f8 643b9f9b0a754b768ff504c9941c627627b49aecbe170a72590179536840b843 d9fc0a70fae6a96ff522389fa7855c171f3daa166e60dc39ac2eaf861b9ce170 +690000 0e622f16da74d548cc9e49c20d072a9a8a6bf45dfd793830fd25369adca29bc9 fcc1d77406d58f3e1e5630871011b389449597e41f1df035518c1e25affcdc9c ea81179b8d0250b07cc04be0c567b863d5f693f5068562428d93b09d87662c45 +690500 d96ee19654c250c20011f56dff3850e61b9b01a8c3be009b93c0f53c79d6ad5e d3b6058792062983ed59720fa58ca7cafc890e475e2411a01331a4e3e8ddc580 bf7073645256ba35b58c48af2a0a1da2fdee8539ec0670c64573c791a6a29d9d +691000 0e02a80970060ff139ed4ce0a83bf5221895d80de69da89bccfd720da52793a0 20279d4dcc8aaf7a83a59d70cbfdc4c51e8d034467a956cf012349dc01d875ea 92bc507ac9395231f1c4387f393428b47f03d79f1cdfa44c0d04543dab744ec9 +691500 6bbc975ee40102521ac8b041e481797c83174c5f2b5fceaf3090895a6301f42a 4ba322db9723202338d5c0e46427fdcf24c8631f53f3db590489cf5cd74311bf 65216ec91cf0206711d495b52d5bdfe54516c33d5c5a3768b67b5246f52da328 +692000 a36c0ce45bdbfbcd02fe25ec7c199be6e01f6edd8e5095dd745b136e1a1956ed 65fb3e0023b45c838637825b0e95f461b02f90134e875d85ca8f084bd30d3eda f71487796ea260abc5d1356e178faf08b6f91a8f537fe2d0ade5537b43dc162d +692500 2f8577c57b15cf8c176873a546e1451b379f4e09967643452a37b037b538a0e6 b15ca73e362e6394166b6e104ac474d1f73d4fe671117a77ad3f9786ee35488d bebeefd2b5f2fc70448c02171877b83acc0882d38a5714c4fac4ca3e0728cbf5 +693000 634e96cae2b7253783b3ba6dc65bbf79ad87782a46f07a11ca8c3b2325e2d2aa 08db37defef7bf06dd75f2d8e4f8d1be0f2004d24e816a71ffa4fee43fb5153d e14c7fb41dc5c08b49848f994278fd52b1a64eaacc6095e16b089862e0c0cfac +693500 c472b7da4a1d6e9a9728e58dbabfdea31af58c18a17e79e3dcade6d96efdb689 021ef6717375d52d4e02c36bd8757c6c73b77c97bf3bb4d6292cec23afc3c8ec cfe39e0052abc482f2bef739131cdacd79582c952cf1a18f18b822bd2a3412a9 +694000 8d5000ca461da1bf1687fc3ee92e3a1b414a92737d82e301895d6cf41e0e4cf9 e2e6ad6d2a58ee8538e7dd8136587a612c39ac281fc3e6bf609b1c497d9e331e a341bcb67f9c01c7cfc99d09e5e8e0ce74d44603c48af064d508726c0083e901 +694500 daf014e18bd15e7a19ac859acd668aa28bae8fac71079e0b8285c25fd28a46d4 9a671a25ba774c600b2f967a1632561ab4ebbfc4b4016979aa9288af8be93065 61c76269727aa28aa7e21471a6894b778e28807559713ad41f6b832aed7d9a78 +695000 f0d64ffc15600b2a53e5b9f09f1a0f981273e1cff39f01bb69a3c27fbe679c71 d5adc8baacd5fc0635fe0ac739a16893fe0c4215655ba111f49e3c709f0d1faa 46f19a5bf4e7a9a77cc966982ea6f0d54e06670471faf8bb9a3b0e272d1498d6 +695500 d784ac30db59c0e5e8906f2211b6405356158cf57af758b047445926e8dc140d 7d0c9248ce3387940358e82c01b7accebe7d3445fe97f6569b0a99a1a4822b61 fab42a73d154f8f6dd6662f9c8b72919fcca0951d582a296eb48f6b6273037f3 +696000 16e6034f4089c38e9eb2a11669e4d5b896b4e36e767626bb4c2cb852031099ae 5f54a918561ebc4c21c27b793cee698c347e8dbfa49ce72f4580ad7d3e464a91 0f024cdcaf10c1503193c4a4e6976507f46eeb34974358191087c8690574bf55 +696500 bde4528da57c22025db1123e7fdf3e58f020015b1b500be5d2ea13be8f4f50fd 954600e88d55d507e82333a0b9b36f5bfd5da128e5dfe721ea486a117f196e51 6d65c68aeb31a3b4f823b9ceb46fcd48f93e0e279cd91158124dd4e4b6fa697b +697000 eea7b9418887e6bfe3a460b03f30f800672d8df94217fab7d1e7a74f437ebd50 a210a2e4efac6617e3df43fd4219eee8e4a9dbf05e4cf103cdc9f39e162d61dd dc2d1c8baa899d025878d103d902be6f2ce14b2a1f46bb3bfad94f13fb2cf3e4 +697500 af96502823fad0e9693d94bc707b04d59d3f42fb27a12134f1aa0a863ca616cd 8cc57e73164f446606d37223429ba5a37d92d1ab52265fef43c81d8f5d9756ff 7c22bda98d112e24cbcc50d7e6c71892d47ec18dd658f28686f58d7765ca7bc4 +698000 8a0878bcd828268633df687a5405b2b86051640a122f616231d8d6146d4c2ab2 27a9f143cdcb85bc01f31868f92a964337c451cd1a546f93c29361f245aff07c dacf575151c578d5b0f283296f31337bd7a1b976607fd492dfb0a88e0411b9ce +698500 afbb603de0da6476915e14cf182c6c785ec6514b17d9ba7bfa74e5a228f6d8e6 f730e6ed2ef1334071ce63f9ac851de557383c98b40a72f8bdfb29c49bb7d571 70863c81dcc8cc482907c82781ebee38697b9c01791ee71132212a49ee4cc875 +699000 4e3bcab244d1ec2528890ed24340027a9add680ccac038c42e9a5b4880368a57 1b7062e806e70df560b7dd19713440125dbf814412ff713c5bafc8776c443a60 7caf82dc9c49db7c7baf08b8863b2577aeb18da4679d6a26ebfb620b94b32fe1 +699500 69c03ffa655f439caaa38a36031f45c27f6afa345fd8d380064ac4106a47b9d6 0522b34e7ce87f078124a74b1f26e25c44cda27ab10ca9884d777a91cff19df9 770d8310ba9272994252c5df67d39d32018ed69a29cd7cf734a9e8458412f476 +700000 19c87f86c5d859f1d4ba642097f626a5c6cc8420f1b438ef0ddfc52d77b5a7ce e7cef1ed642d40f49563c66d9428c699a66241a86d05aba5cb6fc6d6218317a6 0c8c3f94794122eb5e615582ac97d2bec3b09ea1c5262861c7d7c4db6734d2a6 +700500 c22be0aa764d1e0d90432e726ecb95a769d691a7de81ea480c1bb9e74f43bd8b b0c38cfcda8312393e4906e1068c7a323defc33624e99c8c8f918771010a417f 422cc5c68ef275f1f6d93266cce5c9fde6c342e1ca44a94f39c3555ed4059759 +701000 b2505b0ce33e22fc06044bc95bcf1bcea363d91c541451ba7ebbb07079c9b8e6 36066185fdc8a919096d36245786b921b24ea4b9ad0949d3685c7d54fd3faeed b8821bed4a54d18bfa8803cbc988a6328ffe601f98282b71ae2ae265c57de22d +701500 11c69ac149f239f122c309f5c7c8c08ae9ed95e563e6e5ebc0db4d49628972d2 52282de896ddb2f1cc56c22ec74637395d1c2ff49508e903cf4ef1f5c01a1da1 be400f9771c269879c127f664b0942276cf7768a1da841f8100d9f9c008f29e4 +702000 73e7769b7982c2e9be15c6d3b0156680f7705c802452205d64a5d66187de5008 623290f47a7ec8b202b95f45d5c6408072766e49439c1aed29f023bd79a8e1d0 658bd4418ebc07af0c511bc5f99c029d23d6786cda4c1d6f16e3f23c61fbbeb0 +702500 cd7f69f08cba82026873f72e8709cffc89a4bfe3c5300231a180fe4e7335e87a 4f1bd226f6b1bc4313e7618f03e4522da41509937f596a3728da2310deecf49c 364f12a79c19d5d7f2ce28ca42e34ad435f0f73a5c0f20eca5567f56ef0454c5 +703000 6253ae1e6bcfdba8257a18760dbd8f42bdfedce3257b9cff76660667e29e5e20 05134bea7f58be79fbc3942bff929fef977a42b5bce28e787bdf2bbc1bc70764 f51a6b93287a28af8cab3eabe6168ce93f9c2237ad556d3460874bd6a0c99dba +703500 affc08445fc42e60d11152790408c66118b2a815647640a3eabc3006e0f58f8f 34c74888ee86d1759127612373b099f56c53bdba1b0fbabb0a7ec61eb0f24ef7 e691493935a99f1250c1d6c63be39aa71b0f92be49c7281ef5d9f95ace106ba9 +704000 5298b2ba05735ba586e9f6aeaad350fe88b762d00c4551d6b02f6c0b706b0f34 9a36354d1266eb50f84338359401e91aad336d97cbfc39d574a83fbb4aa11d67 d6ac796bb0fd95a710f0895b3373d11e0c20dbfc4c30182821df72841345b73b +704500 f674bfadd8d412cffe1c8d6fedeb91e9c8914c3280414896f97e1c08e05b53b5 6e593d4f49588dc6a68b5adbf870674cd17037cf7431f34253eb6cde06364421 2aac262167b4696b70805dace94450148de9d8b38c1fb335a8f24074f6b24899 +705000 d288536328fe3b3301de1ba97c0237dcd740f225f4df07e923bb570f68716604 b918a47fe346fbb9958ebff0e557b9febde26c435ff6320858bdeaa09ed0eb60 0748bc47d6824e6078bca751e7e1ab4f8ee1ea090fa714dc177060f217ba1066 +705500 bffd8b226418632ef3a9f71f473093e5592f446776db14fec222f85de068c840 e889bcd01a761d5208221642a51bb1d0afb1f324f74914590242204164287740 b5d68b7d55cd34164b0a82778936cec4c44ba1734d282515b93eabd0d1870085 +706000 2547d907a333fdebec0140593814d90a1d806ee539598cf0672cc30a1d5c31d6 77323ead475140b2224eb35de6da439d3832a091f1ca17e53a885d0b4d469105 7bb1897ef463a29cd8fa71160e3548715453b2e75262cae48634a5d8ae5e7a23 +706500 5625e44c5204f1d9d3cb4b5b55aaa18f13be66ec9f76988159a172713f141fa2 31a50d4821509dd711e9a541a3c54e28aad4bd6c6314526ba82e64857f52f4aa 391dc850fbc3760fd29cfb5182c2fd2da847b2ab00fc95b890b659386878e632 +707000 e15531acfd422b5932479ecfe5dbec51af4e824298c73658bd43c143958a70b6 e9af02a4dbfa950c0a45fe96162bf991f65df101072db521b4631ba7e64ad248 122d80446848d02cb0c41f3c774e9476694ed3d6aee605a5d155957191f309b2 +707500 904129b3e99e06b3a75bb2b903b65b1176d82601355b13c92dfd2551edeea6e3 4e5bdefe9ac9916fa5ba321a6056ec1bc8fa32ce3370587f13bed12c32976b71 a89c430927f04d1935f0c5babe97cc0c5708b205a843803bc1a3fa9472d5cf5e +708000 23cd48d83d0bc7e5b80c8a337389801ef9bd5584097667310342d92beafbabe7 e916d2f42c77692bf97058ded798c541ce883f69786596ad94a22108adc17694 e76a76c39fa7423dc5d93fbf49593bb5205d8b4d6c1e26d42d596f2ee90a451d +708500 2f58264be757741e695394b348381a9ae8fd583341791a84d68d338cd811ae39 dafed9faf74c750eedfc2e65491b75d4bae7d13b9e082e6fa91376c2d6034da9 a01f735cccfc8003ae24b4dbfa89385a73bd68348410927d2ff7871863523868 +709000 e55588bd39fc8e754f2b272f80ac86b5515bad37eeeac6fc3dc0d1179fd53423 69815269b65b334aa89cfca70ebf71dce7de046cc84b68f0f9c462da718cc469 fb38f0c1e62aad790786497bd1cc083a3214baa52977ede6ceadab3b15e44249 +709500 e30d4db49a196e4ae4502c992118f37ddd6da696f296413500ce20b4b9838497 4cdf69b6c9515176894db3bb5ead92d5ea1772d53717224656242e8007552228 6d30ed16ebfd3de5f0e740adf51b7abc43bdf106916001bfb7e62ee5225a21d8 +710000 6f141473cc79d5def23f888471ff143ab546b5b1d1d5fd1fe51c996674e3018d 5af180a3caf0ca42e0ba20e959495120693f273201de65aec15993cca37cbd2b b4103cd60381eaa47b921e47afa9080e02306159cf1766107b5c73e64e0c5715 +710500 10d11c0d1dc7316a7bc8a99b685c0b12c9e2bbec941d3c33781059c7048ab022 541f760b8b3ed77398d5b5193220799c84f36e5cf342256921661f6d6fee0316 2ca42896757f6e84ed6f2db42582eb9bfce4e21f5d2148b7d18a12a1f8a3265d +711000 dd068ba9611f623d9e761f5e6a10b0298130c8b25317f047b6a4e79a3360909e 920987e93062ef5eebcfeb0a98ff5b108649f1a092f76cad1c7d09b276469f80 3be52dfa74fa750a4e97632d4a6862d859d6f72a2185626748c81290784bc4ca +711500 96778f4ce3094a1c3323e3afd658b20cff90b2aa7f23d886a5f5629704f5726d 9f4d8c3657fbcdf2375c92f6f7e700f8f108a1a5df22468685782c897b15865a b4be160bd18cc35c6b4a9d14008bfdca143ab1f9ef58f8a744ee7f5551687864 +712000 f4414c743e2b4f89177f92e0e11d61e9f3b1669d3ddd6148b3915862dd2b87b0 df705fe65a056478cc8c914ead67c0a9b6023fcecb68dc7d9ec56a8c6ea1b865 1d77d1875c2fff9bf63f833455e2db0a63337357ddeef49f50d9dfa9534831a6 +712500 fba950fc02bb67da1c4de9b6805b7bcfc0cf7e2bfff478568be99a70596267ac dc357d74f8f524808f3f41d6604d74a8a96c6bb87f695a15ad835abcc6669be0 259ac2dbd6e8e2972ec7393e876b26818d1b0d8aeb44e6672c3e49cce19d1052 +713000 ff4dd851417240d00e594ee5fb5408372e4fd5585bb5ebf3d73a97dce1f4c41f b54673e8a2bd6d75e2218fecd8d20c0bff1b231b80fedc53b3f1deefc7fe4747 f63d43982f24de8b83ab1d3837c6b7774137ce48f15915f0a7aaf6543847b258 +713500 92e49d6caa2cdfde8ec7d8c37ae12d995b9552c76f7c7ba0abacb77b02bdb5c8 4c7b0f7d4f28c7c4d35a29c0a74310b38789decd628308c72a5a270a66ae55ba 695ab5232e19bb40c61da6ac310de6020d1118c197032762b466f132e15bd1af +714000 dc8dfa5b910afe73d3558be9d077fa57f1b6ac42e058227cd73b1b1cc0c70231 9ccbffeff96630cd9248b3001d7ec7ccc83c9daa5351bafbdefd8a88c03f3224 0031da42727b6f35ee4655ca10e454b4cbae45c43809098d870d14b6d9a8739c +714500 e172274b228f5e4f49167f7d36076f71db89acf666b9e519da3a33c548515826 14e35bb2ffc296d0d1f30be89e8a66f0bc7ade63250bd68043acf98dc625c91e b33ea3c9fcb3941d3783924ac3430b384a13e725e698be744396fb3e30632a7a +715000 a9b83db90d65b2e1db885b5b708f1d7203019a7073ca3e5310ed4dfe19bb9d61 1e2fea7d862a4b98f558f07e35d23b1d229dcbe2047a58f7bcec840147dae863 44cc59497c3c6af33eedf74daba3925d8ffb15d32ab42fb97bba51511b227fd6 +715500 969fa24302ef22b2bea25b3f981fbb756f3de84f841d6f73ad9d6a6bbf463fc0 31872cd93e38c92acd7b1af2ca83b7ddbc9319dd8606725fe0aa2b50026d98aa f6f41e6dabf4a38f8ab1df628df7d3cbbf10a40f7408bb54a74729e1c21f390f +716000 e33babb3b3269852ab03a5044a595312e1828dc11169020fa2a05f4ab329ac15 129a208db82ccf3418d94c00f39f3eb81bb7ebbe901f2a698362be4fa1f6e7cc 4af118880519c0d6d340c1f491c3f83c8e5e35ff9dc64b6608c4e090d0aae0ac +716500 9c0cd626f57ca90c771b00015658c387466c2f3d462d36d9fd3622abec903b1b 044c3a4459440fa9078eb26f15d114c6ef9d63bc5b8640f84289a1f376b4b85c e8739d4d29d69754256bf748347fbd85f66714d772fbfdad9539fc14a761f11e +717000 77a31d517bfcc769f64d0de88617d62d4d433c1d1a3136962eb07baa5f227a86 e1f060643884a9ede876b52b38690ccca9c9d94140470024d2f825f4307dc918 cb8be832b1d59378ba62a3ee348b044b60a74c8cf4a7edebff236530a589d5f0 +717500 546d0c517b9b0c5910d4d7337c366d76c7d99be4b875f673cf3876ca5458cddb 814a3c25d78419214f5645a68ca361b0199b58ba3fd3109817b585cde74503d1 1a3552275af0b42cfcf5250b893bd46b266ebf45a74aa5397f99f92c9f99b7cb +718000 7e44714aea5af5ac9195904d29c9d53d03fca15e00e0f2c1a071611b6fd03011 38d5d155e5a9992a6e9c1423f0ee621f19173c533e6954a46258e02982b89a02 135d0b0ab3e42a885cc0ff7e579455fb52054127b4b6b46ed4fe32b871e2b4e2 +718500 dabb2702316c8e8043539190a1581ecb881dfdb7502a517fa183815a012eb344 268c57e30e191d41a2793ad6b70796829bfe2726aacb3864283e82e384eea0df 22dd681a53aa2818e3956d37d5be7589582b5d850211ea6ae5e539b003e24b22 +719000 9db785b29f04f274688856f0858c7c63961a6aec5788a94bc1aeaf483dcbbfa7 8addd23f1cf6b051fc6bcd5558893366fa7a54ed89deba74d79f7a307c5224bc 7cb536f13dc79ae18c11e9240142e7577142a4b1f474fdb45941d91a7be4a4d5 +719500 4615a7726a6b3b00fe5a9cc53fc916af6402871508fdc9b9f6e5799083edf0db 3d3702be96cdabe826e24dd724ecfc426024a693c161889d0b41275cd6130d19 087027216c909231bc86b0b4db03ceb66674212d63be60175b834599dc49a834 +720000 6b70419e1023a8dd272910d32c30aa0617bef67234063aa6e7447aae5356fe34 55f7d559d3733e4d3d6b5c3c68265e088eeb6d2892671e88e9567f238268925c 92e88488be2bc52dc5a5f775bfb82c388630a19e7a5238d47c119a8fdbe2cae4 +720500 473da49304fdf70d4b5adadf6fcab3f0c332ab5ffe82972dffac6b14aa20f23c 3de3c3ceb92f8a7f45fc19ccf72f79f2fb8d3bc61654c534f81df978e905a3a5 3610f4b330e9ba1898d98a64dbaca5d63071e971623431b2a1e873c31c733474 +721000 c293a009462b561ea37ba8614559acaa63cb6291673c68082a6e4691ab0eea86 ea34bdfab3e2a7087605df85d858866b54b4ab1acd86619e99f6283a99f7ad67 4d87009034cbef9f17d7ba20023efa90676fa62f3bd397ddc9e2a00e3b66a498 +721500 a15ef2603cf7a7b0ebec81fe4abbc6035183755a08fa11604e40c95477d61812 6aeba98a3c5083b997eca56cd003e7f0285963bcb8502f73f2994dc04492c35d e89cf0c9fea734cb385b7dbc8af311bf26ca4564c58f338c52f8f0b5afcf130c +722000 39271600011dc5e938c1308fc8f467fa44145f8bbc5335f24719d125dc92f664 bb0387e362d72388584708287f86c92ae50f7ba4330c9857b308837d150906fa dfe30371d170807cd3e31ac464d3e284026235f2043a8a9d5bed5545e9595fb8 +722500 d7f846f9e439702e48044fe02c689990aa0a56613fced844d989816e0317be80 f9308f9c0bb63c44b443473a8a25777e34d9a0e903edcd33598b270f0d7e9036 2333a3407fb1d80d66bb3655b2ae3e64e04e8099ab1a0c37235b106e74792f12 +723000 6fafd8c865b3d0bb05f18cac70fb93007cff223789fb46958b55a205ffbbc959 cdc9d13b0b9a5fa827d2572e9c3232f498e8b06ed8627199c61db9525469fcdf 2bf56e3e72f5c449653b64c5568cf6dec1602888a9e77631b68b814e5268d29d +723500 6ed55084a271a39809b6f3455a08d082fb7c56ad97427307ec207135c7c16ef3 cd4a3d7e1dc9e293cecbcf14b969480c0c2f277819e9eb2286d1761df7320694 a0ce856d8b19fa250998213ddce8e945e25238617d9632b1345fc257bbbfcf4b +724000 c1b649d3101d61bfe8b949f443e1035a3d5944310f83e94785592c4cc91552c7 452655726058f019fcf400a89e464688ba4bd0fcf267493e54748b146c7dbe1a c21245ea304822f3c688f672f6068b2c67de6c3f2658a9e9cf7a509cc190c489 +724500 21f5f4bc2fbfbfff183a3eaa110c1e3f826eae2f58d32242919026a8d1ea6206 27b9e765e888343c7180fa9b5066ea254d8b5765b2d7e4a51ec62a8ecf02c6ea c681b8a5fc3f74d6349426ef2f01340c85c28bb4fc8857fb74d284e6b3bcdd75 +725000 5db006a94bfe731764372f332c2b23f9863f7741c0aacc4d92769f353cb4a4d3 db57165deffffe98c3cfe7b95e119d0253a6e984d11fc2b1894ba4bb3010301b 93b86dfe0990138a22c323a851c26bdbc1ae9d2c71b7db6468afbe0052c96799 +725500 f313538888a7b2cbf72adfff7c6aac1583c44b477c27810920835e1f36104ec8 c811a4d09b2afb0e9e70bc9416e58aa2c3dfa4955ec4ecf03b3db9b65450e858 2a5cb9561d2f20edc69cc6010ad5ca11a07d77403c5f090e404bb65a879d3e29 +726000 f9f289b08641492431e4ff87acb944092bb1fd4ae405569e0f3f14e433aecc79 5c10e47957ac47afc2bd4fc6daa0c7e30f127f0ebdeb1b52149756d9f996eb76 770901cce9162461c95f8f5506586075d2e0b19b82f94eb83bebeb8733146728 +726500 769de3f5c47b72bb76aabcd88f8c84595015f6f3f8d78b4d4a0df2be171faf31 12f1f3f363f1cfe762d972b988ba7e0943520065bcafadfeda1cd73aad8c2aec b38726eb05623a3e08a3015a53ceb5de482da78b04c14de040f543cef35c2650 +727000 2d757e0b21cd7f64dc962c5ef6a7268d0e0223814f74e6fff9c81f849e496ded 3ef2c4f48504f065f4efc06814674b635ff6d31e9b667f9b1ad864819804f446 7f02f5fe584df7843a2d2590e3a1539fcd8c8cabfcf9b196fa686e2263e50e12 +727500 5b2875cc1b107110464a44d7d9a1835e8c19246cc4d646402fd3bfacd53b7201 48695a64b57a8523e285989dc5bca5360df44847a66d926c154c6929e92608a3 5205580f5bfcee12d6d83696744f906c044a5ef6f2e15e45840eae9bac331622 +728000 35fb3c9e4fb0a40ebced7b7d2e9bae928790bac78a8460c311b99e70cb109c9b 758fc72831974d7f37e9307b34f80de04f3ceebebfc97c79eae5e1dabcf2374d 32a4d80985277ea290d1299ccd4b5701d8b809e6b3dcb2c401cd66f75079fded +728500 156a06f3bbea42cebe61c148aa7ac4cdfebf95edde5d021c03a90ddaabffd20d 6b170063e91dfa3d05c9d6edf71577d85a9e3f0ef734b7376f757d1bd5a42705 2d46a53620e7d1d09d96f753cda4aa6de2300f05c4d6b2f5fadc3220fefc9bec +729000 e8771ec45982e5e9928539d0f4f398b3a35f02b92f44ff6937e6a6a50fdf4100 bba9a535cc36db2ca8af73b8707635e3c12b3125b320df91257a944ea3a6af8d c0d1699b8d4e8fe005dcf224e460dab44bb1f6393036f0a9e7bdaf3c740d655f +729500 e17e17e50ead400f5dcb3f3ffec5a1ff95da211a7f6d30f87399cb034b2fed00 0263cf2e76899d4424125c726396ca7c8c3f1830eef290b084bc67aa3dff7ea3 17725208b4e351c91f043dc00ce64fc4882b12bc2f84c793cddbaba08d27e845 +730000 06ee01124cc2d7e6ef4f764638700ae11ca26a457317564df6e5e7f0d881ba4c f20e5e74a5a07e05fbea7bdbc73ad393bc83a144a7e15d03a096f052d7065eff 0ea35c2865b1b0dffc4062e9cffebf710ee85294257e6b5de53c0439e0624cb2 +730500 2692d795f114318940b89b8aba8a910b6360170048ac824590c5d814f8b01973 9aad48ed4e603ebd7c79c8535c24ec7d2ddf7db6eed92b9d1e83846e9e139a1e 9958167159bba887a61cbe4100f975ff830eb291aa1ecf35d601e81c825c54ca +731000 e167080479d38ecc4cbcd16e4fae05c1f87e09d33e4947b6a9813ca63e147d5d ae82cde68df2aab3ef79112d4080a285b806bed3e457aa4215c6ee35a6d73e33 701917f137a9974dcebc359e7f39ce47c4c20127e5d90b0cc6f715290d4052f0 +731500 d8c7e6903152f5f559f108449eead76f647a5c9991f2815eef0d0058c25b6bb0 f786151a72adafd6930fe59a04cad481a49770c191a3f5444eb9b4d49b000779 1fa2adda7b69711f052d101fdc698be6cf424b7c9aa12ad51151d4fb61455c8b +732000 7371a17e1393bde477a0beb136f98e89dd30f49ebb28cf59a265dea0f82deb70 67d98bd80facaa69bcac4ddff46661d1dced445c622bc90bbdbe1e7de9a8f768 12daac68a822872d95dcc053f2986f4d792377ceb347b5803739832b840425d7 +732500 921701199569749e2d13f7940e6347ded7a3f1dfee26b7f7bb744d5d3db586dc 41fd3e2f31c4d732326d13c5f31cd850e864c43f1f179d8631ec1aa69c506d88 018fc6f520e5ffcfc1f7cc8cbee755ff914818f3813b1c4fdf66ea67a42adb82 +733000 d452ca29f9949b714f175c7ca45841a6519857541c44df4e52caa73b4c9b347a 616e3b11378287c338d03dc5e2395c5500915fff6340d6fb48c0123e33f92d51 c33b9f88d8fe1a9f7392d5244a3c81f4b5e6ac8ce5c6bf01116acd3e582fd438 +733500 4ecb0e1b2273ed4df5bb7db47988c3271e81cb9933d7cf50120e9730db47c82a 6dbe9a6615825d26d58bc5a2c068e9068dc5b4a1402dda75c43ad3810cc55a80 85633a636edc1e9e147caa51f1dd0c9f347f224ae059f80a36e905562e035a1b +734000 6ef7723b332f6d1a4791f14a1cf2811870cbb08c2484ece5cededa3f69fb920e de8e532d9596a92249adbea9833ff2022f96bdd3f82b7c734fc3580b4b3cc946 1a3f96832ed8a83d09635e696af0c7e9c613d1223ad319a2a3b67ad0258f05b7 +734500 01d19d29a83d79e38c274b76943e9d5769932a6a7812e3f297620a40a0bc922c ff43eec3f821cef199133f7c5282c9892c1b1546a77f6fac3e9021037481fdb0 9483a0bb66b7919d3e4577e0d388eb55554a2a9ef1e151625739a14fb9b15499 +735000 544a5f6ce7a71e13db7335cd2a4e02fb7b5ff98253016f9d7f26956dec908470 662695548e437e31e7687cd4aa3a463d2dbd1b0579df23c6f5daa7e9b3788e66 c746d32bd2dbed6a9eda016c6bad0036ada8232ea88b85dc939b7d12e0983b2d +735500 997d9b45e87e6f1f1b76c7c212527bef213f348c51d806200bf6541da07b76d1 68e5ed2790eb489379491eeb583227ffaa09afd5b62b9073117e540505058b8d b39478fd31667381d09d847574aee5cf03b9477bce4f683cb3600c6aa3f1950d +736000 b371ea1a60567133d86757ae1b12faa8832166726b9c2eb67a643e6878b0f64c f5308b0f2fe00d7b1e1bde602e6028ba5f2ce8849da22ecf2cc07edb069a540a 0cfe3bd3e577dbfb6dc463cbd437b5658392d640cff71ed697581ec6b7f7df85 +736500 ce6bfc2ae42b6e0893e4abf6edeab04ee36cae259415004f71811cac250e2abf cf5273f67e35b1bea345758b059f5b4b05ad705469c64e85cd90f392f03db171 ba542ef5c7f0000a6e504124dc41cb5c833a9e8b132bfc51970f3971285a8de3 +737000 79e359fb34759ed805e4ba17b22b3f64f4e05bff59b0929d5a996038e3e2684a 06fd8eed2bedf16f590dbe5210c4657f8f14142fbd12b823b4972a4062c46476 6ea03bba2478d703a2733547490033224633d92a6d9cf23255673b97115cddf2 +737500 3d69d33e4b40ef18a677394e025c74f1ff03807f1cc1a9924301da4af97d40b9 8d5cdd08a8a4db368da7ab6be4a68085fc9b2a156fc5e89b69ed661267bd9d05 e2627eda436a29aad70b7ce047f4dbe731a21fcf889c41db65fe75ee8146106a +738000 de67c044daf5e82856c70c57c05e0963d2767f721c9a2a3095052d271ff77a21 3f6cace03de90c0a7093e549aaa5862b4d0d4304d20e548c1b77a7022a39722d 7107bf0fd8cf132d24c92e2b15640e5bd98e857a64118b0a6292a1d36b1c0782 +738500 9857746dacb79d61819a9a7bed47d4f3f8a8ef2f0a4241e4a26e84eecc388178 b324b1e1ec98f23aad98bd643e12396cb0e6db5b6679f5f197b8c82a74912869 e3cc1d3066314c3a969cd1d4758b7d20919507e4a881f8c9162390cd6fb503f5 +739000 e760e2ba3fbf67764d9ebb7a9b5684b71d079174bbabdf7de315b7814e6a6d74 74cb6e148688d11254c235898692018c699071730431d7e9f7438c6859e1b140 f5a11830bacedd7dc2938de16c36e1e64b8a15418e99c443f3297a9b702be043 +739500 f066444b8192b7bb857f79443308595802f67e277d85efca22432c5dd095ca02 91fdef383bf939a8e230f32a00ad0c58452c3bb0847a257a136297dcfd476a6e 3ac87fa0067e5fa90dde3e5fbe065ebd5b81f5cf757416b6e218e9cb4006bad3 +740000 8d11e7b07aad1f84d0976806645f5d508acb6aa563e1905bdbfd49f88a83f561 d1fa7be0afdec09bdc631fb8d5a35bdf26f47b479aeee287cee3557ddcc412e2 327633198b1b9a062e0954dab483215898c26aebdb2a37ba043f5de5bf950dd7 +740500 54b44786a4b53f25a1ff7dcbe85ba288f6108cafb0abaf193c6fa9fd1bbec690 511fae7de79f3e6aed0645375673168bba00a2d39563ea2596e09e3a0e609840 53da3ae936a368c0341d066925cd431802924042b0aa65f68d03c3a78b256def +741000 6e98421219a255828fe8067f68097ce9d08c9f33886b8a29a22d2ebe6ba1f3e0 ad33286ebbf08385412b7a732c551354dead015e466163e74e7fb5f94f6b1cda bed250411cd373b3b2be382d14df5c00745a98ee5b2a0fa07a6dfffbeeb3f247 +741500 81eb9f3b0f352e0ed1c5935647d526ac71e0b775d8715732e262f50ab6a55963 fa8c84206d369ea634fb6668aff771d4c9d3ca7e687a6f2aabf1b2c80563b955 d00302262d909b8aeec2869fbe84179c8363d6a099e593b536a188c66bfe80ae +742000 540e29303471cd64e05ae80fbd19847c61476ca202848595583e1432e45b6a12 01c47d0edde8e38dbef982a21b7b95e6049dfd3ecdb75763b3ade1cb8b804ac5 6de5d07a99e47f413357b1234c46f8ec1750153692c54150808309b6f841f10a +742500 6bdd578f687b5b04d2492b7bebe989d618b7d55802b977c9f1362c022d37b5e0 abaccce8aa24b8424fe18df7490c67e36999e1f44dbcc68ad557c59717da560f 46ce514134acc7a1f0c69feda82c4442225be9cb87077b320970e56dc8f49f77 +743000 1a56cced54e09d3e03f267054909c5800b30e571a81e21cb8e1960c32fb615ce fceaa34349bdb34a4bd0125a9d5a0d73ac8eabd0da333a665f71613075268854 5b81d35da286085c8c5f08bee82e38a8c0f90d544947c92f8d5afe8da7617b00 +743500 2b102f1ce482314a2ffc09c26320f241ed197ef0ad1b0b1b05884d95e98b4832 0d514c31a22d865f9480fb408373139aeb312d750df0441dbba91f6dd74b7c34 39bfc62af5e07b039baccebca8f47e56677f491d1105f662e9b40543a7325391 +744000 9eb6d3d3bb45887dccff04f8555b7b6ee5c16af80cfc8fd132f2f5d64ef32d85 18c336ab05bde704336b82417e0f8a33d6d70df4bcf3fd3277dbdbac7d285313 3eff0762442919b5bcd423ac1a3c0b1405182a40670c3b72e50d7c93d7e5a085 +744500 2c894cc985ba39b9d41d6cdffd9225d1137285bb2a9faa355fc04e1c3a503783 fafb7464d1745969dd5edbe08aa6400acd05dcfaaf6d09a135b206eadb2d7a5b 93107399425dd94d165437b4c24878aa326f48d67164b4bdadc01b801790b737 +745000 0d3d86df05886717a850b573d540f01159dc4aeb9715260e19da107d8a5768d3 273a426515f6fbbc4d1f505ac48c2be61e47dfddeef2e0725d1d287da3706876 17f3b83f2ba432653925cd636891dd78d469356d1c8a18f40cd2860b9bd66a81 +745500 b614d96445616a551d2ef219bec80a8b104035ae75230819c08c1bb5d40d3eb3 e8a90e0d452a4db19b7703651fd04988b45763240ec6e769e681cff12a9713c4 94918b14a3ecdcc5c1bc43e98b4d437ca0483f34a6e375ebc6e217f004b0e731 +746000 32fd2569cffbaa373077a1d958628f5bb59edb4f1123ea22d827e59b58e6128d f0023c390d625e1286ba9aecfc80f28d96109289f7c438379a75c7b08c915f24 381767ea931c005ac7304adcc66633a229ee3b7a73f67a385da507be65fd5a1b +746500 51f9b04af9044618552cc030e88269c4c8b6f6285653003ea31fa0596b3be8ca 21e1a38a259322e17a4fcfc9d45cbfb75c345d2475f7081373a9e8b791e3d906 de4d31abc59236bcc16c6bd7b36a5a383000bb1e9b57d55ba02eccb49e56dd62 +747000 ea7dec43ccd90255b703203200c0b71d3aa7332a2bb43549c5b713bb03b77f9c 9cf126abdc8e883dd428ae846e7fa5d694e87f40d1de07f772f916de45db3de2 f28ddc3a0c8dd9831dc98edf8e7c80395bbc2a6f482ec626d2a43d3f6c0dfd24 +747500 1b651b29875be11fbb4fa8ed4c857b030122b7facdc75ec31ddaed88e3623566 66c676aae65eae30d876db4035a19e8e00bdf9a9331361e72f57af17a3da4dcc 52c8869f00a2fb858219119c25d1e9d135bcad2fabc2e4a12dc96063b840c04c +748000 55f61b3e6a5434428b1a062ee86523b68f5459e7615c29d83f01eee310ec66bb 4927588d5f0600d0a418298312581aab6d41144ee3bb87a6875d7b11c676704d 92182c1111a64f08ba98870b439de9f81627d117715b3ea650bfb5fea98feaa4 +748500 cc910d9ef1a087c0c9aadfb77da9051aed5124b7d072b976f4d34dc74f842f14 f1b10cb29bf15f5280b2506a480c07a610de4dd63212ac5fb1a33894c2fc0353 d5d083bee08926e2bc17c9aeec940906bdf6b0f37ea7d6c2c23b2d4d881185be +749000 70c48f09a23f35a244e22e7d43f245a20d1d171bd3958ffe261363536f92a087 5cf7c04ef74572576b5debed4c20f3446db017a0360142b325a330909c904b09 e24e68210d96e24cc04563ac6fee29b4991f3b13fa04d3b31f83506a03fb2a68 +749500 33d54681aff8149655455f3331792f7a4582c0f0a436b9d3ec0fced7a525ecb6 95e2c8c804a409d62130abace845c696125f8a938bcebe60a45d9c76442fa6c3 9c16bb3f870ee8e50900d7310541f629e4e087ee581467f3dac27c7601a9a881 +750000 8e0b562cbf9f5d9e0539f9964745265261cce019e73e22cd0db86f0dc7049110 03a1b08260d16527973210066d867267be1f3d4692f3bc680afadd2b1653f995 4c77b7a73824f489244a9a1ba383b413f23b932a2b7cbdfabe707ab95c66f5fa +750500 a85d11029aa82c4dfcad63d3e6e32c4525f9d192fe8ed223ab9f05a3fc4a5d11 1e1aaa3b0c05e04b991026c5a9b6a56228b007a6f936902f7a80f1b8f48eacf7 79078573a0874c4d42ed9497435e6a5e9fb2a6ceafce103a28a3f4b0f9753dd9 +751000 bc48dc5090db1a9a8016b89fcef45999f9d6c87c8982dc4ed52e4b583ac2f7bf 94ffd27371d8ad63511d87f728731b0513ca8d8b948d8b777d852ea9aab4804e f0b84e3b614d9701a514808bb116eee3547821b42e0d2f6d6a3d2ed2863d951a +751500 c45fd98831ad0acd126e9fc658da6851a2a14a1cb037ffa596da1f2da2fc47cb 82be3962eb66aa5c0fbbababddc65c99ac5c70b372b32aff94aa47392ce6b802 11d04f7ee3e0ced8bd872e7bd5243f39704b3650db2372a57a37b1caf00105b8 +752000 373e8654d6a04c16dc7ef938fa6db6abc8672283a0f027cc34eecb1ec872ab7d bc163b7e20ee438640c02e74d48ecd1f65a4bd4b16d21248663a48e63eb02616 dfa51a2b8c35ea201b2fa58dc759969dc8f41036f3ff67e5710f2a6b2a8bfbec +752500 5f217d14da39d80fabcaa06ee56ddb41ee0dfef892576c2e100793f03818145d 91a33cc31ca938ce0b222ee141bb4edc500263a0689d0aed50660f8e4581a960 be525451b8e4d3066207a25961ed80d3fd944ab128b1250c657bbea2be7c8ca5 +753000 3e4aa8b1ce5cd84238df7ad4558f411a41a674ebee9fbe087bb41e880936a7c5 7b8530bc78bb832d51460962af3cca2f534cfdc28760d7f5363534e68a72ec9b 4775a888543db3451784cd50e2459d686dd66b08684e9f82b2aed331beed3c38 +753500 23a5236d81db31cd3e174f58fc2f9c1263365c35dcde4a20f315cdb01fc29d65 042dfcbd5f30011ff7476e398e4c4b90f890a9fa4eac0da6b809410c3a9cbba2 e7b4c5c5d5757a05bd4aeb7a84b112c965b857dd65465c2def12144d828e6319 +754000 5b4879ebfac928244d38117df31bb10c9d7c9e8e8d2a35c5c2f8a230b4593434 c57c3095308f688759285e35312da7e6da208cba0f9db64180d551affaf107ab baaeaca199cc01903acfc8d30213c08fdbfee34e81f63bc7bbf5f0f9a97bddc9 +754500 96cc5bb1028f5ad1cd8a33800d9832d85700d037d5746d6cb4e58c1eadc8b119 df2a0abff85d391ea42eda8fb0a1d7a750eefe9d5fe25efa10a9f46fb6110f8b f0c2a4150df181efea04ac95cdc535f8683ab435c9915de021957be8c4865bb8 +755000 e7129e48fecdac55aa3944a4bbd19eb16f0d8a73cfadd44a79d641aaa46dfbde 385cb4dea3040a9b4d475877dd9d3cb61e23091f492fc5ad741a5cad2268c6a8 9ccebf717328abbdcfc4292031c481d94e058144645784c9ea37b5a21962e264 +755500 93174ce679911cf73dee7fb12bc26b02889deb145dbc92d69637a85407812272 5f000b1a76187f1c309f9495dbdabd5001f69bee3f9498316d0277383d861388 6e5c681a580f3a0c20aa42c5cd521b5259b1220c25e47844929ef21d14de7811 +756000 d2cad51c4c7f604a86bd42e5fa0855488394561fd8b8e403c968676dcecf2f9a d24b9c50230b5c1aac5e5937e488ef65f19cc11fd4cb6b97497cea46061d7e44 74a6420ddc2aacd8cf0c4802e46cc50edb4504924c64bdb287884b4358a45b48 +756500 2e24a5dff5e90a2bddd7343297d9e1cc5f1e8555a19606314e46c09962ead770 dcd2285a17c2b37a17fa6cd27899af70be173d7a3d5c28c7f3ba6cf4d835c716 29e38f84c118831844b79aab7038ebdf2b9a4107b7c2217512976b2536597d78 +757000 d11e6ed1c335b9cbb3db5e79e9ac728fe2377ec42de299a318dcf31ffc545ae5 748036b1271dd158b39d7de65e91a95fc4e51fc0e9eb3445cf7306f15c0974e7 14150ef035ca4576a22d8f67724062f82c3d51ce0899bebc32a1af8d0d06114b +757500 0b5f20e382095632dec99c72f66fa419e1ce638a80671b8ba91b9a6d24f51e29 d6181cc28a4fd461f6de97bb298ef188941d1765a5bf650e95d418fa8b7fbd4c 1d5d6329ebfe3b3e4677ec3da843318ce79e3831a1c0805b10e30d718ebe1d3d +758000 5a2a205c4c51fd035a4f57e79f2d92ca5e3c9af3c8c2beba21a442fb02b2c705 e019ca24e6b67025cf564537c25fc2e6e241b44730988c316eb32aa8afbb6804 a3e465d0821f9f2f099aa45c16db42cd1f93bd213f010ceb1b467889f30d61b3 +758500 e33c965b4ebb8b924a1fb73c65017199c806b762d4441854b79661f4de03b427 313706df2d3cde7074b2f6849c1f134ede50bb46a297da3884d21a1828ce8072 3a750153373092dcfe4dd326860d933a459acc0a9a686516a59bb70b070f0ec9 +759000 31928e69c1bdd6c727eda5662bce3f72e36496d538d9fc1cff1424bfcc24d0b8 98b76d0e9682ac933b75419da77ebdf7ba10f016d35d26638915a5ba5be4db94 77111411b7f07c74f18996a48bbb02906214463af40540656f4b263f40fbb8d5 +759500 2d322b637e8d92f51372101bf714ba726396d413b0a8e9ba573018ee1023b0c1 caea6763d02b49152bce73655908d1bf489b2918b8514982a2fbfcb1099011e9 e56b99479d6001ec1424744a425809882d6309a53452d7d9772aa4eb3c5f0fff +760000 1cd9bc900f95c2e15a802f7eceb33ff51dd12a71718cb4220e466bfaa0f5ffaa 0243b603adce50f296920262a13469d2ac1d0c42c2ecd633feaabea80a4c6100 3783656e78d3879fedbfceee5589968967364f6af046d0f281bc8b99c6d1b321 +760500 4de4cae653ec7611cf7079c4deecd470afc39ac6a083a7b5ebfacd9d789c4394 d3a390c8ac0a632c7565327db3e9a4fcc30aacc43e2ba57377a1477235124baf 2e276fb93c0e9608afcbdcddc74fb5c5a9fe3addcdbac27871aa547ef7819b05 +761000 6aee8513d50a19fdaf21e0ad49ffd92cea289ed0fae844cb3afa16ad3e60b934 045c6ba4c62d4ae995dced0633d85b8e120542be2533abd9fd1fc8c651f47563 9107af72a3f9b005b7ba8b6c379bd51ebbdf55d3bfd7d3f9b39c6ebbf3d62546 +761500 b1917f5b3a3f1acd43c09e2d975abdf63f4a2c6d0b8ab429b47f467020e5b31f c7f69fc7d9f169a97f9ce25956c25668cb780205eb59dbee76f592718d74503c 21a08cc13cf867235f5cc7471480d289f3e7e203116d607853a359ec4e15bd7a +762000 5f11eb707b887cdd88dfd5f98203a949824d1fe960c4c85525995a377a39a79d 6a3963332b853b978afeaf71fdf868b0d36ab203773c958a5fe5a427013ad02d f9b97eae9b714d0256802379dfe0c9efe2812b64cdfd04425c13f14c4df8c893 +762500 8c3d3c496b6ab6a1e56cd5fceb131d8a9dd8c4fdc938d15e6ed090dab25889c2 e6eb9f858bb451d57926036c80c3c7ac4617b7897b19f67e2cb1952ecab6a24b 4062917f26bb776572408ae3fb0789ad6376c988ed58e99558b5a5f2ad19a55a +763000 6fcef4afba243507e7d54aeeeba6cc7de011b43df9d90f364794e3c59621b980 47461602514b2ae53177fa064e5abfc46da728227988a9388120901fb2dc9a94 b58aa437641b3c7073ad03061ac0e9f7e84a8c40cbf5c6f2e237584c94235c4f +763500 41ed18026f39928e570601d40419b18758312017a7c9568d73d12d4b828a121f c04c199a5b9d12441ed489dcdff90453791925fa29ab6eb6c62b0c4d648e28b8 ca6b362ff73a0d0f8f2a7a7088004a73ae76da9b9d2a22333686a0e40e881d07 +764000 67e928458125fe2e3c6970092328b48497a4d26c6b04b01e53cac4de70fea64b 9270bc1fbd0aeda1572f2c2ef56dc700086652533d70be2fc6d13e5bde70f8e3 775bedfd115319f5255de4354039a7159685f98370819905b6ac06e5202e6f22 +764500 015f8999e9b59d173970ac6f7b5b6b460879a56fb254c55fc64c79c2f1ceb2af 0fb0da763fc466bcda98bdb2d28195935e5ed9c8d35fdc877160aacf553a4a3e 7d7cb857eca8938dffa7db3374ff242e637fc934814ca2fc627b3c03f90b6d10 +765000 9e706cdbb0b6dd01e5fed36ab646fc0a80a850e08f2088de2136388d4db8a219 f307dd0ce42f0f743054ed8236b6e8c44e4370634d9382ba439ef593210f14ca cf725e3349b816344204d20b498755e08ae270bd798b55a3081642af7c9cc320 +765500 76b996f89bf12e2d725e1df6b6e1f9fb71a0e4741add4657f8233fa6b1a9cc0d 1c1d390e6e339f40129dd63bf89b9dd34574b6c0e16739449ed1936b023f73a3 8987ba1a7fa864569fd085de2d8fb6455ecb5f19c20cc57485ff1ce2c12550a7 +766000 46b8674f0faf71bdc7bf0a656e0e02660d90388ec7c3df894b0b3562d8541ba3 ed993dfee8eda538ad156e46f49e73c96e6abeb40c4e2ce1b34751bcdf4e7bbd 90b578e9e673e5a0bd8d28b9a19d65faed380af38b35dbb755f85eb0515e345b +766500 719246e48b8d681ea5869953004219e8e9ad1ae095d9f7005b39316010542a79 7d760e07389497315c4c3b10c43d939fa4e1d43dc29fd4e898911ab78a6943c4 303206c118e59260c94e39b6cfce312c44f1450ee1e223c4f0ea0880f8e61470 +767000 281b1c63ced6e6a9e548f01039e79b341b4c75980548acc70b0c52d71feb8e6d fc8bd623900af0aecc3fdec5de0a55fc7889c6b3005c4aa8fc3973a221702eaa 9b9834b90ef9349513a363f3fc57dcc98976193b706a9916c18b689b4c1f01c1 +767500 d9a20cb9dfca54abe3534dbcf69a04b8f6b43afbe3703e7aebb2bee8cb81f73d 899b241bdd3264be250d3f665e9930a6b2f302e1eb87ef65845be021d856c35f 1b6a40b17f0dda2c341f653cea81e3d6e6a8ddbfc9aaaa063a145b3d735fa0e6 +768000 8360e09883922bda97c55167146f583896798f25e12baf10cbdb39254ab11ba8 fa86336cef4c01ff1afee67169e0f4a3810546750ff4c38cec86e37c27444bb8 1854519636f63903204c5e6d7375411fe7d4ca51126a9b89bd903da11ea8088f +768500 ffb03996ae3de8c5bf73eeb51ca0527f6ebee4b20dd059828efad08e7e6601c2 df22eef90381eb583a9e93e90e0722e0a6210c72da28deed40c27499c7a5ef21 b8eae47b85e4f4a219be1ebe5901f57de53415bd7410ca1b2577aa908cbd1fa4 +769000 2103acd9679638073a79876db195d494213d9d6e749faaeaddd6c672cc7e177a cc3a63870c9ff71fe67008397b61d975a8147d03a0d8d35a3565538ed514b4c9 0180d7731d63e1b4a4ba0bcf7d40fa9997c0520eed0f1c89959c4f705ddfcc11 +769500 9336bf1ee4de809e164e98a29bddd7a448333f2e25de891b4ac528d1bd7af785 605f77b3340dd29717f7ba780e9f4ce15fd0fa43f2ed916b9e54cf23aab2863f 77371c10af50eb346f69bbb2a16a91044a48dbe7bec4982ddd1f3e80b1da8157 +770000 6182eaec959caf801de20f3000efc3b9431aa1af594a05d704bf2c53d810fd83 1ff43d1f6b27ee4063f01fd16f49110f0db50d58ee4937c28fef346f0777335b 469227309694c2f4b2bd3e0d691164a2b5e6bf747177ffa5315b26f98ac69a7f +770500 5405e7303c38724438e124b5e518c9af26a0076596be02cc57348e91a89abb6e a64f6256dfe425b8fb3b98b45dae59bac34213b85fd777b91d08d15a62a25623 f5cb13454e327025100ace0344bd4af58e088555d3d7dd78e5c0ccadbb3a15c6 +771000 07874de328fb41f73e1aadae9e57705d7679e8e186b8b6a2ac50ed5d1455d1a0 38084368706c2b4c84de621b821faec1466db4cd8334bbb13e4eb6960dda4b5b 8451f8da96a32b867f9fc444493bbb25d26d18a7eace68196afa1acd048f0a5b +771500 caf1cde2dfee0a11872272140e8043b92a33ab604f0b8a8c34d7a7006a11381f eb96afea84eba379a82e30b8366611d133f219dbbc728f99d55419e5494c5b6c d7cde2e02cb4e0adad717bb9540c408d7de57c290db5f9fc0327e27f1edc9249 +772000 3f8fb7f8de518b519eb102a29f372ffb4627dca2bbe06dc035bf7ebd4e6b733a b6de44e3b4a2a16494b4d6d7e5423e1ca66faf4ec0916a8ac97e4a3a656fde81 df44c8261bc11e19e81c4d8978013bd39cd33852c3b1315967ff0f4786949dad +772500 2fe560018de02c9be5e9cb02c0d2abcf8d6efd94390f10d8eb84d9dd3964d53c 631496990ae92715067442cef87711925361593696c1ac62ed053618951f9d76 cf131dfff5f531c19ea26b7760c86cb3ac1b8ac3f8920f9c4f15d336bcb68973 +773000 53c1e8e472ee4d6bad6411fdc74d9fe4fe2564d0baf1bc5107b9dc4ec6262afe 8d48f77bfb9b49f20dfdb2168f0abb988b8ddcd8e9e62ac35ab0a2968b912986 e2aec43709ca010a47522638f0624907813138e1e1b380f7bbe6f180e628fd60 +773500 2836b1c2239c528ef1ca59823417c6ae51c93040e1a5e3ca11742dd10350d3e6 16f14274772f96d6d2072a33cafd5c8f9cf4bbe37111b3f620e04bfc42392829 0a71b92e9860fad2bd7f294d271466c0e66a73c057d4b8ad4fb7e0da53894584 +774000 69a397d817d7155b644d650da51d5413ed2c133a3cbe2b54bbab7ae7e5a82914 c50ff677b8441b9a940984cf5ddb46f4b690ffbc9703ced2b163d89b929830b4 f8a641d436f1f789a2f605267b1acccb8e851946b22731e19a4aea620672b3c9 +774500 e7569a38cfb85227d2d2189a89c59518b64da01e2fdc89bca8e4759269fad47d b72f3010914018a60019f151631c660311b949fb400e20696b900603404cb82a 131c227374a68de26401bd9fb82fdcd47bb947602a40990c87ad1830d5c95b10 +775000 d62bff072790320b532267e13d16eaa2b6124b12e9dc9704ea8b3472c33a7584 2ccb3c701d5d6730cb7fea0a703c1228f75c58b95dd167e135689d020e686cdc 4434ccfb2b3ee14daec33d99f0e1a4f1e48f35ac1bc270a796db881fe872258c +775500 69206115fd6be6c73b95c85875329472d8550ea98bbcdad27b1fff5f13f1a383 1044c0b51ee23082e8268ea9f57e614ead985939009b2d6595f866bfd407c543 36c58dd2f153bb315fb5ac171b2d7ea231c405a995705a9aa5448887e72c46d7 +776000 acae9ada07a40fbcd1abe244a88eea4497d892f56bc6c47c9a3256960c48a674 fa6f6390e5912cac9e116a1dc8ce23ea3acd3a45ab8c372f265c2a813a1d43c6 766450d063de6aab1e43fa81768c6d063e83fa9f1e3109eda9cf6dba976cf44f +776500 c7800bf474c58aeae4052c7de8a9a5be9ec371403659d6ce87f478083814cc61 5801468504c422c927e64b555cbde135e90690036800af540e0a515cde84a6ec 3e003d9d796290a1e73dae287b93363e01403205bbaf21244b6abe9d079d0614 +777000 60999146dcce1a4d7c57777fd14c438aa74620575ee304da40f3139145be094e 761c802120daf7dc3d71945a83698a8ec2813efe961ad3ddd5f0e8b05d88824e 34924d2e59d9aed7ff6e66e5e35e97aca41d40399f5aff99be4319267e8d8000 +777500 55464b5c24a72ca78e577947e5e31095625d4a5453d4ae8e1a628586173696cb 7198361fa24cc1510d0eed076fab9402f8d312924dad53b2cffe4a2634450753 2c96807bf221759fe40c6573bf7ea44299c5c292d72534b698f20df0cea9fcfa +778000 a96e3ae7c78171f4839888370b8ab6a75527c35181a76170fb0c0048a340efa9 40f745faad08e9ec7fb07610cee6fb0bfdc4b221bfe568e692928cbd556fd0d1 31a1cf9cb956557bf6c4c96b3b6bc5d4f9fbf8c53a37649b6691ecff7d076793 +778500 dd54a9dab8dfd4362d396a50863007b96b150c454397a2b4cc486f8b4436acc4 45f3cb013e25a9a12e1998baf79504649e32d0405bda1b8d6cecb7f51597dac4 88b4035bbf033b809c2c3ad7e410a48bf17a5704e49fbc92f7792d3932a96bd1 +779000 04bc1cac32dcf0121905e3b0f8bf15938de5a5470e130dad3d5e9478e5c04ded dfbf8b41e5cb2498ab9f6c772c18ae3af36f693115fd0b7ca12fc18fe8dc9d6e be291b18bee752f9cef517ca4263ab5ffe3d18de70f60ba98a0e3301ed8d5851 +779500 acdc4b3a573253149261bf7b8483f07e26febfa36a79b0f85663d0418bf89a87 c4e9858c10b84a43f0d48b59f2aabbb978411667e1e740d26cd90e824e60bbcc 8fd3e1dcdf0fa802af029b750601b028e971f623f731e35a2baa82b04868c384 +780000 70e69b1c46b39329196e880591e35915ed2ff68cb83f2899e1c8a09885462ddd eddb55e0d58a9e963cc6bd8e74cdea45af4a42783f9b070eac50fd00b10933e8 25c18241d995a1759dec8fba925b3da79c38c3ec81f19989cd0526929a3f270d +780500 44f6b73dd235490b827c83c949f8116d3e794d139ff88688db18a6b45e1473b1 011d86e2b32e548d2143b273ff895d85f132b7ad91a6ada40d29517155de88e7 d0e6dcd1658763ad2e899fe15a7091f139bc5540ed174d9a5b774e61fe6df67f +781000 afa04315bad0a73e082c417351c846b882f070fb89fbb62f94bf6627355eaba9 83f5ee23a34675c501aaeafbd8589c2173bed116beef5a6c05da3652da34eb4a 96aad7c45f8253066e4efad6a5fe94c21dcd772afdc291cd30ba0acb0e9b6b93 +781500 daab9fd8e2a04d026d3dc748d775734b92ba9d42af448b88c4e54313458f8e55 edfa9dc118b24ca0b01976fa94551d0e78fb276ab38af92581b336d08ad979eb 04faece12c26b07545b058a21ae9a71b478a34ba3d7a362e394bf94d9d26d83d +782000 71ac38f6202666bef6bd02261cdf9590ddc79b15b1f0fd74a0991f32d7076cd6 d02102ec38f004cd966d4e8d53db021475903f0630404bac02af92fc1ba0f055 7abe17429f2a42b3e4a1a9b48c21cf087f9de1afde339f2e71bab9060551aad3 +782500 7065d66fe20e800ec4e007a0cd3301a98985fa7f755f0fd904b2a999c45f16fd c68d77bdcd1b1080ab776a210493e4371a1d30e3c73d7fe871e04b9345a0661a f483702e71f5a84316d18605c3cc41b2cd010aa444b88992a7d5d48569d18c36 +783000 d494fe23c434284aa32d3043e1cc6443fd7bf9b36fe12410f7d2e35f5360b5e5 4ef3f9328e1d2d96c19ca549d1147c2063430601ec62870fc66c5b6e68aab6bc 45489e8456e3cb771b5aa7897c56a1602f3b861d3656bd9bc504e1e80bd050f7 +783500 568a8df7d5669899b02e916c28755a8d1fc4a111f3af3dfd4195298ab257a847 7f752afdb474b41347fb14da6be44561bbd5dc034ad25035718d57ba0e326165 f21daa8b18e339ec5aa19a6ec0d285de0c17589b5e0b0ddf74dc4bba29ecae0b +784000 98aa97184148b247fa71460e2ac43389d0d04b6265546ce0eba7c2be328b6bbe cbb9d6529647174626503265092201bc8ed564798e1244839a9a2f022c5774ad 3ffd983e39a9c3619919a3cf95f271a5c6e909457d005756e301c54cace97df1 +784500 db38f59e0843aca6f105b25581ed990384b8b6fa6c340cd21be37799ac892e8c bdf27aceb99b7e0386f937d7c1b8a5a8cc92ceb95cb3191e5502b41245ba3465 8901786cc7cd832d1ee4b48e75d8b747bf9c729a742e7f6e7270c3112fb7df5e +785000 ddb1f819bd3e7a89588081208e3dc87ebca46dd381593d402bc80aeede0cd724 814c34edf844fbebab1739243a0a664de608eab49ef2d91c57ef7195bbee80f6 3d7b3b15cb2fadfa928ab49ee537cc627e7bdb8a0fba2d2f0042945b7d87289a +785500 92f3c145e77f1f518c1decb6e99b826ce6d778c24634b3d6d3340897cb670c63 6d607478b75d072ff0a14c4c23454a04b9a08d3f9c196ebc0b817fc7b9efbd30 e59d891441d06cd8f973f6ad5c05adb3e5666bbafd72408eace7c7f4aaa517c4 +786000 07a5df141fe4feb999505fef56d930e19c684e5e452ca352f0fc49c2d9eea76f 192297c49f950aee2578f0ee3249bdebdbf6955714b4a4e05edb3e8f24aae8c6 1140d8f9f47651b9fe9974a905afbef7da25fa1f28e9815a83ecfae2d14323de +786500 d9b454e9c5a5a6f9d16d22acadb61cf1ce231ca4dae12878d868598425eae775 d47d551d3fde80fb8fc6886f235fb6164cd99133fe9dedc2bdfeaeb10bd45308 0d7646032a898170d3491176f37f62d78aee810e11a73df03a36b2f9cb443f99 +787000 1d5ad94333c42f9cd396bd5a2772973ec2440f1d9f3cedade83af2e4951cbb32 0cddc7f86a6714a3e3d2d2b004d1d3869d5226992f0bdf0f0d3bba94177b6a49 7fee71383d6838eddad2f3ae1de0fd6cb0f2586e6265be99e5d78eb59c8e7e0f +787500 b454323565de62c5e27b717877037c918e5c046dea15404d0817ed066267fa1a e428f7829407e31e1079ddcac80dab9b56743be59912ddbc0e0691178991b568 fce258bddd4cb4c1e979f1db0904ac6822c520b292f36622b61dbd922f997569 +788000 28c337da150a017aca9d5619b15d605cfe5c41838893650f9a8108c4844dc5b8 0d7ed84426c912c0a3d3320009e66302ea92039ebfa4eeed9bce380b2b2df8fd 6472ea9ff1201bbdffd7b8344fa8c32f9afa5f23fa534b071b0fe78eb8072fa4 +788500 5f6ec263add108aa8bae692f8381bf9e71a615ff5d4dbbe3785167a10465dfdd 3171b907ce8071d79c40b61ab802f51d8f1ecff22c4cfcf618065e8bdefa3910 6d0bc878ac444cb0d59c77ddec27baebc74be98a0739f14037d03f7b30303382 +789000 1a1a8318353d2997eb996843165ce0a2879e058d6cc2498ac43fc495f3010874 0832a6b246a8221f36b8cfc3c15c743878842545a3ef3b5ffc0f1cde8246b72b f309df4a8e1bb1278d50f91826b348e0f0b041db376d3a18c864d43889d05ae2 +789500 88387f881fec667c0a2943deb34f9e508a994383c3ac8884d24b1dfc400344e2 866305720d60de682a074333f7b1512e45c63ab0f9090d8791f315e199222519 a94028bb8240ee43d6c5e07090cf2b198ffea495e7051580c34760811f2d4c11 +790000 1659d12734baca5dc87174dd4ea3020c907031df843af6bdf22cc2ec8dea611e 63e7e3f379c2e361085770ef24c82f250cb47056045bae37c92cd369aff4984c 550bae5652731d97b02f51443fac5bd465c5f19ccda22e8e0e685104c5beed42 +790500 a01132497c3c4a8622f3c0039f319e7bee99942268a0ef323cda3fddfa11f1f8 aebda06ea6afc6b95cd31185250686bdd815e89025a1b067f47db36dec1fb8c2 a299c70cfca4a801fb39ace7e623d8346dbcb7ecaa9e8f58c5a556274cbbd4c0 +791000 9209e4bff9f2c45a6bf3d2dd4f8960b050fef2a600c1dbafd65dda57bcd909b8 e005838fe0d4d7128702bd61e7be6be96340f3d4538aac8ec8adf6955bfefa94 9ab13acad78de5329ba9ad59dae73b681e37893b6ee45146fbd04457df3f2de5 +791500 facd9b684bce4af3ed32b93fde842ee8d30775ca97b1b3a691ac0f267301b280 df48a7e529861e94604eaff33a4ecdd7e35be502a78ce16aaebc413f4f4ba59e 2be1c96a19a5f3631aac8cb883f8e94d85ec5099ff406ad5ea962a13d0dffdb9 +792000 8439d367ef216677cf50d64e35abd6a55d555260d8a4f53af86560221aa48b07 6b7959d457444a0e8c085d2f366d54460a8e8ea5691d8d0f198275ef79b72ed4 056d4125acd9efd6ed734709aa7b23dcacbc1404cd764ce5f2a7abfa0bfc86aa +792500 2200f9ce62b2fbb1b25ba5e05a09301f576ca7606c2eebeab05a7188ff5d714c 2b7504213f6fa99dda613f8e7bca2fc6310930eb40c405a06df793406d146b8d 301ad8619f7c451bac9fd29d4d41c83867692cb87fa20e11ed94855c9251ee7f +793000 3c520432d9a47e6e272dcdd99e656b04a1bcabdaafeca135cdb61b105b31d413 6f6b8a462b2d883580b1e2acacb9ce051016c06a12a87219097e5327c39d84b4 96a981e03d7f6b44821c7ef67805d6ac18bed8983ef15881e7b4ad026508eb8e +793500 a9ede0aed7bc7639d97fbf8c81203349b1aed926ab534ffd055199c047c427aa 6b6e849eb0227f85c0faf658c06e5b4b75e15431263bc587a0417b801910ed72 9083b804013b0971b268c4ba338c8df637bc8a9bb36343d5b15a2ed43b450f41 +794000 8173afb6ef69b30acaed892e2cb93eb9186a55ec63a8730cf5f23909c13cfa9a 4f340c5f5665cf08ec366e0ffe561908c19c646b9567ab3078ddc99ce216fd32 53b24a984c2ebb796223af7d02150cd5cb56082a0ac5b6c1f047ea533c4d080b +794500 debb2e81b7e22fe9f49c42c5d747837344567a5d301f900731c7ec427bc671b7 79a735251474e25bff8fd23b469f0d79eae7b941b45b181f475d7bf8ac2fb842 bccf02675e786af7dceb9fc7a1345362f41520089cc1e6fa0f0c3ce462db9407 +795000 a83507c3c3bd71dec9a8b3f471cddb67361e6401767c8c8ad348926ce4830d89 e626138e04de566aa065b5a7106daa670c614de2ab4d326523bfe5d1a4ad4899 6aecc8858c719d0a8cc549660b54f5c9e8a34cd9cac07c1289151a482fcd37ba +795500 0558ab8c1e1ddaa709688f0fbdbc1413bd8f80362f6e053f20479e9aeeedb4a3 13a40efafdbd6358d9ef9f1b9307a88b458e999100a93b8f4611542996eaebf4 9d679d11a6e91fad3b2f536fe18e47c9d6590a93967be96a98866779722f199d +796000 a141fbfbd754e10fd7e956c10d459834261d3571affa49b8fd90c0c804d0fed0 00fc2ab3f76f3b577f97c348313e9256331ea81a5cfb7d8466fdf144c8e9fbcc 252b656f49a41308c16f727b69a001dfc325826b60683aae6bec855aa0517ae5 +796500 7351e53a275444b95005213efb4a5a1397a7a01d58b750323bd37ac47326c704 57ea2db92ddb3e36ad171b3bacb48f883fb7e8ef74466fb769f7d5553be66c0a 95b1da9a766ee86ab81026c998b07fd025d6eb4133c3279994aa4a725adde067 +797000 80fcb6e51160ba191312939b815fab48de5a56f4121a3d2cd7b6925918a07af9 96242babb7769751d636828f5fdc2d1a44ca57e399fbe5b0683d09fd66b83da2 3787de63477594b2a378e31210707d4b61f18d39bd84c748f70e260380236c51 +797500 57bf7c33a40e1813c1947efd7412a3977b0d74ebfb6e846097aa45d03eb1fe47 e1250b6f44746881c59360dd6144bf4d2e86f8e31e68b0b820732b2a8bd69d5b 316dbbba75ad23f9bd8cf6cfe3f6a277b1ef742596a3025165de2bd86c4da49d +798000 f3370335ede3598caea04a87041fa7c1b51e5c9e1c5e0d50bf2bb136a64cd167 e6e1d946fc72e48f0399f980e5a4f7e544b4eb2997739223c355e3b15af48fed 647618c6d3effcc52dafc6a6705ad58695436d48ef25aaf8d684220757bca52a +798500 8f2f93e0248a8d8ded2c5106fe5034916127161f1a554e2ce307c5b6afc3e00c 2db41c24fb6ddfebf0b3bb5d74fbc1cbff4185082e7c22ef66c336467c652180 ecfa971d637bc6ee3e0f461ddcc77ac59a408c30dfd2ef3dae3d43e16c15e5bf +799000 5c376ff3e907391741b0ce9601a65e616d6183cff6bf744bdd6597c455b306eb 9b86110172b3879f17995b766972b505bf547f40e1113cdb52533357eecc4ef7 52173724bc690d27ecf672136ad648668707cbe81735bd2a77202a7c765ef32b +799500 bd143703c66bf324a5cbf67f9da778755b4f7a598450c328fbb011d1eba4d96c 83480b97e6c3221fe90a83591ec104492b37896fa34943c4f71265cdeb5659ba 07f30ede5076d4d94c9e1e8e46bc5402d1fae50effbdd0a50fe82d31e2e5bf5f +800000 e951054363c21bdb8e2c65154dc8453a7ed6908ecb10ed72fab814899d3cd345 9a0b2888559918507acbb704a78888f3293e34ec18cbc9961ac7842ca297984c 8252634f061e18d4e82e3f91d044ded94e90d223a7de0a13b6e772c5c75eb612 +800500 956b9c5b3c055d3ff4ca81de618186166629076e317b2bc429faab8ed5a9bea2 9a80628c0558276ab328fbbff05e76501ccc20593000dc13d57eb3ac4b618838 f65f6f7cfec65d2c895982d1ecbe70336c1f8405783317db7207dccb3a5b0c66 +801000 3abcc1a5f4b6411fad8b518e4e0266bebf4d74ec36400e0b242e299aab5d8d43 6e72ab4aef323f82c48dcd697cff16bb1f0ecb039a1a892a74c57abaed498d92 21dc9821cf54c46293bd6e575907a6e5ec525713f4328952b95cb5d9792d7131 +801500 c49350d66b895f226052f92ec5d5f35b70596d37a64fc2f36e386c21cdc224a2 1e1eab3a1d14c473a254babba1a8c9f342cf97b0ef0f60c2946149c72cae6423 4385f5a51158e98057db889478b6ad2eedfbe9463b47f2998bfc8001e1ff5c89 +802000 f739f9b985ba0ee82823c7c03d7ef8788d23c01ffa5ab040ab23682d5e1f27f7 45786b2936278a79a8d856f96f53f0d4b09a04056b96a10d5bf71f5ff849cb58 25e4902b2c0f1ff83a7b4e0b7796d4981b31c1a50256b9b64b4f2a66fdfb36e6 +802500 1bc5ec3d7f952e5f27e9de2f21a30fe9333fb4a53b9627d78567d789cd578098 11b12b1784bf7f779aa53e67753bb6eb9d1fadae56dffeb1b9efb5f1b1ddbebf db3095dee6d0a50357a953c8dadc06f2498c054a4ab1155c0ba5163d6cf928ea +803000 06fe520cf2eb81478bc9548d5802a7ca815743a5e541ad64b995af5b177ed245 f2401149fd3855cb680fdbacdb22b368edb2a34f73c59af55099c2d44e79adf4 2d31efaf10a7dc9b590db9fec6421b19cb6dd9d9284d4e731f1e34e940f510a1 +803500 2bc1768fa981d73fe4eef0174018988fcc0aaf5316c8597cc1c1eae8618eb055 b1a09ed639e05848794994217faf96d9b66a9e5ea926a08efa7bdfcef312b107 70849af07f962ffc21625509928d9977d6650bde0edf450ba910b14928022e92 +804000 9d0ce3d35c935bd67f2970d8d3d5b098f99f936e880f9ec87cc5e0b1f837a0d1 4eb8648f841497a4bf8388158844361e138eebcde30aca295e530b9d97bbed6b 84d64f6c3969c5a92a36911c98b66cac9942cf4e8a0cc8def314b28998593cfd +804500 87f582951ccb498931e71f194f2bacc2aa593bfd236519e4abd2336136333283 9ba93a57335f44c4bfb962c33fc0698f6846755d94ab393b23a81fa9acf72603 e65a4a25e45bafca371b86fbbf7780de48b39fbf4a5dd9d5397673c953f25ed1 +805000 efa84f401e0f8a68ac402f09bc3988192fd6c85f22fdf239e5b76ce100e3a2df a4a5b65c94cf7ce1d1cfe3c087f63037ba522ee4916dc20051d5953f6d42e067 a788f574e086bf728658f5e9a973441e92aa1bf0bcabcb1b077d3951df73a243 +805500 c0aa476e7e6452f41dbf4cb5bca05893a93782716c3299f44cf31670079f3190 349733cacd77e399f52831dd1f33884319cabf7934c3705e798fd8add0d90247 60fca81f8f2814562456842b24e875af9df1a5bab37f44e67f3c7c74c70fbf99 +806000 8459d195b63e53f3495da811539f2c883361bbcdd4b0097d0ba214fdc55a8219 9fd38c1f19472a144ec9b8cf57d8d9a85966dbc99cfb05628f5683dbe75501eb 345d444fc91ed2f7aefa42cbfbac89707532f876a91b91c84462d8defc5ed659 +806500 8ca60c34843a452a19d05b38dd13aaaddf0cf602601ab66769801c5443380904 f1a31e6d1b4cf5387c7def82294d179a656a10f438585a643e49dd6372982193 4a88dcd7895c712cb2b4e1fd05517f68655072c04713adbfaa9c88715c4ed4ae +807000 ca98242c7ff34cee593fe6dad4393698bf5875e9a980928363fb0f2bfc01e0cf 040fc4bf74790e2218abe48b6e53fbc6103ccaded8f389a0957e9008f96c9e2d 021b8cf0157c9b7b74d65d4a19a8409fe69f571ded09a89cf2b26df608eda94f +807500 39be5b7e38795922ba3653d1310f1579b152e493ea3c8bd6630e0a561465fd7e a88ca5c9790cb9542ef0a64dee1b5c001d56bee7636c09105a95abc859ca5335 63e034d22973193d76f09a5a933a188954bcf1f2d28a8a86d1a04a06a3c4c0a4 +808000 8e9c44d713b7bb2ad9d8cbb9ba3d9aed199b4a70ea1f7288795ca86c966e323d 2c9dbc0b472b7ae26418b1def60df7a4869a35cf9bbf74b9a323d08035aa13aa 95d2fac440da1af130ff838fae84ea9f9a91a2f707a91b0312f05d3ab917b744 +808500 dfd89eee02bd3dd16482828c743927801121f67cab61a4335d4eead749876a21 549d7b6c5b66bd74331c6cb6f937c8cbc605dee884796067f42fa1bd04bc6a86 21e6841e9e4a40775fa7f01cae49b438560c94b49ca8187bbdf7bbe578883269 +809000 676d2d9df28b1d4bcc68bbb1606033349d3e3a4c11790eef43f689d5e8d3ba7a 18d4addc8cc3174723f9ce263cf632f3817d015245ef3fb6ecae87aed807b0bd a358260fefbe6b4e1438bcb06a671260cc74b269f25fe018ea858331c5b658a6 +809500 001261eaa38a49c58facc31b6c7245af90f5ccae8d120be1aa3b23f80e68513e 1489cbc34c82aa22a7de85e615f2039703a23da1494aaf7b9d1c425e4839849a 0954013be6e64e28d40eba427c1c046d767e295102bef3ceaedaf706e0e6cd52 +810000 051b563ee0050d2539bb0f57e3a5b5edc759af06e4dca9ecc9b651122354d828 84359c9f7e1bd44948c4df3a1affb6a4ee05c2761f3b22a192faf696c1c8cfe2 8afa7f4a4d945eaad25ed01a71a065c33ab3788519b108ad54074681ca8601ac +810500 9ca81889bc6223d0195bb98eaae9b2b81771b202153dbcd4aedeba781063e4e0 9ee6f32bb1bcd2ac2787662019ca595b8a2569bb90a38be9dbdc77fd30e0f541 8d69e782ade3fece55262c1dbafc192ac62eef03e87f547dfff6a6682994b20a +811000 e24027de80e7e3cc2e2fb95439a4bc88541b10316eb1b111d107119a154ce444 373b8d3021db012bcd4b8558235d625a2d8eebec48f5c9c8784ce80be7ea459d 3b7baa5ff205a15500e756427cfc82481b5a4cd066a8588e3316091e2c9ad1db +811500 2188003a3ac1f51c3147082a9737895235c62f579500ab7207e04c3db272300e 5d5c778748335e1c6a4d7b72e799a84b1128150bc5b782238c222d234b6e916f c3d6ae0a5807575eee61c9e07cef23fa13e0ebbe17686880a722c04180097efb +812000 8edc7d32936aead671b293ca3c35a4f2cd8da3da8d0a911eab810aae919c671a 67921067e57ccb2692bfb932c9fadfd695208ae63e41c58cbaa2d1ead989b572 3e70e461d77ffad5b2360e03d535f314e7d007a5124cedc04d2a9e5142b55df6 +812500 f93429e089b8304c72beec28ab2589d33557ec36f12f1e5c21acf96a1eccbbca bceb1b621ade4000a2e9855c387f4575dc2599df96fff5fbb43a4e934612010d 2d33f5ae00324de69262e4187ca0930a32a9168b8901d3bf33429776d2445db4 +813000 c50b28d6a65438104f28a3518afc71932e5acfc9cbd3dbb0870dbdf8e175e159 b43d73d2203a216818e42d28b5108016335c606dceac6f6706641e240b065929 cd035b84d4a9e11704600b28b2f363dba81d32c87e2c402d5ebe6f4d0eac3b62 +813500 9ea262207c1743a9666200b8f174328d53875437ef4238ac0f7f9f1e841d52cd e915810eb721a46d939812114e3017db4a2fcee9c0d3b6701f070d61260706a7 4a7f61aab0c3b237dca327b640b730ff5587be83bc94f49eb5036d512cd033b0 +814000 7fc202882e511a8dc8b76ba9fd0e5d24578c5c45f51998f83d22e5c54eb72c5b 69feb5f7c9e1eae4dcb884df1bed34f628846110480539f3ad02db9e49c87f59 d387dd72b95bc8e7522e3525f2a1d1093358be2b3852c8298f4caabbe56cd679 +814500 946dd535ac1806a838ff7af300006a3b019926e3caef42f04e77cc50453fb597 91645835f2dfa4f7bcd0818c145f349fc912335d0c28bb21f5a6c88833531ef2 6852325a0f560b5ba965fc180e05bcce4fda06e5e3a1dc75e6ee57d127f94a1c +815000 32f06e0d2112aa022953d25a663a77c34fb1f0089091be64755920e082588a50 09503cf3aa4c5c2dcdfed49412a77bea1120ed6741f024f25384f9a2f6865f4d 0a90b89381fbcf7f61b4340ee9a1bff11a365472d68750575b08560ae4f538c4 +815500 ac758032ea15073a6e7063dc49bac109b04e84245383dfe4a57d8a2d68e74c5c e8796fee578d7b8c3a1282cdd6106eb5be84df03f16f290b1042788e3cad77a0 87f052cf5fdb1900a280431413ce9ec399d7709407e5e928ea757959afeeba70 +816000 4b0a8e17626d583d00af2d1e0d3d5aaa733b2637c0e7daecdc9ca7d32ef78b16 5513bb0e272bc3c35af92c733ac8e3f54a4f9280dd6305eb3f521c0a798864d8 f49d5ce010baa5a402628547ba02fc10645b15b1304cb1a975e850c18fdd5b34 +816500 7883f443a30cbe6777c45da4c70e650bdbdf7f2296d0eef9580b412d304dd1d0 83b8b3ed3caa544c6827b267919896ad0df9b50b416b4092a81c4a16cac4a2e1 ff6182b74bc884b1eaf924d2fbc00984d7a078108b8244b8bd65b2e2fbf61be1 +817000 d13df124f351e01764c49f28bd7bd9d94ec697abb36970435ede31462e245b78 3668760c6bac61282ad6173be88f0ac74108aab7e6b2d5b89bb05be5f7450139 9bac941af8695cff28fd06e3908c6cce4b0a8b83302dc1cf4a6c346523c7851d +817500 cd9bec7288443f2289c3e350aa1e2f133d13377ef45051c8ef68f588f0ebfb9b a6dcda37fb4542b47d6358e6f4990494b3889031b7d57270d4581c3c5f5c834a 884493c8c41b3841ea683fd22d126ea1bb45ed0d2e6fdf227938eb91d4a1885f +818000 db2426a8e3f0260a1385c6514a424c1db30e077cd18f25affc301b857899672c 1e887aa787c16fd0a14425d7699a20ce4a184468a4e8ddda982637cd60dd684e b02eea2ba1695f8d2d9846d2da47b93bc05df3551d9d209a2705d09bab4a26fc +818500 475ceb331fef75bf43194e6ad78493ee5a3132b1366764166bea3f98214c5e02 67e95130d865ef6b96c3c3594993525b0ed740d94de1322bdbdee1ca44c52be8 0f8cd1408b9de9af632f1e58985e0326c300e0eed6df70ff99bb77bdb38b00e5 +819000 8bb061140f8217d2d20fc59542169fd7afa823a911f74040d58b3c86dd366481 226b79c0b56a187130199fa71bb43f0c0c17986b38be4bc953aae9035b3b137f a2db1e16f286b3eeb7efc9e17fc7da990cd35d6d0db72b74794c89658346346f +819500 9fa10df35922528bf712983310840e630f4293f91e9e81ea9a6f416107b4b385 23400d8d0d4f2eca02b0a320b012d9c3874250e3703defd32a742ff3a14161f2 32dd6310b486174a8f3985f5a58cff61919ceb6dc90dde2ee18a01d9435bcf2b +820000 0b83d657248250c7e9d96015875066e2e5d59b7a0696af84d83b246abf9355ae c7575028b8e2df600f1ba0acc5a101952b47e9660a8a912940a2b548172a05f4 d74ebff85dcacf707b41d180abce396954d0bcac13d87bdddff2611fda3c68a0 +820500 e0176c1631f2909dcccd2e56971085cc4a435398a3a967945666e2d7b3232d1b 86cbb6afeb7fa1e6ac902b3d28f2aff25971d24b6cff228da7e4c8046b397ad6 8363434e90dc1c20ee0f5f4b47fd7c0dea0400b93943a51aff7986e173ad861f +821000 be0584aaa7571f33c631f75d7881d80e2a19f6eaddb91f311547687ab8b6127f f8edec8d65127f3eaefc274cfce29f29c4cd339739f2903ec60759367f283f67 c755a875eb8b6449f2a210cefc2d896fd89a457894a070554e0067c239f0bacc +821500 fd2e812d81cc2da106beaca8ac8e7ec4ef854416f30d7428c83dc72944e01ed4 9bccbcaf94c587dafd152fa579fe7bc4e87734d1840e0f939f494d1d60dcd499 f032fa6b906ab9fa959545de75e6838ab6a908e5913c8bcb5deaaedf7037e5bc +822000 9054e0ed1b7621397499863a4dfee073b379cbab6d211118e0daba86ec09b239 0f78238858465e4308062dd44ccca1a81e3b1aa830378d63ba37cf340272f04c e315de9a64da20253bed5b374086a7707d049f1e99fbab8e68f1b9d0cf55a648 +822500 c50dafdd9aa14cb0fb01b2d54da426cb862dffeb6369c1ff1f27b86bec6ea28e d7d020758a8d3fd93ce7a603dc710b085d16c3c232f389f2518b96b88d903a68 c5caf8bed22e2c5211f32b833db8b51dbe0e54018c177c883d5cbb25e3ffba53 +823000 6631367fed6a7ca98d2ca58e0ccb8060e9e0309df1bbb5d76ea337c386f3066d 4ef109d1b5fc3ec978f34d66b8d93cd3ba0b278d7ba9c6ddf4fc3d56039e0fec 88fe2323f91fc57da58b494933952f12aa11b292953077ee9664b6aa32d7c3f0 +823500 b924862a40ef19454769b776643bafafdf407500c16dd73a70a61ff7d033519c dc8d2c04b3dc1785a7a76698674830e8aa8371dcb815083d849851ecb47f1805 7232bae203573f6c6689058ddb2b4d2b06ac19ddba5caed5a07b08c3912d6ad8 +824000 d9ff8b7426f57da2db3d9f855572b493eba90e61b0ff3b40beec0b46578679cb 95e502ccf5b34258f239d7a5aa86f16c643e189873979210e0cee9c5acda128d cd794aad8626da79dea81ee006ca4c52b94aee1f55ef2912cb2f4807c75a091d +824500 b668014cbc4e38dbe8870d15c7ece604e8a698dead63136af5954cc403a13921 d79c1357567cc361a4629f57d3bb01e99929680f5597fb20e976ed9da246d732 b3a4d6a91d00cd7ecb1890525ca19214242805f0ddd04555b4899008c735337d +825000 ab26157df7834e458aacbb394f8f6f34fd489cce3c7a1e6251289401acc59062 73352b8b59b8fdbe1d83e82c2da9ed6282c5788802e2eaf3db7e7647e04d83c6 219be8d78268674671c9953aff79dc2f3bfac601cd535dc6839ea7dd550b194a +825500 4447fc4bfa77499510c1f033998de510174732f103eccea27ffe544577472f5b f15ba38703c021fa9419af02b8210ad9a9658b8866f70cfd734e282daf996169 9d3ea35ecad6a8d38b11e387681a7b6f3ec972492c9914e5a75093bc32288bcf +826000 8b30104ee7551d9d564a9142e2334aade0c93f1fe7846f2d2d21380096a5a1c0 dafdfa617b0bb3f7980b4df7dd4d0159144b7973976db5e60a28308c0e9a2216 ada7a2c9ec028cbe84830bbbd0e4b0d4b503bd78b0567dc69a6e74e91ce59ac4 +826500 0e2e09768e2c0cf1f39eaab0b5182b1616b40b9a6d931946bfae09c246bff35e 417a26d05c6fe49e0800213efe648fc7fa29040f0f16b4e0f3814ac4087fba79 e6ca3b27dcc0a8d4129a7d458543297a7d3ea8ac12594de75b945fa58210ab60 +827000 9539816f7acbfb9151d30dbd91509b104a83bc0564050ab5f3c3a180d1659bbd b8d3ddccffd24ee4f56c161acf6a739668f48a10fc703233bae30108e8b23f04 46961bf809626452945dc9b458e398e7df465214a7638f9b4fcb5acd54371a3b +827500 735c35ab86f85b3d7c430b126cda4a4c8e55479a414be9b344ef0749bb2381dd 526c10694250f563eb1f7e7be275d89c14893a95118bb5caa0fa3757d2f1b08c 63113fad7d2e86757c9a30c110290e27b0eb3a34ae94c3c19bc98c65dbc9fbf6 +828000 846213c0f91cc5f47286bda5e74a48dc86d91bed3d5549f2130211dff2210540 195e0a72d1b5934d7b37d8678c6ee6da4713fcfad761e397921573f0c727dcae 31feb7525f87c51d0efa33adc2c7846e4086f9a5fb0d8a49e90356e9b7104493 +828500 033da5a6c02d67fd91df3e6d357de891ba0a8352546be1e4c3c47d6d7a0b8916 3d55e3405532f51149ebf67cc1367c225ffcbe2832a37814c37dbbb324fe8c6d de49ee4299d76badb800b1df4df0506a30022a79d5090130584c9d2e1d842537 +829000 b64d6b04a7eeb8513608c60f52b3a54a2758808beecc359cf23e5a1c9991e1eb ccd618e28a3217ca7d14e462c4d2df34473438c0e89e68a498b9d236507003bd 2f667922d18d9fab532b941589fb89f5ecbe9d182edb79e09fade2d3eb4dcf9f +829500 31cc80619db75aad85974e5c52755375dba0dc8ce67a17e6e6e4cb29f60dad24 41145f9a5566c0d919937386229a00f302067d3d0dfdc369d866f164c4edce40 4a6178bcfc9fb6e5c545de1980f1ef89dcd83c4676a4201fe92e5f797c35894b +830000 ba6ae9853c6f5efc64e12f9982df9f199587f43ac41c49c56c52a217c42d31fa db3584bd7127b287f20a097fefea21aafe602b6d36287248e5b878d8f59a55c0 77361e13d129c986a762f3d37e7d02b47c84fb06774199ea9bb2f2d059e537ff +830500 881ba4b6afba166f55baadba4ff7b98076398db48b53f05058e4fcef5931803b f2d61ffdc8eb96d572eeb829ebe227489c2748aabb4e7ae8dd2d4ff04db6135a a727d25ce975a1c188e4e15c2a460023893f985bbd65b4a1b65e0da3840dced0 +831000 a49b5343b0e4fa384c6cdd8a9b79713ddefccf1cf1b9a9b8340a55ec56330684 d5d6f8ddaa5631cc30932ced1cd5151825bedbff4f7c454fcbccc0dedd8822c4 b401a21a7c7d52316b22552a82facaf78ad6204f97b6f53b0595ec94394b48a9 +831500 2325e3f54a404e7bc60ccd0acd9ea77d90a31b18f8368ba2797d9a2f7388b482 09565fb72aad572d7b2fbbf1b0662da7687c7d98db22f55063d753d0e59a9663 4d8438c7be30e5e62e2283d0594256eef9bc8d91fb71d44ff3f8a9e8249f4253 +832000 79353ddf61d1fd1c8930b19c8e2abf92382f86b7ec5d3de61a766952b465144d 2cfcfc5a17e8042417128b3e60f6c2f4acb4f980508c3d172e0530ef1322f55e c10e27c97f5093fe783e94e9bcb09110d32e61701c35c010799876e5e612a79f +832500 15c4c20b6d16377134e683d2eb7d561d4276a32d61f2179b1ec4f6461ec4954b 8d2364c10cb39a2c74360fda5585ead678c0325656ee7e2803383cf5c9e94862 6ddc31d223921892ca90b4a5eebacfd6ba6fb38d67e71fd4383846b7240fbd9a +833000 771fb7f8e60a4065f3977ce3397d58a58102e11111312bb8d61399be0774809a bb06d1ca6e8e92d34fa9f31c9e3332ee8b3b31e0a4bc3a1deacc6a9e0a24079b 94888abe56fe36b87c7952bd271966e42012a8cfd289bf8aee2c9ac3c7f58d60 +833500 b9d939f1ccd4ee8a2b769a4b014dd932f2d51d765eb4a4cb45844e726ba26f7e 77a9c4bdc03d8413b3600eece8b0593804b58afc41204063c3ab92b4c70d2478 623f0e27437ad34d1003504cfaa0aca7236fd53edcbd8edd8e2b9fe13d695858 +834000 c7bf6a274ef1f46d5faec1bb73cea0d5873fd15340b0ed103b0551213bd0b168 89deddbe651ce60767e84fcaf8419a7146cd8128f439436cd9c5edeea0c0262b d183306424b5963fedd2f7ede8e4e39d68b1a092957e84f8b32341afa963f611 +834500 614d3beaadffc9dd3765a68108e9f2e01c33a9c440438163970be6883f71b68f b8cc0eca95d7f827ab45bcba1eb5640f883f803c6635d09eefae1ab30558872a 79dcd4eecd52ba310114e3df54e355e44b7a8142d9c5e7c32322605094d98374 +835000 9a9f3c4367e50c24b3210a0650dbcab4ca0762018f41110fd7d45e70a0270e7e d827e1af0280be63e64f467a81e39404d3798234593ed89f03619354cd4dd7a5 7f307a633d01ead46c855a3ff23037de616aec636a15a68b005db4017c33d3cf +835500 cbbc70202da7cdb4cde6059eda7529609c9781e534661c44a1f61e5fab4de31f 9640b254c6bf22f95f94b10ee1263d475d76ec7ffc8d8813c2a7f73a7ca77a28 dc221fc429853e9b64beac869a705396dbd079a96505aaed00e8fb9737c861d3 +836000 63d55fcaa4b84b7278dc98564a5955756f3ecf915b231cd6f2399ec836537a34 be4ab8603457a5c080f6d4f451702426b19f87ade3869565c41aa9aa1cdb6b16 81751c92dfb6cdc8fcb076788e7e070e8fe3e8b1253c9adffc10591220caa988 +836500 a0a1ad507cecde4069df4dcd3ff6b0e44b917e732cded5fb86d50acbae0009eb 09c9ddd16cdd8ee68faa85a59b8547b9d07b19ef08ad42fc9d98f9d85ae7f54a 45869cc5a27d1e5a0a20e4bccfafdd547509b7006a3179083e6f4d9d4fb72137 +837000 4236b2466078279f38a8df0df56bbdf71da7a184f750d439aae1b7b9b6a0e217 1b7b95d0f01cc0dda255ea389572d8d66be622054e9913e6471347d83070da7f 393991d1568d9894d8fc66b4d9be11f0b213fd3ad618bf1b9e2ee7045aee3f0b +837500 975034c8d678099a6afeff9e8e37d1ee524f64a851ce07def65676c0ee189b4b 2dbd86bbab192ae7e44609388bd9036e20d6496962b2ced1b23eb764d4eeb3b4 c9a9e2e0176e36cfe676ba951e29afe717f905cf2e1932f16044fcace1c580a6 +838000 05228288f4e87f9283efa2e6547316fb61f8a6c9a1c4b3dd1b919d02c4beff88 8bb8421d901f05fcb5b476b8d5aa66f4c380fb7b00f65833f6b0bdd6ca93f62e 155861e19f5454556292463548962fd95d701ff0dea9aa2506afd3658815bc16 +838500 f165d6b92e8b15b8a276e7aa3682e61c44e6729a39111e1883cc8bcc78cf9b30 55e669d31736fed4be07280a142594c8f283e7a427f0630f9ee7f0b06411b948 7508837234344d9bd77efb2a47a09a2d4bb841a2abad90d37bfef179e8ae5605 +839000 e7b73701d281fab70e7279cc3406b961db9c7d89643139882ccc269515bfb8ce 44e7b9087a0f031995a963ba2c3d4d59a2856ddf3e822d0944fa472768990ddf 991dc1f6c6e7905e56fe721e467392c0a227f108b003ade2e13875145cc5c99a +839500 a0e9976acd9fc6b93cedeaac38938156409b74d9192f1eb4d614d4af4072d67d 774aeb086be488987a9ff3d9d80fe11d7815c1061754431fe3ec2ff387a4e2bd a66402d20b190cf54e62c6bf3917bf66bffca9d599911d6ff6ea4ae619ddfb87 +840000 85f4bef924671af404c377269d655812da734608007a1e43c7e2c974ff1a7f26 a7c27c2f0b37677d61314ca1a510aef72e2a7149c0dfb3e314c47ff151a7589f 298d9f5856f8db53b74c14c701b7a0947ba6f92a6e3c809a9d722cc84d778c38 +840500 9a3f8a90c257352934919ba5678d710e02abeb3f8c9b609f00827147d2f7cf81 c9234118875f5ff26dd4c37d0f498911d1caba96dee4d33a50c7ce378a9a0749 4a21e3ff00fabeb73bb38c41c1e1b97d25d59aa61a1a3dc248538016a482052c +841000 51b45385204a2bec9cfb32ccd8677bb9fce49c7c5fcb6a53c452e9b36cdb0bde 07ed169f164ef448a9a828d17a6c3455f3a11dd6c2bda1eb38a5100b8817e04c c512255a21d35ac5102e25983c4756960a5f6afd0eb8d7672eb8ec8321f61d4f +841500 92f53759b018613ada40999270e66657ae1026e4997862ed0d5e5560b917d6d2 37b8239afbb1d59bb35fd5696404860f47dd31163981e62738867af4d1d13c85 96805068c6193df48a0eee37b2e41bdd0a3c73c7002a2369636c46adf59acb8e +842000 a1202ffaaa1bef1c9c95e11f9b2f1e1b03e69f535628130df12635ed9a3fc297 ff3835e7e4cb8e4514adddc8fdcce0466170f3062e57d9abd9599da0fd0ae1dc c076ccb715442fe2b85dc94cb8ddb79fdacf597b37ddc0974fef209a475b9dca +842500 fcaf836bba0923b8d887f619a0ecd298a94f04a1127f82773a531d8951326582 7fd60c91ddf7611c5d0200f3f5adffda13a651c5bc71929b0724a3ef0c178463 1be228c7e806ebb9f4357ee1690da16982a8853629d04962a97ffa08bbddd6fd +843000 37827f08056c92edc0a941127d96f9f4f481d70cf2cb6c8c0212bbca042ea04d 863b61ceff5d6d3314fb420c17bb16c00b220833a634f53d24f7fb6c9ec7f7eb 3eb3471a68af99385a084fb558401e63c7a952432a6f61d2cbeba43a26c9ea2d +843500 5dae3f790ecdfda5bd46aa1005cdf1170b25daa976dfe3f83f07cddd47747f86 3d352565915c9634066580e57621f6682cc147cc92fa1e7f0112af699a2a09fe 9d565afa1bf4f9747dffe38abc72517e189be7af526058405d9e9d6178a1143f +844000 b3b067a2be410c5b04cbc3088bcff2678204f31c734440fa5ce28a43e61f6e20 dd379efdd80ed38f855dc2fed11db6947ffecca2c6d78c3b13d9e42de618eb95 7d01e39a64e1171e37a6affb926a6b6ba95e7f804955d81093191f7657e7e40b +844500 d8ec90a7f602aa58fe31112ed0917f4597352ffbfb186524253bd4a88a283efe b8684b9b13ead86b6620d8c6cb1b4e3ae9891ad53c74a5ed93bb547b05d1a8df 1deee7cde09be77c018bcd36d69dee4048b1cf551c42c7168a39e9abe55e1111 +845000 66ca29da4d604a893f7a56ebd96f365b3853ac2de6b38b71db898ed7226fb49c 2a671d1a790cf390618793e3a9e2995de070c431014e9b1c88c9c587cc12708a 134177e23c5e52aea8025b0ceefbff4b19361eb4849473c43fb843f1990814ca +845500 b735fe850f31101901fe04a4207e15ccae72039895ae0f149593dee3e6cf8a47 fde7269beb8e5c3ea60f2b30d1d43ed52319787b1d9363aa67c53e6beb187d6d fea541f995264a4123a2c94178a42c2804ce048e48364373b14872eb4ab89a74 +846000 b526a9a73f37f20c6ae046ec9b131f6354e90a4596cec60cce1414285c838df4 fd42d265ac2d194a94732500fcdaa7f4f2e629793fb220a871459880c0cd000f bca8382ad9026274cc09e2f3d0e8c6fc2ee05aec78774aaed3ead6d88715a072 +846500 761bbfd7f554b81cd153149a73641b567685b60914402dba0ee171d8dd0237e1 2d9ea683992b346008f860b330b15ba6ea707338daba431103b2a444542f9870 6cf67a4ff5492aa8c4700e89f9df215d90cf9898565a5ef0de702c35bfb96595 +847000 375dd44f3bb80150df686ae8f3813999d60507c6e9ac4750686b5d182adcec3d e4ad131095150cdc0a23d0d7948bf3c870e01ed0b4a6f9950457ecfbb254b342 bd3c6fdc759d432bad20314c703d555d9e56388c7c77277de4a8b2c40cf2f4f8 +847500 0539f76c06c311da93887c10f65904de31c72a00a2c0ee1bc66a46c50433c0b7 2ce4000e6e36145f7c0711f53a8b20144a69599490a7da79726938926685c5dd 1fa52cb8ef3c0fb707e5f3ebeeb99d8e25adedc2eeef565b82b109fa6cfe198f +848000 c6e8ae1f92209bde14bb652bc8478d5592d0f6741c3d2f2f232c037494d81f70 b7c0aedb71b645f0501319a9842e1fac4873184f50a0c5b758fd9f2cc2547a1e 69295041487a60c8f00f631c3e56114c9b348f5dc7ee790fc819631e55fffa0d +848500 d302c73e4d2ce3e318afb5cc773b089956501f00f64de08073bde92b2f3a99f3 0a8901df9a3d00b66ed1bd0b117645237b61fd34c63fc45a0604daf2ac932bea 4b93992d98ad1fd9b9557cdc1568803133e96fb9dd51878d5e6958a170a02867 +849000 0ad8844c1a45d6846464c00e9c6853719f80056b6f0fb70821536a133432ba1b 6478dd9c136dd28bbc4a49eacb7909c179abfef94618dc6da67adb4ffe69c6dd bc7dcc71f8572ab902c0c42773f396d327657951178a1e3376556a12c8be2391 +849500 8ddd724ab7ab24e5ce2f5355c2c4bea780fe7a2b4a01fd04d6a0be5bbcf6059f 54da6435a5de096881e00dc1907cb0b66274ab5b976fe6b67ccdb70761fdfd44 f71d51e6094c79459ca8b568389c91d23560f0daf00a023a460315511c97b09a +850000 b5e0c35c2d33ac37932b6d187a8839f1bf846817dbf5f4c58b73418e9a93941e e9f2c9230ca20ec14c17a35fa24d9eecf9119c5a38809c420ef099d9cd4ac61c 58c376de138829f5c2cdc42a78ed1936686cbb0cebcaa4f0c2ae8bf8d9e6f4fc +850500 7c1ea7bb106ee4a55d64930589f44b2e9fe63ab9846eb3caa545fd3b5597ac0b 9b2b304003bc1746f27de0d9a7cadc9dca7d6c87b6cd5c88da09f45282298480 4adb35a77d7e23f431c34032f15421dc3a75e86bb025ff7a470eeacc0feeaaa3 +851000 78c3131d573b6a70a648b111fa904b99707c622bc56f842297953968e50bb804 9dcd68f3d2c985c324ae53f03582ffce484a70724e2c13602f84099737641cd8 b7e3f52bca1ede78075f9934b0bc416ab5b99ebc2dc32ce3007f9857131a1bdc +851500 e470491ea5d0631653c6200effed322f6696614bd98109f9f1c90c2cfc72f211 5dfdf81aae36a8b8aada229a8ddfba138552fb9e101f4faa56bc76d3860e7738 10d9d0567062f9ffa7f8d8293d719b47be1f49a174847de61f3796bd16b0fb58 +852000 528590bfc01e4b7f567aa786f0de29c2b7aeb8dc3042114b087f761a5e6b161c a96175b5107c4129f6512d54adc38ebe2f236ed6c3f362f885cd4a96c6651e0d 83cdc7cb8e37b75127d148dc8092f8b6152102360a23721c3fe45315865e0227 +852500 a286a106373a8e32cbc0b3df7ac65b0720c04cae34a07cf070bbf652474d8c56 205a7977e413da822705095027abd2edbe7c5e34c9afb7225721dd18b700454c 822fde522643b4f3382d6fb35048125d73a72555d4275f9df3feaa09a17844a4 +853000 a2d7a0b916cf5aff1d6cd5150b034448c58dbd104c5f88e9b18a692d4a8e98e3 d91fce318de2b273cbff6891c8ab29c769d7dd2f09b302937493a38488ce1446 3ac1da42ee057e0a2d6712c7fb4aab7f35a64381133426ce3e0b7c72694171a0 +853500 794d93de5f3d5c39ad05ee77658de33f094880b037da8d2c124f4257f7360164 3f94598f08e53b436df3517458172624b710f4f9c108c463a39b2b816e511a0b be9a507170b144c094e21997367d47daf719134fd5b6234c26dc978ce6332fcf +854000 886b8b0cae2d1c914ab6748d636d5553dde505c655102ccb384a5c9a2b864516 308dae1dc6e58335096c15c90fc276e9cfc6639289c25a9a748ebe226f37604d 3e10bac885ae26b5dce2fd259a9fe6e9ac91cfa46c247c53274050428b72d668 +854500 78d0ac66bbe4ed7830eb9025fb934514035d9440e2dfa75d4046410185235755 e2976153d1e9c4253528b84741fbf9d8bc73e85089d63a59b29d5c847e336c02 18ef920835702377682de6772a5b57be2c8ed8ace449d334d05a30b6c1b34113 +855000 be6a06e20a33be8f7e0c96318ffc3ad202215dcc9124c06ec678a6a775c8f67c 4ce675eafc85e0f8d54f8281fecef780e98677534b3dbc3b1e9e7f7a529aa3dc 67b323bdea8d1b397006d4caab0c950deb258ba35738eea3a737eb114acebc63 +855500 ac409e08616a1e06ddc3e14a2b1f6bd947840932fc6e8b007246de280a6b66bc ebb67251598e38254f9327ff1dc2336da5269cfc209a5476260da523cdfee0ab 712ae779bde3503952ef75ef1d4a580acc03e12af09a5250ca52322c94da1aff +856000 62a624ad49bb1908d25d7190f363019b1cb5f1a1dfb849bb50226561b3c60218 ba4fef7924ee2e26f271a49319726894894497685b1c81ea84e0bb62246c24c5 42670350f297560ecef23e4c5bf42c3bb72378c57f46ce6a8817c065b2ebb7b7 +856500 f02dd187e61db50768a596177bf62878130d15910ced1f4bed2d5aaebcf4960e 8e9e38e2a88d1a24151ea08cd82c2debc7034d5fa21e75f926d9a6c0df18d6ab 1895c5403923890bed2d912fcf2b6b7cebf2e23ecb8cbee27a27fd918633138e +857000 b2ea7f0e6a51ea74155d6964d732dcc4fc8a0b71c4e6837d1f17030d026da89c 8ceccd983eb05888198163e6a0ea44261e44876289a9effdcf3d377ccf62ef67 4d2efb8494121ef8f03f7fb1d43c56d67205715eb81f5424a52d07e0d6810b12 +857500 f99e644cfa949f806ea938b97d5232d9430ca11a51ecb0ed30ded90e6d4f120d fd26d9ef2f463304bb2839e8bdb3b5b0f48592e2cdfd043ad809292e22391623 793a973ea0030005c216afb7c2b40fd42f6fc269de9ccde2f7cd578f4dd1c4df +858000 9dfed199b5f19ad984111f21fdaad2d5d1779a317ba5982a93e14e37e21a2eb0 3da6db23d0fbcdc02c440eb755828b4a5c02fe77c75b153055eb25362399216d 8d6e1cef06e63fabe0db295579b2312868d74053e4197860ca17a57a28711de3 +858500 daf47ce2ce33b9db10011f6bd963bca3abe9b8b27e6101394d5516555e8e7bc2 4fecbb4ea28d764bd3dfdcb6571a7c6400c76c1e7f21a1c1407d057fbc6feb62 b8ef93c05f197b5e555999918188a148b5d2234b4560663895070dfddd73866a +859000 f6cbc9c86ebcd2832f2d0db57e47b611d187189a37f33f7588c7c24e2f2174fe e85af2f0bf8bae60e417cc65de17bcdac486348b40eb55da41a51e98b5c148e9 d8c4da4448c5bc5dee35365b15d3352e4a66820c2e676ebbaeefbb5aeb621603 +859500 11102fd852576a361c4c9a3050eb8d605f317f82ee78200d2a2820d8a3ff76ae e70ce2ca1c2e9b818d276254f46f0d6156003a8421ffa99fa8499a09a982e1dc a30631a2a3c6f5532794a4ef7104b9d087131eb039c83ae4eb24ffb2550f17a3 +860000 b0689ff799ad43c8123c38f815e8a5dfcb4fa2b2cc1d59dd08f6d6e6f260ccbe 60815a438a372d41ec3439f8b21cd8cbea71b090758260b1920dfdba4558f235 21801f9d92c87f0cdec4e499059b503970e4c47669d8c398ac549c4f8889ed3e +860500 6298a42b99734a2702bcc358dcf100321fca31a1cc547ef0c168fa83a50eb132 2881b992eca478a15c1d505d3b021e2f589d536832e98cbb90831b4d0daff767 65794277c6392e331fa20b893332ac9d755d33ababcef60bf3e1b4d97654294d +861000 9f8f6446a6df4ac6674a0639bc616fbf8955fbd7c5a6ae8743ae009340acc6cd b9c2b8a675ec2a9f1323f5391a81d5a2bcb83ff02fbfb94e1960eebb50033bfc fb2d4ff73be7986b8df82094c1e8ab7b52e1697d4e259bc2fac8b91c790b3272 +861500 c53640e61534d7de4001cc4f6547133d225ebaf607937c6ea99b3a92e0f1b445 7befef633b3eb72ac1897e3628b20540cb0cb51bc447fd69877d178705b165b7 44cc2aae200ec72ac2b1741928330621ece7a7a0c3b5aaf58da2830f552225ed +862000 1bb40c878bbe264e2fad6a6e523345390091bef9bf689f6860bd30fbd27ccece 66bf4703cd800c13edc3e67d0889df0c4694e2f6545c5f71bb0d43d80adaaaf3 14612a0dd18d1a9ddb64a1d068fd9c8027fdc9f86b6870cf7c0972ebb8048e72 +862500 464bf61e9afcf7f9418661d069ebb015bed143a3c53449e9ca98013c624c0d01 b858f8d0afefa1f199f3434b656587228c659429a9b29876139cbcde4a66d36a 42e9d60328738e7dc1a7ec7eb51fcfdd37ac65c504319aef0011ed50cd8dafcf +863000 0dee780a99a58bfd60c05f95db7ecf49c8ca8380b7a5b8ccb4c7c26229966441 4555335383dd8dc416b36cfdd110d6da87faee63fd0461dbacdb6cf9dc61fd1e 58a77e6126ee627594569bc946a69928b328440f27c717558c89f0b14d97c9d2 +863500 98a57cc44810adfffccb2f42f93455e1124e3297a8dd4e176b6367bcf864fa6c b16bc478ec16263bc8995541eeb0cfc6640074c65853989f7619f1094b48f17e 2bb84dd8577f675c40d2f79fc20f4c854b67a3e5d7f4226dc80e5923e48ba22a +864000 516c8212c055b610d7295dd1dd14e797a2b4ac025f1fd2aa7b3d26488f260a60 e221eacebb459d180c743666d691c11997995f6f4d75dd21613b75eed2be2425 28fca9cdbee34e8df75cbdc4f32f1a64a83042e01dcc24f547ec69fe18157184 +864500 2e8ffca67b4cf71272e42d524e1427b794a8e663b437c156cce8f9ad39d28b58 7237d3868b25d2fb9801de887b7c2071cf24952719c6170a6e550773a61a2170 fb67497e89323233970c4a98b94be927dde692d743cd0faa9d3134e551cb9047 +865000 995bc313381ad5d7799cccbcfbc18876582f5a82e25dc4a6bfd299facb83adba 3ea758c944b2f0be32fa7fb541e18f683734df6197ba711285bedad4f17d1c8f 9f8e354ed83d6c246d802b0ce027d31fa350fe285e736924058b5009f1259d53 +865500 dc2fb63083a52596b814426dc2577b6eca27f5e80b08b83776c93adb0b913324 007ae746a4a5b901f91e51014eefab59c84dbec3a3e784711d1a16df0aa04ac5 404254a5047229551d03464a1d5b86887e1c0a72de0e981d02865b83c5e9646b +866000 a1a4a61f9e30b4ac585c2777dcb066e543a3ff03ddc20b67aadb9fe8842080b8 953ff29441259817927e36e3a89db69fafe11d253509c36a2bd00805563ec4a5 94aa4289d06e9f12e46423e7286d041a63cda7fbea30695a6d8d8624e277794c +866500 44fff17033fa5e2f48afd1313484e62ecb1bfaeaa0b19b1973514abe18381d2a 1bee0d01001a576776d0e6113954449de228bd3f69feea67a11769f2626176cb a53e44164326bad1e2bab2c9187473d43d8fc1fe9e44263fc19e2ec3a0066d2b +867000 77d6f737b4c7b493657ef08c7f28b5dc43e3a7194b2e3193a37d1a931daca9a9 a9f847fa150f5881ffade66584ad6b5a741f8dcf9310eb808181c9c3e4724a8b 21232a978d4964960887fa86460c27ee153c25601fb63ee11502dd105da94c88 +867500 98da2413dbd1bf3e2d3d6254f849e3a971ff9579e78a4bb1ba192f61a1ca1bf7 55a4bc913aa643d798a0d9d29b5c31bd38db0051ccedef30bf4bfb2ae6210159 174d2ff6dbfc46694e7fc438a37fcfe18f98a2f946b9d2eaf337c77f1dd6a058 +868000 1e33271126faa909e8b77bfe4431587ac68d50716e3ddee70f18f4ba56509c98 6b3ceb03adfc3ed05acb7ca6a2c9822e0b183c1359826f2714d26fedcc8b779a a79c5253e761b325c53e7383becf3000e36b15268ea637514b84037da39ac78f +868500 b4bc5ab2d0f52588e8e154a831e92f9bb249bb30c4b6a4e379d529d9c916508f e1810b871f581727fa81164f7ba37242a0376aa7870f897547fa032efef248a1 61da85844a76502eb61d1b647470c06e0a7d1a9005b95eadec03bd2d16aa4e1c +869000 9db0fa91a26eb2c05272e50cfff46c7c9faa4d72938f14f03736c7084c4b2d20 e80a050a8dfd6c5d2ecf765f43222b8aec1a85232641c32583487753ab3107ae d2dd26abe610889bd4d2ac990a3f97030fc4acb66f63ccb3f4733d545820f510 +869500 ca4ed5b1069fe42bcf42af8fb065aaa98db119b2e98c23c8ee9dc823c46a0bc1 1f45046c69978e3a13a013d995a469a2a6583b18cabe3e48c5735a1bbe88f1f0 6adcfb05cd935fef4d4a76a7e0b6a0eff99ae5071f610ef7ade477cefd2a48d9 +870000 02da00fc2fa6bfb0027e8c85a1b92e919495b84e763dd57afe758df11635956c 8ff1ef73ea14756b421192b3f936ed06cc5a8f016c33a4bb8c3eb94a0a4afb6b b8a590ef2388d946e9d71c758838b56227a4abc719cedfa19edc8eed9f6571e6 +870500 04cc97d0004ba00a8211986f0fa13bad1cb0e7cd17e302242128ba5bc923bbeb d4dce041cd8b2c51cfb7a50864de5d72a627a93ea5f5cc4d837004e9fac80691 35cc8956a844e114e3f3d133a48e322bf2f8eb5b5d7b1d2a0e0a430f46546e90 +871000 8c46f91d61fa06dc47ef2715dd66a510f1eb909b275c85c0f8f914e8ef0e2ce8 a04657d974398377996f4584c23bf29a55085fd914b88fcc85bcfdee46c1f4cf 91bc499bb802787f73201fd4b19428be38b9ee7cda22e9c3a1f2c637cc8784e0 +871500 285a13a25bf27fd974c9bd32ffda2796ba46e57044b4c282331cdf94ad55ce0a c701e8a240d4dce38b98c91b01c0b306ea6c8e72c345a2fcec704f4af6f880a9 a58593d021c87cb3647bf70d501386a4af2b66812b8dd83c6c21cfedb42002e9 +872000 0f474790eec84e0216b27a41df528a1037767792657a3aa79122dc31caf1e1bb 0774199988a33ae42d91de34cf2c1450aabd65b62e4792acdd67ee92c9d617fe 25203763e4455c575a0871bf241d8b8d40fcb5ee4299262c68bc7bcaa36d3165 +872500 4192751ee0a2c7b7bebe5e6a7c60dfb98f1527eb6dab97071b5ea89fb851215c 9e36875819fc969d8b5f971bce6d1610be7a012a520b317ce574c1e24f26c0dc f39c114d1ca78036f445336b7b671ec4c6dc52d4460b339bba60711c75bc3f25 +873000 34692e36b62fdc785dd9468d43a0a637aae66ea75c592d5c92e3b79245efe449 e97152bec752a6cda91c4153cf191e6a04135a2d824a6ef8ce6d64f640a97fab 0ca6b7dff238551d4fb8495eb9cc85c22be5098f65245cf2da2ddfd4d4731eff +873500 af2ef369df933f912140c7a4ba01d3e33ae803b7b2f4939f8a98405fa4127b90 3e30270cf39cf279ffcf99ad4b0cd55c85872bbf82654d03f6a9a40867ceaead ac2375ca321b3bf357d1bfcdb51faf0664c89660abb3bdfe5e63eef55c14202a +874000 7f1cd90d997b5a1da4daac3691082770bc7bad48acca998746980f0b57ccf21c d7cba24bf85848378fbc0f655a1795b9baea22b97a29b3bb1b74fcbdc25baec1 2e4b750cd6433607f340cb88227e3d9dea81ad791931f096c1f57a9ba4199adc +874500 c15fe484c8c031d1327d24f1b563bae0c6ceb1f81b8c0b37c1a3a6d3ea9c12a4 77f11329dff67de4d40f655a73c71a76e4637b274af5ecadd6f8f2ce7e265d7d 246acefff1f0368ed146b59c7ae6e3c74ff4e2c0e99c996942fa9b109f5ca498 +875000 6d606825c8c4902999704cd9839f60f072743c33ef3cc8fe5b075e15ad6f521d 0f98e7eb858a741ea9b7f9260142cd07d98f3ef2fd0f5897f0dd1196506f28af b1c7dd3bc7112815fd1d6f4c8762dbcab3e87cab642dda4c9447a037d7fadc53 +875500 8102b25248d5cc9fc5e8780fa7782a5f37113d5797ec544bcb6164d922d91ddc 5331a1c3f2f1e95e9acc0acb83ef4cbe04785dc7a319ce069d252cccaaa748b8 55555d9c896142ea08db6eb683d05328b1d060bbcb4dc5aec81965a740737360 +876000 2a6d640eb47cbc93033640e4eece162640b36cf256a1cafb406e2c22f0c10fb0 34f34e19ede327aa5be14240436f18ead4abe6f226c1571429937380247402d4 ff5805c276bef1199b7adfdc679d716f30cc2aa8dd02c51a9c914f28424d4e1f +876500 61e5fae25c4f18e92e7adf64242dcbf6507a7ce4f1b0de6f2e614b8f1f5b33c9 3f421f95de7e2129353ef06a9f9a206639e0f5be018937dd02e4c39907b75702 0bfe75b21927d526919bbc82a7beb4f77b9d2fadbcb6c5cc4c7aaff6a8d185b8 +877000 46d077012ece5a31c29ba761425e6ef9d42501740db45016c8c5b7da1d216c7d d06c5c6aa3c05475f8a8649b9b6134e0c92301d47186f2c379e7b159bab2388b 4e8df3fbe81f73207daa1c4676347683302341edce0f2f8a1b581b548b0a8183 +877500 610a50c20c1661286355fad8c8d067e794b5ed61c14087d04976cf0f378e37fe 18141f4f7bed0308bddc68a7b897a035293fa9fdb074b6af3b271c2365a3d1a1 937748d05622215c2ff5b9c77fea03222d4f84e20d3da7b207d9d592db6c76df +878000 1742b73fe7c2d014484b21a1604b0a70dc7f12540d52b21ccfdc9f9ea72dc53a 90831e43dd3912ceefc00d3d544c3f26dbf358ff3b5d24041ba1f322be13d9f2 5e5d115c0010292669d3bf10702e7fa5942a6031319b29c886819d6edf89d56a +878500 749fec5fbed9d5446533f22f0aa36c20b63b35116e6005ca519f7fe1ddc76b93 a13ee98f76ebaece600b0723a6ae7f7ebcabbb86e6beb5c4b9e5cf3e8170dd76 53c82882fac1f55d23a1cb58b7b975e28038ccc395fbef1c5bb2d540ab011157 +879000 8c578dac00d2b6db2e1972886194a4be70dddbceeb457150cf1b74ff19022532 627f0854e663c40920d22d252b41ecb60a4bff1de055d1789727ff33eee14455 798f54759dca2eacf858dc30221ee3dd23cd3afa0e10ddfbc85f808a50690f32 +879500 b31016513fc56e8df0eaa71197462492482734a9dacbb0d85838bf4253b70b30 854e8e0aca0625eda1261e56697d87244c1e386be8d6aa78f15de8de50a76169 9e39462f5b988c5cd96dec54db1283f98a0d46cf6c6ac25632309fc9bf32747a +880000 e0764e8169753f7f532973ad4706e5f6a07e64b7ec10f64240c91f0d319f485c 4e1ebede695c7ee95e4442814a5d98539df2ba46757b95d8ba4f0e0e437bb535 65de64495fae8054b2af0ac5c24045fd567d2089526c93176bf4fe641884d9fb +880500 b72623a454e91149046f522d60935871a1e5f098389d9cad4086119732b5e3f6 580082c91f04822d21265dcbbf8c3d3a0866171acf5564e982c8386ae5a3a40d 53038b71554abb4f5d16a454e1c6694f14de3166eca6ba6f61e5603c663760a8 +881000 b94687f79df272c2c5e85e21bff01136c5e99576571bbb8a635353aa9b331c81 8f383eea1f9a3014c27cc3c0a6196b0764c269a1f2f3effd31f4f6b76d2a33a7 c0efdd9fe63174d834d1c2a5a40967b61a2e38dee84ea431cf1a0fcfae782ba4 +881500 5ed1eceeaeebe16a0c746f796507f6b0dde6da8c53f4e3502cf5a49f4ecdff18 901bbb467df17a499475e767cf7886763681deebd4bbb537a4bfc7f3dfb89774 2b42e9be5adfc9057532a7ec0cadd242e49c8b225d85f41b62e0dae491d43960 +882000 bf12ffa015864c59f04c80d0141643c9de99f79b79c2b26ddf9bc398b9d8bf32 2b7b77da53ad2a19f61e3aa54ab5833bef79cb88700e51189ce7b1ecf001a2bc 4286a5d81097b7e676a6884e65333957554da50fb15d8e400aeb5c938af843af +882500 c8e8deff1d81c65f2b607cde0312982b03523aa76c6562c666c1dddf223e7432 ee0cfaf5a0a284a4e324c4725bc6ed5499cec94d170baff0b955ad6b2a2eb487 6fd53db43f079bd26b9bfeedbb5687bad13ff05c05a38dbc1d1f8cea0d7bd37c +883000 b12011d25c4c08da00b5acef266ab9e451d06c2fe9c65e4f149f7f0bc32b9c44 9b06de94a84c8e550c49947303d058d4a93d898970d50b8be9cea965ca656575 030c738f6a0dc2eae18976ff9c86d99d1e3ef4cdb492ad0b2183ffd8473dbece +883500 77b6c306c2410ce6e03c825d016aafeeaea3daa7172111085ebcc5806dcd3bd9 01d7719a498afa8051f872a3e8fc32cda3eba0e4151fc16722c0944d8715a6ee 4a16d0e045c3df58b454e37a884ef89ce882c51c0ef3d3418ec42ed5350353b8 +884000 1fe3f4911ede2f37d7587640a80408092c044904f44900ce1bc41df2e0f887fa 8e9b706cdcdc53e77915c281b532f0589c649a80fb563bcedfa8fea8493d4a67 f2552453cdbd0281c8cfe49ce64155a6995f5d3421635e73f8cb82631e92af12 +884500 22d008aa6022144cf5b7070e91a056b437f105ee9ee3d343c2e1eb485afc55e5 90404898817c93e64a98b4919df62ae8a21e4dcc9bff13fb563a33d544b9a09b fe71a783991a7aeaecfaf21841596e948752f868c6c9b8957e9bdded0229b95a +885000 0d39372bb9bdadcd80ce022e52792bd5097a8235cc9a571cffa92805b0d875b5 bdf6ea092c4bf488f836f3db4b29361eab0dd0323add526c9448b115f5e269ad d1adfdde0b4fa3c041dbbc9a11ffe1f2d6c3b130c6b956395b0c422de8d00bda +885500 b6c7b44b85b84f3366c87bfa92a3a5d047fdf0fd265d5923726d1edbcd823a0c f6d9bbdc568fa107333196bed759d22eb22a2e101d3fe25cdbf88b74272b7d5c 46e3ab90c37dcebcb162ae85a4d8333fa68f12ed87e6432a66017e149da25bb7 +886000 00109348c7d7187a543a4f45d72c842076614af9f5ee0fe37ffcba6510d429a9 893946048c4c8954313bab4b7f2ebbbad527fe54993f9055243b83460cfd2fb0 b2a6503a4c9ae11366d03878d5e8b95894c33ff03a8adf130b31030c188d9ec5 +886500 c50a72846bd8f0fa69fcae71eca2dae0aec9b2582896ff54dd2cc32f1c91519b 61192422f9fe7ff5aa553363267310c447ead236e9c8798057c3b22f4e32ed8a 847329db8444ea7159e364ca10364bb63ccf41ce6bf4362f4b7a05b51ecd5fbd +887000 51902324fddad3458c70670d38df58410ce98950a70fcc4aba475fb2a4c10554 b4c451e8d6f329db4a0d191970be6d74479b4df4615f1d576589a826cf025fda e83d6a0542db0eaf77408e75b749df59425e58f3a8604cf5c617e463319f247a +887500 576f26ef969d63688e1ea000213b96aedbe715cf97031c64ad19c0e5a0f9332c c1ae2f4a3337bb92b30c745971a612af9e911d78bf9503f2d4173d32ea3e2a6f 2952fe72cd55224af4aa3fec9384721c1014d006f324c559b12a81b51bd785fb +888000 a67f9a20265eba880a4615aa5ed2e62c51dda0d707b65f45eee03b4fc44f0e1f 87877dd3894621175bd850a8656bbb101ca98ddac12d54a86af38a08684fb31d f3a75bdef56bf863e6d727a4211dc6d5b58c9e4591ef246f29578cf56a236fe5 +888500 ffe36e4c302b226917ba2587b586115115ccb319b79626fb739ab1f4e511f048 0a3fe9d179cd2bebaf9f4fe064c9c6addb877f12a05090709f2abdd570b36ddc 0219907577c432170e08eeb909bdf1d39d0deed3f411840f007408549fdc09ed +889000 3fae8f764be49d5fef337a07943d3419f749eab745c5349faa81aee4aea0a638 14c98ca1a85488d6878125fa5085d35c8373a461ba7458e3b689a54a13153f84 340fa29de6407586a958d38626af76b1cd4f00f2bf41099837fd1e8d3bd25809 +889500 49a7936fd2f10c0c1fe2dcd9b65a0938fd4ae50f7c4ac195c6084fa067f76919 b971aed9ab7b39f4a9d42d50c714443e9be5172b9cdbb055245695c28266ad53 c99cbf94433fd898d33815bd970d3b96ce1665eb4eacc9dcfd6050ce1d8bc8ec +890000 761f8aad21a4501b257bc29b52ebff2e27f55b0a465fb5497587ad11212b98b6 81e6670cbf8594d99c9d24120c2ca70574834637314f6ca75996fa13a2694810 e0b7cd5afbc69a293c1c554f5f39c2a89f8302169553477476e6d46c2055c5fe +890500 6f040c12fce7f3e45c6cf2305533ebc2e740c7ed5aa812201372447494772b19 b79f97bf1e7764c569e5cdd10751ae56de90d41ee4324f9c4b51ee3603852364 5a3507ecef5219bb37e23c36b581af016bdfae7d3392565f48747aca46deee37 +891000 945ad3b937d8e0e0c8ca33a5da647d1019b9c8e37e0ac4337b66fd3e3a3cd09e d02331f0631f106e84bdc9a77e5e4d4ff4f3456286b1eef2962dfcade867522c 4f06e91bf73d2c1909e6204d14a96761e1f56b728824c7b1ef2cff95a95fdd1e +891500 118403722d3ba35113e3d5406abc1daa269440550145bcbd0272a84e528da03b 90f9f71ce4b26c8cce5558f04e9b842f539ef65f16bf55de4d7003d28b5f9c8d fda330db9176d659ff4e31d71a14d6feb0267dc30553e8d91b2b48d9dadcc45d +892000 80769648898afb23defea7a20cf1241f584c76ee5637cfc7a49223cd53d5ad76 ebdc74487afd6fd4c963f8120e760ee8b8f0f8534cbf85cc28ec67058c642fed 4ee3c316f5c26a26a9ade27054c6fda8ebd758ea0909d18fee3f5073b20befbf +892500 887d6de372d68314ba865a6a1bc5a431e2f8df673742bd2fb7e11b439117b0c4 46a0ffffbd5887f14c94ac1c232f46304cdfd029f1871b1a30b704fd1378b949 a7d421ab4cf79ddc2b33ebb0a569bca25d8cf0eaa7b390e6946ceb3a945facfa +893000 8b0bacc43bfc87581959a67dabb72df9fe52ff891daeffbac58b0581403a46e5 5c472f2d80c437716aee3cbc3439ce0b4e256363248a93b5d1adbee71d77690e 6792f9bcae3ec53b7fed0d070ec6fadeddfb929eb4746f0b56c6eb5df9509d83 +893500 961d3fa31e522bbdf6cea3742ce5b8646b3fca603fd44daa57f5c10f830e4071 49e19baf811717ab81e294b95c8eeeb5d96fdd1a4cb26fda305046aeb5041207 0b7645e62baaf6467b665125ed34bf47a6877b6a1ea16dae2fdfe1f1e10e7003 +894000 cd17ae71de5a09dfa983f6dfcb13fcfa6d6f242080ecf3be722c72f6bd7d402b 9a26285e49feb36f6ae744bf0e89cc91a3b871339cfe538b8beeaf5ebbf54fd6 76f30d6a2811ceb8c7788e7bd3b375e86688d749c1229dd7e85e233e73534302 +894500 25fa66f74866b3b730f3fbb2a9f92d3c705354e71f2efb2747f8ffe1427f494e a37b7358d87c473235c3731bb985bc698bf95f6cff9a5d3e225e4d1ba1c668e5 875d3c2e15ee2757c420b7d38e239c0c0a1113a7c94299cb08f4b44ce0e27ba5 +895000 50b47a9ba28ab1c5131ec35372be0690b9ff7c5967a81f7d6d7d5d7bab8c34e8 c6d808c63cdcdc412b9318270655cb0d37c315957dff5039d0b018ede34113fb d789857674b0158469cce78c39349de4dc4ff43914a8833b690a1c326f44f72b +895500 944784b12fdca39238803ecceb354bc4e8e5d91d4279ec25792820866d5c3e5d 21129c892476213ae6df19646a942694518db3758cd2916e38b4afe436d0be2c 9798a519310c9f896214a005d9a400e58a2c47b099428177d986440c7368b223 +896000 8b45a6293b573820f4b798c57a2144f7d94bd2edd02118d44cc0c59d4c92a5ab de0a319d296d3e88d7bcc46a4cfcf93ec469305122840f5512114776011cc03f 92dcff354a50898f923f899fc1fd3f44ea41957679fadd7456075e25193ae39b +896500 c3303636f08723508f17d63f0d376e9819e7c537d96e7ddf5bacc5cf02455287 36654846452e690e6b833d5fc2d4b6d402c5fe81754332d35162ea65b1ead7c2 e0798392bf6afce7c1ef3ec91cf696b570d12651d25c7c8185c5104760ae09a0 +897000 6cf1a830afc57e6d8549c8197e90839f477113278db181bba75a3ccb3cd0718c 387883d5fdf2362515430c50fb20dbbb0ef24c387c3b6fd4f21be58102f4f20f c14e890bf64e617106ca77768787a7d29ef1d18e254b29217982d432452d569b +897500 323544c069e43993ba59d272db7d92d8857855f67cecfb03afb9fc6495aaeb98 b006d9690b7a362398d09b5d5066bd8086f36863295b5da7c2a113035852ab00 cf5e1d997aa0c51ac80169bae457d5f49810f5d7b601599e2d1d682cc93823e9 +898000 e303ff088305156ddd6d2b5d0c239e459d5175585902840d3f6713a40b2490f0 4504065e186d009dd784aee6d957fbe295c8eb1c3bca23d860a92c6be32a9e16 0d624b8f5443456d6afa38e9d8f65b44e63bdde4857b2dd7d86a79657350ce62 +898500 4400aba3a75afc73ab3f6f8328a179905fbae533dc9a75a67e8533dc34da8281 f78290551a6f5db3989f2c6f6087b5746c0419604cca77a8bcd63268455aff2a 493c6c9538fdd84f4a7ccdec7da1656bf3397863b566af0d053cdea28ddf4429 +899000 30d2245ee16163dcab5b9b71fd37c6e0a1a5a3924f621dc4bf2213702878da82 83f95bf132b64bfdc4bd75ca04fd972d5caff941d36a7792f55f478fe140972a 828367c69dcbc2bc8db30bd6a79fed31d5b0f465c1597faa85b9fd0299a7253b +899500 f35505a5677e09578cbfc9c7900bc40b1add13a8df9f70781a95b00ff972add6 a71b0bb9f424c20a026bd94aad9922dbde345382c0751bb892ac7cc9cf0b9722 d6831c7b98fe9fe24be7e4e5e01e511c9eaea623a3c9378acc6f424f4675ed31 +900000 e37b70b214a685698666a18c3de3362baf0bd158b6f972e77bd306e62e7e4bea 7a6f099828ed54a20b3b9565c1548ce0fcfa4de8c6131ed4caaa629d96e17864 5a5155ad28208bc00f7e8cc3e48057f389d7e52db71d4e98ed747b4a58838f81 +900500 a2473a95b679ead1011918bbc526ef833ee8b03a5aa3f3e11198e30d11d2efae 9736c820b1d63362019d39a77218d604205e38ec79a117c117ad12d1dd1f0075 eeffa6fee4c89d0b7bf4aa5816c8f2d5c4bae46c937fa58f1815c732aac2de4e +901000 dda19f6a2f7a7da12753b2d7c334e3df7cfaf74a44ba8304b3c5f5e05882afc7 bc0f02a893b0609aa80e08392cffd1ad14ee3b625837d16be6869b5e405139c2 4c98b101813e05bc7c83bed737947884c949e7b299a03b9416e93491b2b988ca +901500 5d1585d8239afd15b1028bf7deac725db26ee14e9f611aaa8f972b27c8f8dc6f 6f02fa43604aed757759d0116918538b094641c0cb9f66d75ccf62458139c5d8 5017c361f626993f0914476c5a4f192e258979cf96ece6e0386868c3bbc2b49d +902000 433e97c928b52d4964e08193549e6ebe938a665a0fb4bbea22307bc94c5ebc73 6cc41a90d5140aece6e637d823cca6e4bb96fc7317a4d603c72fabc7f6239cb6 db578775bc1f54616499ac4e819baa4b40b4e657b5dc18a5b1e7ea6e1b1cf918 +902500 4650e5d627e8526ec617f4f8c5a31bfb8ce3c6bdb2d10cea58873bf361cad4ef 06acce13e151648075467370e9bec6864b80189ae6efe4e0e94a395b4852fcc9 09b574f8cf4cacd2f1fcf2ceed04417defac847baf5f2d899cc0af70cf99e44e +903000 3f9bdecef49c48d9d259d75cc8d8de5a09baa6b51aed59ac4cb9661afd4ee856 ecb871b85f6e41259176b80cdfdbbca72a0e5831c0ec4d42dd90cfa361f2ea32 938cbf36ae75d4ec793c8de82183e3e2c531f28ccae06603932618fd3460cd01 +903500 38512db7f3d831faafa2e27c548d9f10e08176c8745fceeb56a59b4f1ec16179 cfe52056c802d202a734e35fa3693c77a8ba3a8f0774b76b9b2e9d962687003e fef1cb9e1986f58d64b1ac150366784a970b91c84182a5a2c8abc26f11a240fb +904000 56e1e664a1de1e2f3fa285ed05c87b89a1db02aad29d4aa425d4491d6b502bff ffce9af2a239a9b97ab7f571269255fbe6bed14ec448078aa1315b1d7d823467 c7cc12aff57434310d7d9d93a4114775b738f01c97c2918ec204ad5283ede6ac +904500 62ed0214dee8bd914f40e07f60d0b42c2838e060aaa771b39e3fad5db4aba3e6 004bdff9bea3fb7de4ed18cb1a546bae626f03adeda035d47fc8c6c7d04fce21 d94ddcb97d5652096975c7456f98a99f81c2d4a7924d5ddb2728576fe5317f0d +905000 02c1fb3064dd2e906dea5b09a9e9515ffeaf4a8e6290d213adf0328aa310e023 0e8364f05dc947ea27a36adb21a97604d9e2fac67508a098f1c147968b7f9341 c6031e17677cb3cd881166acd24b301964ad7ac0c6744650e8abd7c11fdd2454 +905500 013be02154184cdeeaa19e1e3419d4dd5f63991ad93362a2b4fa2e49039e9beb a12d791cfad9e6e291441245832cc82f7887902d4112108b57ddf584ba71d122 a88ee394bce510665579b886509ba86417e3d937285c2e4991e17f23a814194d +906000 3b1787f731829c85e9888fb9bc683df92ca34b636a1aa2878106d04e4d1ff448 bc52cd21978e040a67220c44f03933086337dfe37f69cc3ace07f5d8ab1b3474 7026fa68a8cd65d8f0a228b08dc1f2b8305b6c45626452142ce724ac0b80603f +906500 0be9d3396dc9be557baf880730a8c8c98f0d008ccad020b54ab2f4d3ac5b2bf2 79047ea467c9ea723cf97796ad295841d72b866b1e9b925fe363f99071eb9ec7 0c791ca86defbe69ba22fe652e8d99edc976fa89e9d816c33a2d5e6b68acce15 +907000 6e80e964c740b9b31d2ffb3939b60f86d019bee6af9c3714f3afb313f659e9da 9fced4419a17762d628a0fb6efce506270556b2b041eac626ed03b923e68730f 9620881fe0c84df16713e0e1605a1e25236c9fdbdef5789f17b67f69165e4a18 +907500 7f70ecb783d1d233ea3f331fc823479f0478d4ba40e0b3e25bb5149307e688e2 06a68c9ca8e4e9803d7d91072c7b8008dd77da2df6f1a329f071ab497b16dcf7 214ed849404ce6d70a5f2ec0160f64e2461235ae3839eec2d51e9175e09ba4f1 +908000 1bb873cd795e98cb9b30c692846a31531cc7f4ce5a474a50bed96e2061e65e17 0b269ad251a90950543ba4657bd0044258f3bdcf6c50d4aac1c89d87499d1aca e1d891bb3a149411fa39a8075fd428e2e6dfd32ab888a949b0ab3e9405d881c1 +908500 c57c7855c97f82ce4645a2addcea5145c98d1cb9553d56ad8909d43a29bdf320 b97be283db5a293ad45e219ce5d9c8287118d7daa887e25eca7914ecce5b5db4 c38048c0bdff948f1b636c072fa4af4b83fecc54ea561ebc74d728b402f173f2 +909000 340e921bae13e9a770996bfdc6b30d21502a9dbd0016d2cf0a60d299e01b55c4 50d0d76f836bf9a1f6c807cfc9512ce2621a7f8e8d3215310d78222eff1dcdcc af825593546ad267439a73e196ea826c12d3629235be6b1e3e0bf01a550e1a3b +909500 bb00fca39de21c9b3eeaef52a0f3ed353e63f041c817977b6339f6fa1c127827 69b6dbb417be0072ca4ceb44d11e61569bff4161834baaf439361c0b17eef028 c7cfbe1ec7c40047bd9a460e7eef271a77c32860b97baec14cdf274d7f46682f +910000 355ed393bdcd6c79964e984b96df10eac86ebbdd70652985e5652175230e3f24 6be87fd1fb578588c43235926805d8740eaf1fa271ed3ef54e1b830a976b85ab 52e0ad64384b4dd7be7dc9fcbf4c4c6999935f4fd6ce4f2bbe018567e5324c8a +910500 cebecf803381bd5bcfe62dd27d0fc46b34ca7f14ebbc463ec770e6998a1b629e 6dca0680947bdb1ba9f6f2ebffd1475d18874ccc79ec26b75134ece99dee8c04 a441f43ce75437af4af9d797d3ea8f3262ee86c42eb2f9b6d35b8512aa6ac652 +911000 0fce8ead8161e060242c6f7a6003c4de749dbc1194d8efa84dd22daea8cceab6 649a3e01e83b89631a710906ed025cc0f67e8ea52f11e0b51ab3f8422a14de46 9edca6d164ac003f15ad325e06f42763d213bd339161d67cc7fa053d0eaf3903 +911500 6e60193890cf91c0dafce4c0756a47c2d57b70b84723bed083cd3af287d82435 b12f27c0626739460618af055b57710d241bf473d10c209edf8b10300d64a119 49014d1f75815a2ead4ad7dcf46f86fa7b9434c22425b7d7ca99aa970f273328 +912000 c612c0ef542a4a95bc1f45d8b5992c5bbd499a0204d057fc5c3b8c6052b0bb48 ef4f90f0e2c4a627416f8c7b590c79a4d030ce3b6ef7040fa8dfe20d9b1341cc 5d9b94ec08ef46ab128a48ed2e40030a7fdf49722226c0274def2c0bc1f63334 +912500 4e8c07cc191bdca3f15f8e5e8fa2a0ccba376f23dc9618991f9fccaad35b1694 6d2cf50ef5fb9c21ed59b5669566dc625e1a023ad3aefb75351c4e96a2df4222 6af009dd536d8612079da2da7b7971c1faf48f858b860d1a90f3925b8daf033c +913000 fc9fafc9d5208d6507d92462be6ffc8b3acebc7d3acba2bdb5f5b1afae779ab8 bc2b997013ceeba576521c5a2dbaaf429b9d6eea2501947de4c696c2fc8083fb 72a6ca802a448ab77bad7c28b3cea2ce9b8363fc7c978e2fad61345a686ad16e +913500 928d12b4332252e7216fbb36d4384eba4ffd8bb79a50667b3fc15878c7deec76 49d8085c3c7a8477fcdb80af39c1abdb69f5a0366e0dac79bfd30439b2f293e7 805ee656d505d42bce2998fa67246169c9ec1f16e745490f1db09c54b1c281e3 +914000 7bf600d26589f7dc4cf0c68a9fd820b4709e95c864c379b4e5175b23d518091e 6e60fe7892f34d0eb38229ada52332a8d1f0d120de231e404ef18f319adf5715 ff1d407a33016b5ab38fabbb6ba22879805377114ec6adb19613274459e156b4 +914500 8e5cf10113f76678cb5265e293bd0365012f0ae661e58e6998005c96f1ac9869 5df5fd9760d67bdf9708867bd15b11fe60230e125abf2db4500fd7db945fa6bd a933bfe1c6fdbc8d339369b5277743e85487d751d3dcea4c2add3e7cd1c78d08 +915000 33ddfa347fc55f5b299363d8b6bff03dc1d98ec1041236e66babf4023d3d52e7 8a85853ae490805462a8aa3700c84a276cac17603b3dd0002c54490842cebee3 cc0b6ba00675ca7088c7c4299286af7e1cb4ef0a98622e8109fc55cfc7bd2dc7 +915500 afba8520a990af275a8d1f82de844c793547432b5c6941e1b30859513098758f 06ceaf9f70d81c901054cd961ddb15b5399fc0f19235c048649ff24bf916f552 2f7ef80ddb64ee43f85492f1760fe53fa72ae703a1561e4d06aa1fbb3e36953f +916000 fa8e0f7e4c73fa9914b795af620ee52434bf37fdaffba88d318af058830dd361 41ec81c005795442c4705e943715065eb89cb4b32a2f38a311cf643b06880d79 6d4b4d0f5a8c1a70bdac3261724846e02fb94bc538276f7f17bbd9bbd0914ee4 +916500 2b20f9d73d4c0af59212b3bf8383f845c95baabc51df6db044ba80fd5051eda1 324489489a55e3767836aac9d5b620f5be775806ada19f27a61671a94098f269 b87648e56fe39ca53538ec9c51d0ae98bdd38dea3049b54f0919568ebc5426e9 +917000 b7b20466d119311d1c85ebe1ef60dca612ee14b87e88d633fecc679d00b959a2 96843566d7519919c12ee3cde2b4793e7043a066f63f3dfd690638d3b3d2bf5f 128994409844e5ed3e8d4c53cf3f2a0f7ba386a88cbd21bcd2798642da105d2f +917500 624ee2db152989d3e86cd4bdd32e84cde6f8d0fbc556561bc690c8d64d95319a d043c5740ca03cf42a53e4f8abcc96dea665a16acb738dacf29cccd3721a9081 b53cf73a34e412370b6c793e3acdbb2ad92cd6ce6d6cf91d66a5e569b095b677 +918000 eab30c35d483b6b8d4ac7db12c139b294c9b9aec8d4c0db627f57586b3d1f6a8 121c7b5a220fbcba9735c6ce0425ec14d9d80f75bb498a986684c446ce8ea2c6 ec65f599ff6d9665845871374ec58197d0e6c0d7fb2afea19d7eb81c4bcb2651 +918500 e9bfefe8932f66486d1d3a740d14b1fbab1fbf80b5abc9abb4af1333efada148 3909b21ceddd287e2b1d8cf16accff743dbfe6c2c0a0080a33592036cae626ca 17df39dc7da315f869c7c7a1a6cf1a4abc14dc56b4200c3029e977ec7f1759df +919000 4111e02c00666bb2701731d59808917da660228f50fad0d338d31324219fcd2c faa3d00c409b5cd2cac4bff556bc5d07fe901df0b3e6f1e1059e661f59dca640 f098984bbe4e46aaa2fb1830f5d28fb920997095d0de60b0c44f839f60d035c4 +919500 fe8ceefd0657909d523c68ab34109db47c31a56d96190f25eec23ccac28356ac dff9eadfdd7da200e3f9ee425b46e6f1869c2947d77eb068d3de8e281ccc9f33 90889e7baa5d936dff61a5953c5576e2877455f1f0d92bdf5d17084260d122a5 +920000 94c0c84e0720cf98585709161f8e0d52106a76810c36e8eceaa50c5937423e31 985aeea9e4d2fa5b24727c5bab4979f7c181d52e1939f5c1e9b9fd9d8d21ffa5 619a77f293cf5bcfe5b8e55422c347b1fe595d6a8b9380ecf51ffbcbc776f899 +920500 7942c1928c1c7fdce2a7f9948db255a58ac28c650d44f2cbb568b14b7e77a869 3fac2092a646a391bcf3f5a3703341b9667c9dd1800148346bf3d0ac8eb0b8f8 4274a21857221b986a03ab73c4106111e6c28de8d871ef01d78de3b3f2c8bd4d +921000 3ad13dc5aa84d6f0c89d4c1d4424928e1c3f17def687432e3dc5bc0d1f748e4d fc66d327154d4f892c6fc8a1a766917e137dd5ac1de66a8e93a1e3206318133f 4568c9acce0621cf48b4c9257deba3b99e91d3a271645605c2a35e654b73d3ee +921500 fe4b447119ad825c1f495dbb58a1aa394eeb40e6fa1de1ddf72886ea69042eee aae2951a99bc6f730c70d78dbb6486d95d432b7fb154696f0e866b5e661baca6 d546355aab871ec43391d1028847b386e92e2f80de62cd9140b01643738c74bc +922000 7d1d205b9c72f860b446b8b254d1c22a8e5a5049227ceff04424ff01761cc29a 9fca8ce08cf17dda9b4a2695096a50f5cbd54c8c11f7c048bad4e27c01a7dc9a 511a897002b03614f4138dd5c05605da5e8d82a1da39d01b1d58433eb69421d0 +922500 c16ad392838d47ba7fcef91e9a0be7cfa1dd11d22c9ccc0b6f631aa48abc73f8 01ccf18791d85e7a78fdc9e751948c42a6d58d9c4fefc118cf882c0a5bef2ac5 a28930ef1b65db143de30c76efb40ac8dba61cbe0030eab5370d3e417263f61a +923000 438bd2d6867e38f68f61f9dc64952993f7492e39771516520eedd7d5d9d4054f 40b95ef95e78ae4c9e99865bd4e7a4f7d106c8d2aba90f54aed550f14aa9ce17 ca62e3ac3b194977d03c66b015c7975457db5f6c849f7b999dca95161d06064e +923500 6c205a2902c4c350df7de4e96c6815eda103645b9181fd9e8bbd6e53b5ed843f 9d8c87504c9db8490188c7d8fb0e6aa1950a03a80cd2bd0f8baf0297a73ceb27 c3cdf41378c92bd85ca01c42ff115906b51ace69f122d3b1b6b4a5f922d92098 +924000 821de00a7dd17becc9dc0ff750b9e74237ec391e9e2effbabb71d33fe96e574b c87cec5b256635170e6428e3040000d705decb654b84a7ac9d1566211e18dd36 81890bcab453994fcd82bbe934219d642b127460aff6fd52a37c957bae1f0ca4 +924500 fc66fbb75f4f01611cc4bc86249e329e5f217ec40e0f64f332ef508f4d524fa4 13e45c01e9098567eead7d1e2840a44cde36926ba83c270e6bb854ff079fe864 af0db78afb9fd983d191c7482aef99fd8fc3f83ddc7bf969250a88db0cfe3e8b +925000 b290fffcf3f8eb763704f79a4a6e5fd76a853a3cd013efe2e41fafb9177d223a 3d9b89cc34b988fb0d1df0135f59df3495da0221277ed3abefed3558408ee132 ba6e53516126dd7d723c11edf28c7f60eea4c250f4d9183b09cdcb74df0496d5 +925500 3a1fb804b8f62e4c394b4fb34b250986d195b4a066238eec560443219bb06a25 3024ae8c2825c85dfe675f2b66b4576a6ebb934166dda6a12016fa8f79f12a63 4d687963ecedcad164e63649974289bbf8f463acd84b790b1aa611ce7fbfe681 +926000 819094082ab3ba4c3a715880ca1de8c9b7036d68224202838a077d1c48a0fa33 afb6ae704efec0cb30127cdc4c608245d88b3bd39e3f09b30273420046051679 471b7d7e14436515e046998af8ac65f3e9ed8339f31e292c2c1f793eee400ae3 +926500 eb74c0dd62c2e8fc7e9c45545e190d959a6ca29515bc7775cf20f2bce27349f1 13849b250174a3db106e2184f7621ea88b2e6b6fa4d36ebb2353cd7fcd0d4a12 1303beca265306318f19a0a0aecbfd784a5304ff9a7537051d14f78c1be44815 +927000 6397314f6bdd9ef003cc2ba39a4539c1e2267b13272c78b886127419a1edcd28 3455accc7f9a3e2324080e7691ba7134f8a6a3d6b0f59ac8ab1f8de3b1db976c 4875a59e95790da4881487d2e8f881cfb6370ea23609e157a3d3b67ec84ae8da +927500 5f1f6df5959482ae36d755bb88a5b2788a0f6e8ce6e2d62811da77c02324703f 044a874fd1df9bc0e384a192c669fcacc6946d2ed148bd5b3cae0eea0ecaf625 2fa5e7eb72e545b0de5970ea40f9a13a9df27a3442d71da9a75aec0d47c10160 +928000 3ee8e52f1ecd00dfa60cf89435c08ffbbfbd1e0f9596541cbcbef38c520cd71e af25521212acea8f5c894fb0e2c0f38a4abee868b66ed124a77980e5ae7fd840 a839361ff828bc1035236d946e156b9f683598a5d432024ffcc81b4e53939df9 +928500 c3f4c0ddbf8dc7a91e5e27e3bd4d8f817d18ce724d9756354449d7894f96cb7f d7cd61faaf6d8e0b362aaef72304bf0d1d8d751b1fdb6e8c11482fa5b14c2045 5e37546783cc6392c5658a293acb1e30132ab4c77ea58d328c00a9cd663381b1 +929000 73c7f82ac5c353490479945a8e5a3528e85ba4276e3c7b5b359ed66f34006d68 9def4754e80ad70729276465a92e65e9d70a3fec02ce46d76a6b748bbf19180f 5aac3534692f0996f5383d9cb8de32dcf0226b872a9b1005b855f7eb86693b81 +929500 90838c6bda7f6f4a9964c3b99caff44d656fde4928d526d7b761aade9f6c5a4d 43be3d47189799a47edbe664a2e9452e57e7ecf8f5df272a5090552cce912ac5 51a31579edf889149fd632d32a9e8f155fc2a73aed2d375f0069e9f131f42afa +930000 993167ee131ed2e0875b7a764cb7e8651a01b44b85b4b40c16cf8b69f0754029 5183e99bf7bc05a09fd514bcd646aa16fd040d8313d5c2083291d350988e99e7 c53da68fc001a0f18d5850b88a9884e899cc09745a8fd5001610458b553ff45c +930500 53525fdf3fee3ea4bd860ca7185365312b74dd8cc1e3f6397f3a467f2fd659f5 b08fdc19e65d7ba7a01ae37de9db8065c344f602cd6811a6b0fa7efc22cc9ef5 8478d3baf29d721b940b68501c85e0d81d566f89e56dc19188e44be9d3765f04 +931000 310257cecaa31778dc0ad056b4d0ba181b0339630bd9a54f1d2c01241546b648 e84fb5af344ef95707e5060d1675d11e8b7373524227fbcdfd3a7790530b9eba adb90dc53ff35e4efcc94cf3e4872059e549ee9e0062ab9d12a7fb3fd3b04b4c +931500 8f92f22fd3d4d35cd69456574605c6463abf15a58bafd4fb2144e58b2ae60bbc a05d6abd0dde92b9e65dfc93c149ca2f6ace7416efb996cbe4a1eb31d4add968 b04d9131cc6c34eb0c55d962434e2a32c9352d4767f4305f5a4ee212b7682a3b +932000 975a067e94d2f89f81945c70161dad251c93387934c9869007bf17f9f8175f66 38b53fea2e9bf87fa3f0478da19edae0de9444e35605e064e864f441c6531ec1 d4906ec70a0e2883a1c10ba3dd6d14b9b01bc52df11620685df1c7e2f7b1f515 +932500 438ce459632f23fc45667091be8a8a4247f6f83500e46805a7a63c72fd674b22 aa7fc841988e91577fef8ed0b8b134e9261d1f8afadd12aac3fe7a39129cc393 1cb0e73b74af2b1db898afe065e49022ccaaa178609aeec1251189133fd48ab1 +933000 07ece8e5df3457f385595c03d9abbf7b42654e15548ee72fa01b7c98d87fd654 de3e7b6128fe92260b645119d9aef6a57361cc46ae6328c4752cf0feffa7e93a d6d5794e9583f01149951f860cf2fcdb80a563e78162acac5282a17b1af23095 +933500 bdbeb91240264a917bf44b878b92c09c6a15005a39d51bd7cc4d6d401e1e4319 ae3181503323e70a8fd2a11ebc82decaaebe409793fdf43f8fce394b17dad188 f8c6efd1358c3135e3d409b5801c521bb0d198ad7b2b3845bf703668fa08c2e9 +934000 f3bd01e5acae46dbfb3365f3432ec1c81a2cfdff7cc6affae91c109ef698615e 74af995d48d047894f0d544423ba75d2018f04d928c6e7e468115bc9d447317b 0a25e2580c6d19575df1b34a8a9d053a69cbd3ca7e47ee9dd5344cfafba900a7 +934500 d1518129840b5977d13fd42440c257445bb31944c177691c8204c6babbd58f46 c270324df573701c0b3e41267557932eb7fd68e46d96f84e1e302b6e336207f2 be679e077ec214a331e206447b59d5401fdc422e20362aaa83cd23ef1cdadb6c +935000 00f16b56da0b5e21f74c506d5d2a1d7a10f4403e6feda3b75b269b93a7b8751a 85b16fbf368e56074baa64cfe454fcd4d387dd2a3e4e8dfee7de5d65ea7a423c 5b3050f09ad3ca761f65bd80fabee09db49f2f20a99c8f22d3b5c95dd7462296 +935500 bca2a40ec3e783714d2dea107f8a35cd01ac37f845d78181e79e88d3770b9192 99a2c6c0e33f5dc75a98b39100a26426408944d396bdfa5302fa0aa8df340f2f ea65eaa05964c10969456e95d66d54e70f51904671eef31309dcf1659173a7b7 +936000 03e8bf996ca3565405d01cfacc215f59481b90ed44d2b8329379fce0967290c5 7c6c2acfeb309f1fc6132fe8a812310aef3840b6af2cc1928394be16105e253a 0e80f01c0ef1549e7ea13ad275af2cb0353e5415e44a5085d72c9a3e171b3319 +936500 36b9b71a5a9d854eb5456a8df936d8995f40520173c81befa852db9773a1d26b 53733cbe7fd5a371c8508291f8d2ed3720b87838f3f15d3db8c16656f722b5d1 8465a44a4efe2c42bb8efbae4cbe46d5819094f9096cc3bef9727e9a9056438f +937000 665e5bb5ece8d808b906d0476716f2fffff168696bfeca1b5483c7345f029a7c 801b0c3ff2814d875ba2f1be4f26abb060fea42ca9190a45275d13523103d015 4eec03fc9f6315c94faf8e81ccbe7e9b840e42d991cd9ce72d1f880c5216a095 +937500 89c15cc1d22a312379aad5255d2c965ce9d466a9a308052fdace9d955878b03f e1b6c64abf2b80105d8c292532489650af97b6de6b6362ca8d5a090e3fb6e930 b729dcdaa9799ad26958f0407c569a6ce6b6272b1c14bbc808b4a90e2250aa70 +938000 69263892b7a2117af68e35c3e6f5ac6de567bb84d10d86ef9492eb31cdb78e36 1db7af4a0cf53f0686e7ad7dcc15076154d06e9fd8ca256fef101fd82a76adda 1b744b3a013f3f3af72b65eddb918a11cc791b26fd4304e2c35b1696c7d70660 +938500 031638da90c052d869dc3da33fc044507e0831219ae121e416c10cd8ff5c25fe 2e94ef6c5ac4720c93b9389a66cf999f22145751f58cf13bdaace6d5b1735344 62380acade3dcb89b6cc458982cb9c760fc3be1455f7f8f1c5b8281067488968 +939000 342f820c0656c6e11de2032ca29247575c0121d8414c63e703c486a5662fcc00 e23bfa4425b2d940da54a62f26883b429558dbae605a1a762be33a5aa18b63fd 17f7d790a20ae0a292ed62f76f2ac831088effc15ee2047156658e51b779bf58 +939500 250cd72bd19b23ca51479cea2a7a9f4bfec67e343e250cd67b6727baee2d8520 b2514af432838f255641352ff93268b990c0346997e2c11e93987dbffbf50344 d59f0df3ee98c60d54360adf42c98dff754cfafd18d21b93ab45b120edd8a914 +940000 1fe1cf60f5e02ab75067eae08e3f8c71e4cff03d232bf2f2c6f789ef49dd134c c4b2e8af2ad3c324a01c586f22be66a30dce34d76e05c9c8296b6391cc143e44 5c5379961483368837d22746583f5dcf50022019c71fa3f948429da2a4892f7f +940500 37fd0de5d9900234dafcd91f2800fedc4bdd5f5f77c6091c5007ea3f5091e834 257db0f9e944de6816c015102334c79e531decc0e89396c49ab043143d557ae7 b752eabdea95cc3534b2f6140ede29ae47192a7003c09537329346847ca434ac +941000 6751331b479dab2a45ccab32a8df6c5667df8717d99bce3eda9099d5a93976c3 8d3c34ea9311963d4aa20cf0c35c17d5556c926589354d474ae4f89fc7610ce3 9e17d95145857f43e5cbaa9dba6394406a1315a9823688bc1a3f75398962b600 +941500 e20ebc38059a946e50e5779e069d3598de8677e2974efac3aae5189904ec9b2c 7d08a1657f10154b398f06cfba601c5b8cf68d0a70afb8b1905ea8b9e449ae43 f808b65efeb9d8b9cf630fedebb42bab2965bd29f45772423d1dfc405e29f7ec +942000 08b423776e24127b4db2d00a86ef3d23defa5a94ee9e8a8d04723a0061c80d09 94e541a46a6d4c989c209f262c0c563bec8a6cafa3bf7a61e1bf73008a3ccf90 49d866b9bf0ea648408347f88a07486802c1dfdbcb7c4b35165fb57de6f422c8 +942500 e99b00e621c453bc93e1238a8de8af078b2cb639f185a7061fe7b1d97c66b6b4 0fcee30b06113c4d3b1f019e57cc19c5f448efa689f5a95f041a715c115deea1 53a1e6bbf4b763b3730c7fc78a48efe5c79f6756157b2bedd17ab55324c1284f +943000 dabc19a6f8952c1f8c2b4a6ee8540d91c59b54a953ab93071f026150cca356fb 66da69070bf359d355715c3f66470c0711470eadaf3ceb1ac80648beb4265b5e f0d29101757acc0dd73a2270f7ef6068f011d25407d85da1d25034aed0fdd069 +943500 efa86ec88589aa9853bbf58b7a66708f52d72b32a43901253b48ef89fdc68195 da99ff838ba09c7843aa05dd869311fc058e9a266ab3cb560e4c4ebad30bd6b7 df2324edb9840ff91b45d2cd4769a4b57f5e4a9a1fcdda6f5a603d94f325bafc +944000 2f594ae136ca24d6d073e29d4a7278134ae0fdb782e823c2fe6efa9ba8c053dc d285a29599828a65ddaad8acd888a3030133f8583f5618af616c3637c3778861 3080c758a77224e44ba67c0667b77fa366310542f5b851c04b994c391634ab68 +944500 c3ba87169f55a8669f3f2c7e94df26be0afb0e810104dfb2fcabfe40847eb644 e028eac5db8fb1a565277f5587d8ff105a3f4523946a20a3cbdb16e7eebaf586 87c283fdcb34a2cbee915f730f72e3368b4cb47f6abe44ebc6fec8caaab96d74 +945000 5aabdf7dbbf96f3b9136f7891335b4b4d2ded4a4ef4b15aae24400ce7eede6d5 a791d33db0c6c72fe407c3141d954c7b6166964cadecc7fc7d9d70a05c64f5d1 b532999fd01a92636e0004fb99621a13161d561a7a3525c6b24919008b50d00d +945500 160513624bd360141f9f2aa0b77e15f2f78adffde5408688a3f5cf2748f5a33e 1978fbf063588d8d5c669261b70e569bb5242c67ea4b896e4fd273cd5fc919e9 e1b29ffb015db13c6f12925809d5c607b39249f5f5051b90d78f925e43a890ed +946000 baef0350d326a00c5724bbb63a3a7d12a8463d59407afe8cb775f3282dabe66f 3a08925e17e7c91fa44526b13304a55ac9344cf0139d6b2573fb362efbf6e2e1 12953db0d841e911244a3e10f9f971c035e714d9a7535d1057ce96b2b25a0200 +946500 3ba6204f144b41e18b5f571aaddd7591cc8a2461790e23117eb263def13a409b c72dd099c929527f4916ed7dc0cf34d3c4b98a4ea8f488be7b92980af42ba4d3 9a967079f01e44081c5349fa42ccbe3436afab5acd9474ffe97a0e9b62c29c75 +947000 1bdd194c738e7fdf54249f73177a6c78104e06133d0fd97d2e732e86752d53ce 45f323adec9c4eee2e3ca82bbb2a165a0a94db22d3d700dd34688fb2575343bb 71ab8b24e330266c7745fffd95eaa3842ccbcfc89ee71d944cb4f394ddfd7f00 +947500 b99a2375ff79648c98fa232d1b0fe37759deb5826866853913e7ef1fe2eb65c2 17dd7cc2b9689b1b4ac97ec835fdcf9ce80cd5728d2d5d2a14883e382e182f51 b6e255002349e934651aa29ba88b523359aefe2c587b12b9ae5f315654e2ad06 +948000 de7bbfc82a59fa0c6691020204c4916b9b102f66536e061a3585824472bbf2ac 2de0049ec5f874e752ed146e2c7edf63f6095e53a8a349ed06c052a341d87e1c e9f976098892480b5662a211469875d3957bc09297ca5445ec32118373d80d62 +948500 ac2e0e3c131538ed118a3123795a2fe51803a11c3b4b08a7e47981884b2f62cf f870ed2d50bf25f95cee956ed54551f4b3e92d54abeecc3f0aa5cc15c5b10a80 9dc10ba06c9e3657acda84f512e71e2623e92153f355fc85f292efbd7fd27293 +949000 e1e69e1b1b21e4f0a18b04ac9cfd9f8285db96ff6f4e9ba2ea5a454d7b4a51cf f08f455608a96421e2c42c6fb44348331ded8f44536def80ddc2aaea53f811be e9fc9f8f87793b08608e8537c9e2ff487a6a0371c40f601076866cafe3819747 +949500 5be555320df6b2e99d8f77952bb45df07ca3f9f1bffe4a4800a156af93d0c629 5801c09b3c3ddd4fecdc69bafd4b6ed5599f5b4c3d480b6cf9e319be1aebcad1 77b78279551add5e0960ac20f6beca37c1a18a3f4d8bb4afa3ee783d5e05d95a +950000 e227fbd4fabcb18eb1e600e30654fe09de863f77f81c7634c2815bdf909992a2 5c5fdf4e2450ff02361822c4702cbecdd0cef3c818ec819a8ada6c7791516396 2900534be4fa7b504bf8f6a1047adeced6250f63dd441cef1e1d684511f104ac +950500 9c0dd1fb0034c4a92f5b77bcc7e5818dcccee55af147ec6edccd499465ed8502 94d3663c2526c1645a1e7430614a665a7f35183275b7167c5893d6b1fac7b530 8ffc20f33c23109237f1f1fbafaa719c87402f09f90ad22c73cdf18ce0fa5cd1 +951000 2e932c87fedb78048a70c47b4f33425ac91e5edf91ee12421a4dc6675c50b084 2b9e81d117f74eb48f91f5ef0c75c345f0d1f8685b2caccdd0e739f8a4d54d04 aaec22e07e78f82d3fd5336adfb33c5cf83ddc95df01a0ffe6624bc222724d80 +951500 3d14b8f5c18082a279d433595fed521d134c844ada0f144595bd1c6c271b02bb 9b6803d021c36acac84246ff8e5ecf486a40de03cf3f256b91dbc1020c62f772 09f5043a2a9f466d8ee91d7cb61acf9ad6d16758a27f72adea3eb453a968dac5 +952000 f1d7b3035d1b4a3ca9bb76325f8e09ff28baf0c0bc02d6d02f2f12e09cb25bf5 336abcd43c7b1c697e751756f24bc499eb5450d9d6adbe83b01233a73587b72e c7aa3eb4463829a604d2d46823be735ff9f47ea78be069a25ea75dacf86c2a28 +952500 09ddfeb92d32ba800b9f715b8c2148d283e4fd0bfbd1d0fb1a32c2249dd919c9 a22209348a5e34a49ff2a9dad503299d59877783d47d5ca6e770a29a07396adf 69ec74309f004f52806a5b3158f98aed9b4b5b5dea08339023515c54d50e991d +953000 613e697f705fac48776f20e3f1ead078e683ba3b5ad72ad9867e14be2d28cecd 5d74a3b0feadd5f3edbafc529ee8a086eb81cfd9f8588e12ec8631eacb955600 fece4fea60c77b3c982fbddca9895e9e3c24e6bbd5290287ea15cd2c3cb9cf20 +953500 f9ab20889ab4c8d6f7dd46411b80f89f3551920684d8e4b1d3de88a5dfcfdd6f 3b4c8c9739de63889bdbae40394a5e0bb12b982a5159e01c32d005e31ba7b4cd 9f322ff3e4fcb73f3849b552fcb961aac906ad7e7c368917935b302f75f0e99d +954000 01471d646b617bc8199e95555f46f2893e97502bf541dc6dde371e0ceca8ddf1 b805b91fa492fea176eb197c88526fe225f18a52196cfc3da37b8850eb36e4be a011d1c7c4af6cf1c6ef8eff91a62a1cd8e7908d4e880fa1c69509626e42f0d5 +954500 c26bbf96a0ff7d8d6ef2d2ca911b2c8f649be385be4f526753cd5776686f9683 e22b003c8414dd5d24dcbd5882705846e7391883fee7252d2f0019d0f066193f bb2c86475f9f60c4d5904eac230f89dc03ce58eddb0c7f82a79b28d455ba4a92 +955000 2812f54afa9234f02d0f89ce067730047af24ee14b3c380024da7a6567787b3c 3a796a63e0dfc3baaa249d05553a993a4bae85c3ed54b183adfbaaed1a1398a2 4ece14cb9ad276c6eb4bbf4566657fc4eeaba0b5519b6111db5553520c024d36 +955500 9c05768aa95ace543246ebb963ce1548cd9e5ddee7a6f5e45cce1db5c47bb2a7 c824fcfa5ae174f199cd91ecf2ed8049716e6d7dcedc0cb4be2a3bae035aa6ec e13affedf873d26bfc24d47b9d4d4fe5a3da26c28f84b4115c97a40287c89920 +956000 769586a0e2d78803ddc48d46a6477505359896a7b8070cb55076d142d9360ec3 69a7018a58df10204ad1f874a7d652185e74bbd75d6e6b29dfe6bce759dfe945 4f7f343a437f4a9af6f8cc6e5c2e355d62a66df820489155e67877303cfd688f +956500 ee555f15c4a433b4ad77468b6dad7560838ceabb56fe1e67076ee0e23a2e5aee 727ffc7586197dd0e3929e7641f10fe84c5b7c1255a4075496afa76cf8a4a473 1bad79baeca77e98f4a0a127d38228b7760aad45e61d26ee8782c3d58a6e7a9e +957000 1df30e4f986c04325e299cfb1350dffc76591f9ad53b40ab249769b38a1488cd 3e689b1cb999a8528c0fb90fbe51adbd0b90f6237a80169b49991a25caa86fea 6d7cd9894e43299c76779bab920d5956d7cb69037bcd2daaec94f40cf6413a4f +957500 0be5166150c2dadabff827efe2a7e1760807aea08f7c0c5855a47e9cea4149c8 b8c9f5d0a6b7baa4947e6bb898ef1ca502c6c77fb6e1abcb58bad5451bfaa94d 1c35f4e7046e10f2c100559833e6f7daca3a51e8c81a1766445607d0a58f5652 +958000 05d2d2d75328dad0ecf43961e0b52b227ef311a18576b2a2c58f9a1fd4844aec ab2e7a9c7bac8c39a3bc96f989afe46468975542d8186cef457c9ad8adbb876b a70069a6c9f4f0ede4c3342ef63b636fab7adb0bc56a3be09c75d1e37d329e28 +958500 a06d333eb4fda03d0e2cbd27d8d415e84d5da63d7e5db371e0d5b2744c32e625 7b093292ab44a6f779b5ed00cca79a1bae4eb79de2cb150b9ed38a43e7deb57a aab451b16be52aa2546d2bc54e78980c3aa64532fad80db5a13b4c8114faedf5 +959000 ce381f9253633f9d2b48b71987f9827e5b8d68d09bc55248badbbeb85ccd33dc ef5fa33efab771f5175bdeb4ad9f5a0e6b122f02d47fc5dfcf950d467778a23e ce46c78c4e93e8213f768527501def929bcb568fb266d4c331d09d7e1f264ed2 +959500 c6e95e1ea44b4e47cece003fb1e8da01479c0b41de18ed008e1f6746f208b75b 9b6c1ecd301c7dce7d5c3f0da8c4e1e7523570aa387c8f3c5006a55117fc5420 9b915bd62d44bb84dd76c96adc9468024b757018674fae0cb26a576b357c4637 +960000 bdb90de7a26c79d8559d48f9cf9acfd272a2ebefe86c78e11759a9614e5f2400 5defaf36aad68670ae534577435596269927ebb28ff6daf25e7992863e048ac4 1fc928c303d4f7a40e4b9ff2698575fd8978fdff1003850762a91f103a8ea0f6 +960500 c8394c48d68806fade6e2d1b27fb16f1db969be718c19151625ed723c4d782c4 9074493aa1e6b8327a8c725279fc67b90dee31ebe94e9e2431ac9388f8d6b7c3 2895f1f0145a7df71c22849ff4266ded050bf8fe5adabde369b398212acb577f +961000 9177a28ac1eaf2190c6d3e96bbcfe1ace9cec8687d91c5d1ef6a51d3133a6251 13d00e3d155f0535894a8a170925f592f63112f285d5859b05119a90d6ef06b9 95ca6d7417b662f691b371faf949de77867de09164d2989e32e82b64f557b399 +961500 7fc9e7b2460070aa7de93a059e74f220dfed6ca9d60784f305737f4924067658 d688c89a2e08e78cf11cf0b62ef92e4969f934a53ab7650a09b3178693f9f4f1 841b8871077a869cf1eff185f6290f379832001cd6f36fb545ab9faf6fcb1517 +962000 92b750fd920737b637e87ec6ba242570e05c24805a4c06ca6adfe72de1cf3cca 79ceeaf812c0d470eede3c04b06ae94cd14e3569958bd0e7ae4ab4583f1652a9 717002615460b13db543f643e27ec120808571bfdcc82199e0e33599cfbddd97 +962500 4723dabab6846111db863946410887489b0917f28b6941661d38150e80045834 2b5b5f09f42e8441a73d1d69ec1248b881401b23610153724bf4721158a8cdf9 647da4cd89fd11d38c19847d198e921f3e538f5adb7d283ddb9338dc1ad0f5b8 +963000 e7718854b1a117c939c705a60d706adbab7bc1eb29e18b3fa86f6f7052a4ff5e aeff06b67b31c015553db2a96db0360e61d61e3ba03b81622a2f6535540bd431 66781cf92c355b1c2b0a8d17868c0c880ae5dbff1d6b29142cafbfd689f6f50f +963500 64755a7e2fe737d5c50c0294b03ce6f11cb5ec07f55e42955c5e0363f371c5ae 3d5d8c6aac6ecff5aa8be9a984838046bd6a8c591e0e179ef9e171b1cb04869d ddb7bdff3758560760df753779577f8aca0f4fd391687cbcfc4d35661f4da2ee +964000 59bd046c3893cc35c97f871dfcb03988af640790f5b81bcd37720fd13a4eafff c0dcc142ef875e0a37f250ebc98a96a50671a4f3e36868d2b6e3782be04c275f 0e2accd5b8254d57a052f5b8de81d05393e019939bb667317ecdd42f47d185d3 +964500 6f0dce76e2a057372de537c19e9cf8e89261cc24a56b30bd3cef7d9458efae79 186d6eb95874086c7dbede1decbe52e2ef4f9bd7389ff5897d40e5d63e4fbb97 5bea9aa83277393356b825cab01690cde995625091b2af3d6634777fdf6896b2 +965000 6e7d4ade21bc5b59d50ba629a0bac97eba1ea1c22b909d55c62115d83c48b0a6 9ceae7a7c366ce13b5903ef59ee5a940c2f50eeb7ed88e1b5d3fe41f3d5cc8e1 b00ba8d4828b108349a7326d13a4699d02013b8c683f4de0e1d5ccd9e4e78cdd +965500 07073df1aab61b4e7d6ac4e3a47cb41266476326136ae32a17e63da2df0eea3b 8bba0ae4edf8a31f1d3f2eb3e2bc8cf89913e3588470c4c26002cab2533120de 05d2bfdcb4dd59c20b9c54a59af159a75bf0a3ce3d3b8fc18690e5d4053a0493 +966000 46de91c0817c0802081c0382a111d4eb0383e64cc412e20e14925ca8256da92f 4da17f7bced7a0672c7932fffcc076da613c82178e51618ba0d051897294a49c aa5c04b7225ed68ebebe52fcf6120524166bebe68416e7265f3e0a56e4321111 +966500 5d31a7188d2e344852c1cda1fca474397652e623eb5160cac91f0765317e1157 4dd7385532824e90376cd8b918f5877e7d65e7826a55cc5eaec718f9959ced59 19e82f194381e36df76799e88d4e71f32094dd8f109cb4157d3209bb821924e3 +967000 ab1b701b49ea5a3d698a37dd97453251fd53b70ff008b8fb6b34d90c30298e07 f4d5279f7270a1277967be4076aee31ea3553c8baa7229456ec833a974713408 c600620b995fe71b11254415ab8d8496e7b09f0abea4f05c6df7cc3b74ad29c1 +967500 fcec3fe1ca40415a65df82b0587f4ccee3f121fe82592d724de22700399e38a7 c7fdcac6633aeb83f348ab7e86341906e3f30c84422c33b1352e96b858dcd2bb 4b3ca0d6ccdcc52d365dd33834e115ba8ad32a53d5f184db6880d00d433f0830 +968000 9b8ded270161eeb47e94caf849655c0930476f6b73ca1afc050f35af10103e47 3fd0c2e552084120e2fcc8b943e734d4bc1a60ff598ce4365fa8a1beec829381 3908294f574a60fb2de3e642dce1e1a8bd5854dfa7f71ab1c2f32cc261eae392 +968500 0845de27097e020706a6f139763ff199f0d665d00567812507bbdb4c4739a7c4 75003bbc6f63a32615d906f51b0e325f78a3281c706162f24d3468ef42d0b2f6 8658ed5f9bf63a9429749978488323a72c94e6d703b44777bffc09bf1d588bba +969000 f92cd5a018e68cbe9a7f4da90a101409966d441e596d102bcac073828c13cc11 caffbbd1f4a08e8b23273a4ab7bcb53ad5c1b80f73925a18268d2f17f930d1f2 4289e02fccd85fb8a0d9e981f24667346bf77eb7d49ce56b0580e4d363d27f98 +969500 b08c175b0d02a58d410f0d9bb296059e5478c58ceb35259b225ce26c58ec2ab6 003d4e578d4e99ecd8d1b569535e33d57e5287248eeeefaa97ad0487f8836f15 5906b9e9c0b48fb8b5349474d72c9726cda06d062f19e1cea40d2008c25824c3 +970000 391747367a3e4346b56c97953d6fb4fa89473d95429e93a75cd5844ffe846812 9af7f2fb1b4e414d796c5cf0d2324150025e5366e8db18cfa5ad7804956e4e27 029d6e6ae51f7d222928fc51ee95d099da8309ab66ec0abe1158c7c046c473f2 +970500 caa262b1741e47d85bf772b131badec7e12319a3ab8a617d9f57d6584360c2ad 293f56976cad2572a3c4b77266dc83d0810a915c1b9f4c4dad5e1cccdd715101 91ed5f7c7abf693f2d85551e5936354bd9c726c4698bf369036f122adb03f957 +971000 ac906e072ba4a6d698d5581a7ec46bf277c76691314d3390188e86b68089190c 718aa15407bea582e47710421ec160dd724f9905a088d83c7d240097501ca2b5 edf900aa75dc112b7f2cdd5d3f272303a1c6fd0b7e2d89a2cfce1d01cf410206 +971500 dd461c00d3aa9922d31abdaa8679ae8bbd75b8aade9a7f9e0bdd0174bb81318e 6d4cf414e86245695ca9ecb3a4bc3fb9b5896f3348f4e9ba916daac9133d7916 8297847fc9f28f3b713a386ee24bf660095dc195e891cc29ed91f68adc89b081 +972000 099e80a3f22cb61144d56175c2e423681e9d5fbcf8c82743af51019d0123b21a 2ec23f05afd3c6f60376c4544414f84617c48f368b3c1a1b7b90b060fbd27018 cb3805ca2213c239b20d2672cddcaa7c436c2b0926928a2ea3cdd482387168df +972500 eb380990470813b19e97939e36bc7ec145ed5bb84a5c15a18f53d8c6c399f626 b7f9eafe3239574d3c22e39a2d2a62b471b8a7ea59c8570b206fd2d67b23207d cb9fb936cf97d42acb845a2358b526a9692279b55591f876c22393094f1cf143 +973000 55ddd462f4830ae58cef001b80805828381fa6f01763551fe3bf41c47bd06e33 48e54fb3fa548f31b6b8012129886ad14d438d0e6af6a05a82230ef00d80905d 5f353708dea02d4fe10525399c823d4a027a07834457e02f86b31404ce12bc09 +973500 0a3ae4c2d5937527041e62d202f1f3eeb575062e464a3566f6e3d4e9811236ba 5fdd512a86c7668309807bdb7146dcaefa13813bfe05f812935dbba0c7c04d62 1c086557709d579b3773cfa821406e79327a0140967713b73241bff2a2a28d08 +974000 55e80cbd096b8eb1df3fc9fdc1a4db0685f135deef48c22236a3be1df8d075af 69b5c8b41f2e5b28a329e3cb10293ba29312c252fd97e2a6e9257b2cc225354d dda002ddf0995fd3a122f864c5c55971d5590d465f019685337502e34540dabb +974500 57983b1af96d8dca16423e30c6feb4451abb992c59eb7daac3aec47f0c10404d fab5f619f442fac58344026a8e3bffca1b547084e5aea670cd678ccf1e4f7be8 a3859c46496083689d30027b40cac019d0daaf008145d6f168139dc7fc696bdd +975000 789decbf3352b728ca2513866842487ccc080040c301c20e219a6169af17f8ad 8cd8670e216d098ef817bc6f4ac83b0de623fabe5b0bdba2bd588c28b40b7b04 bbb05c69cd49f0bcf5a87329c75f69efb90a91b5dc0ed931fa22d9b41992d3c0 +975500 e4955374301cd615e606fa045946f8e1b09dd05be8d4cb90ea334e1f0bb9b0bc 73bfca0d4522e57aad1864c6659e0906da259865cac1fadc2d4c8aed47f23a12 ae8b93c18324c8f49fa73de8bb19e75ea2c04eab0e8cbd71d591ededc819b2da +976000 911ee9db7be3ef0f0932647a9ce131e21d7eef9ac7c3a40fb9da8f3d328a3313 a2d82537257e03c3256edd144045b2767b844046c07dcb75122d4100830f7800 b118c6acb7d2f8a04d82083a9f25d3f87e468a7d1d363a374bf652a3db866520 +976500 82038a79a9cb494206fba58cc2903270b915d0396a2b3d2dcfc00c5bffcdccec 147ca1336392af0bc36504c629248081cc5abad35dda21a7c10be10d2850df55 d68b8150120a191dd977d13674e572c072bcbb5f3d5a97b637247f3ab72dfcb0 +977000 92456a662c9047c73f7083d2cb6a9bbd7f484ec5eca845c3a23362dfc9387796 9700bed9001c1f54a9193337b07715abc03c91d0da1da02bfba14cd22cf7bd6d 9b33fc4f478d2671e7ce83519eb04b8d808abcd4121b0d58e9a4f06dbbff03ad +977500 bf8914d9c6c6b33e67c47ff6100b7f026dc80f11cc6bbcdd91489f68887a68c1 8093398e5a2f391a3ef245664e6222069167cdf90491f84e9899eec391e01f8e ecb680d03236b5ea5bcc4c8d5903285869d1d8ea7785169cf27af41e05c5b50e +978000 b1d888e91bc2d0788175d1167c270dab6bb1257ba68bd0f8d1d57e19788a71ae cfb5b13f8abc2bfd9cbea92a9feccda90f4bdb96861e29d6824d6abf40088dee 03321ac394dea33fc18f97735ab2498c0ec6cdbafbb174701a9a07f7dd48cfe5 +978500 6e5e3a0db764ba19342ffacc3343df6000afc4fd7ee8aef59ff7b6e933017eca 6d5b50718e56fe6f6cfd3bc8a1c058b7c9cfbc7b6cb4701f1d2049e9401f5c7f d00f4ec5daaa22e9b41fb58b56c3fba59090027a0ebd111381266420fa4c3944 +979000 8ab1104fca85862d1df0ab6edb7d4a001962e612b427f7814b83a3e63a56ab39 e8b74e9b60ace577954c8eb0504dbf1b8e5c0dc057d438554c156878d6924a11 fc03ba57eba33fe7d66029fe72b9a52498a693ff39505a6eef822184e3b0bf55 +979500 4b5c03ed2fa33e96b1dd3be6646c65adb5bd35a3e70dcef17dc6eaef44f7512e 1c899654861cf5a3f58d764f8cea03248806c5de89594eafd2a42d084c546be6 cbb6af9ec044fdca6ecc012ae75ff33362a36cf379cf1de9faaf1c2843492fe5 +980000 d6dced594593bd65bdafe4f455f97c83aaaf195a195c327275d358517276cdc0 cb73280ea478de4ba35c27fc544edca9f7ff6bb3a0c1a0b44c17452fc61f8a11 c84997ccf6e5747a0bb3790f7cb8511294ac9d0194ef7e92882e604c5be0a4d1 +980500 a9b5fee48434bf6d6062d4c3f62403fe8882716af75891ee9de40c010ff4984a 50c67a1f249e74da33887c715d827f8dadcae23627c3c01cc3c86e2cc332d3d9 3f1cb64e6dc021b39e7faf2cd5cbcdffb17ca62fb55f27f513f09f80ae10cd4a +981000 e49a842bf035c8ba0d6eeff766f7674df57bafba5bc8574c7ffd55a1918f4e07 3352d7d0d6554aefd57951186ffd4a20906c4c9a562c1d85a911f8541e1f5833 c33807c5bab23c467dafc31f61378ce37b29bd31ca9ca3f75eaf884de1be4bdb +981500 f7563d6939461d13b3d2886ea0eeae55bfd5b70a2124fb1f99e3128b1aa57c41 ede14ce9d15b6d7dd03bf87dd1d6f4358eef1de87edde1b4189b5a7006242895 e2fe553357ac092e527000a26b54bcdbb8b9f5d97fa9760ca53a97d6a84fc35e +982000 4bce72fa79b9a6cc3a049ee07f2b153aa5de690bdd9177c60b9129d0a3ec65ea 790c73a90c7513fb9c6a2b0293739d8305807d61d8dd5d4ff607f8bfd385e96a 39396dc395f66ca2ff0628a1898b7cde9f618ed8a62f78a853240563ebdc2ab7 +982500 77132e20fdc5fab30cf9b662a7f7f0e7cf54d1cb4d81367de088f28a594e8670 2ee079db6a79f9348a2f6484b787092b71ed1bb4c1267d5a18eff8d4c321c14e b971f6a69e0bf347ee37171a52c622aea4594b876f55e0a5feef1d7339efddf5 +983000 fa83e50346e0ddfb583789e0e053b74ca5765a4240f99f02c80753b0664a2851 9987f99ab0e62c8c49f5b8465f24689b780cc9c016f0c7094a489dd6724ba646 158238bf3536cbb4d80dfccb792e65753254c2a912d4369e7c3c561a2508d447 +983500 4c65a2ebacb363949d2a461a6a7c0a2ef50e4318675f4f5c9e417fdccba4c8c6 62e4e5b983d0546fed593a3012c6b7cfa0ff96ef28ccc455142618ac4c7fb0d0 83bddf9dee3f3a2fad3355a2e96fa29cf44b3923633796e7679bf9fc0fea712c +984000 15b16b66f736e2f12a9324bb45854c9f6b49dfc6b367f346e772eaf8ea49f14f 46695fd3d752266cd9f1e6d529472996f8ba494f161a7194bbf05b1130e3a4ce ff43f975ce071a1ed4f4ddd5f0cd6903fd7ef1bc52910d12346d92aed2df010c +984500 bd9c47bb23b50fd7e77822c377f78d7aea793eeb694484291b8901322642c7dc b8d50e9fb564090ff86cfb90867834e86bb23d4a1b9f03ba65b3729e78a85aa2 8f48c1bb77cddba1c79fbffeae6b285cb02beec4a83dc652dd96e899f6f53aeb +985000 215551bd7b382b243fba86059c241a3315ced3cb6eebcec5d64c731a9aa07d95 f7bf9600e24bcacd6716ac7e79942f9f62f16b644aaa5bbfc2cf87b84a418494 11a27d57a9f743be233736970ec505fe97d6b54689b9e7ec9d67f83494bf2e11 +985500 aed846fcf07535b706e65ae53577ac77f106d4d196aa5adcd04d81ee2159f6c2 0c10ecc979a353ee4b5d050ec570f95c8199401598d09ff9009d0d7e03a7326a c44f23336baf563cc5d6fe96982e9b1ff10ea88cc5553682873b45a403d8db92 +986000 f273f50890e0f8125bd23c8ccbe22be64a280b6f293cbab62dd9e9482096a58f 289913c0b5c8c8c34c66bbbc27b602060a274ce12463a0d94928b37cded39687 4eea986addde925faac38e16e38b753ed03072b51649744f1e231faee489ba4e +986500 bb2726763523d72fa76ae25415b8e5251d234caf180c1cbc46684d30ec96c1fe a6322ac39bd1cbb2d2a6cff84e25e3e310e4e51c7f78aca2c1828c443cfa42f7 aaa5b0b41e877095f8ed5520b48b18ec2eabb6ddcaccac765e93d1cd19a409b8 +987000 eb16d2f4fd89294f684687a1fda4cef1d5d494324818c0c16b9e2b9669211c60 a922d18fd438b0b631a45cc52f1b35192e101b890e35787f60676d5ee100a0f7 62223de4e95a2037cc7789c5a78244a5e19f808b4e51c606ed93c2ca13416d25 +987500 d50c6155658a1707ecad02738b6557432513bf5ea78bf3a2e1cde78a3b672f91 95b19f76982eda85133625b6b2d8ed6ec049533d9a8f015a7d8eeea85ebda3ce 311c8d2774d702663337aef37b93c1d0872a6b97f0396d617dbdcde3fc31676a +988000 8fae67f15c83e3f5ce559fa3be81c49b47ea2923be52f8fca6ea76432973a87f db354947189daf8324430538ebacff70a48b80bb9fbc80e640efe5a0032aed71 d98ee08d71f3619599de36326036ef6871b0a8682a16cb8e3442d5672c371ff5 +988500 7c7b9d686c788f19718bc1bb0aa3add6d5071118fbf2a914d4447ec2867de02a f8360801e9268cc2ed86aa0ec2facf7d228bd891e0cb54a5ad7d4761797409a5 ad90ede93f5f3b0d1dbfa2999e5fc38387a13fbec9639924488e06e28588cf0a +989000 464836cbe95821ce2f4bf0ae1eb094b086d894130057e25703f109fd1f6932ab 3e3682d443a12d532d27364e2f7b6a5edd53eb7236159d859c5fb4b60315af05 6657ba0258dccdf0a18e0f1a9c00d8ee9ab04a245f489245739f953bff55ece1 +989500 29766a224c17b8de90c83325930b52e2b52ea23242192f7a3795120d43c6ceae 6d1e2b7a6c886b98a131cecee608276d80903d9f230f2486a7eeb4b094bf13fe 914a22d9a9c75e3a58d84e647b92254ea0e20316ecfae9a9fc008f4b9acc0a56 +990000 7a0d6f86cc9693e0a0ee0febca3b3f8116a2c1ca3e3f5478dc713b9c03f1286f 77ac7bb4b87ce136b1e951aefa132fa8e70566b1aa83e2b41c7e51b50f7ce994 d6092b1688cc0eae8bc30321e515588909de8bdbbf660ad9d88640936ef48419 +990500 2c605fb768a51433d5ff066d9e6736e991a806d3b387c873efe12b5edb30a967 19bbe2a5c3b3d2416b9219cf5570841f143d71a0fc20e29382eb6cb07901707b 4eed06211d950ffb7ee961e659fcdfa432c27255a08b03f0318b482205800285 +991000 13a48c504165faf127f177f7d4fe19e150c94f27e55747dffdeb035a9cd26c1e eb2aaa0eca1b723d685a29f82d8a802e81e53009b8f53d57f0c2d80aa5dd2c71 4a2be43058338bab0472df815550ddcc91fe47215fd487d8eed8c0fa54da1c4d +991500 d28753c20fc3c35531286a7c815604103662a182986e5f1e5f84e2437b49abcf 7f0ad9f3223bd8989cac9836665da3878a14b6ab705495b626bab79a73ae3e92 50b869e5f6dff40cd01214a3007802346924ca2d77871b76785f1c5687d7f5b9 +992000 86d7ea18c4c4d8ad086d71a384f12bf1cfac15ab847838aa2dd3dc2bec258f16 b94aef8147f94f009f2ceefb00902ef16cb7bcd31acd16633162dbad61bdb282 c9a821a330342d8ff2be0e177b2c903131359d0af900a81982674daf2f545869 +992500 e1b3cb464a21d2243d3577a87ffa8a5cf4f886ceda5c3b70e5142097b425fd46 4c934f704aab283fa3ae0b18dff434bedcd7c549816fa1e1a4639b6252ffdf4d c7fb0a4e7acbfa3f98f20a143cd49469577cda8968a06d094fa41010faf5e1b3 +993000 88a8e95ccbef1cf83a82690b89c170722120394b01ea641001a35379ca8bbae6 fca6247b8ee3dcb01af1aa29846486eca0092ca90bc14274d16d29c823abc081 155947c3a9d25af71c26e52dc2b3a599d12f029aaa990335a5a5dd6e5788dc1d +993500 c34e2bcb4c7ead30c306385655a8202de556ef19ced40c59aa14c0efac91e2ba 796047ec552f3417fbda0bb7e8b47476652a831590572051ef810adce0b28f9e 98cf236f8d3a23d8c6c1111eb2eb20ff080452bf3b9fe9689b3b9363ec39a770 +994000 d5298162e2923b179e6cbdd230cdcc57dbd74ee47f24b94467f61039eb9ea1f5 4b23ad485cf4edb61c5db401a01488b7546d5c9ee52f2bd3d9152ecc35212b8e 1d3efbcff1e39633e6b214f9c98c02185e3104bfcc32bd8a21e318994498a375 +994500 b0664adfbec0e115415ded1b9645a536b50ca6abbf6d4064fa0004b70fde8e6a e7c1d777900ebe2a77996f06d21877252817e02a565346e4d014b06c1a29767a f4a31f3384a9b9c47bab2e43b667e104c6b00ac9c108e7c523bdd75ae51958f7 +995000 e508ee8874d2bbe69aefc606873f503678aedf80f7d94f41d2f2c5dd03875cf4 86d2b0cd16d25e2bffc226f79d7212271480febb960efbd50258fcc13096e179 22e8674a9e44bd8e8903e6b3ce8aaf7e047d02b1a30bb87383d6833b2bb32d1a +995500 a707c4371079cf705cd28106444573df7512088f6ddf94529d3ad23a7300293c d45f3c7e465894cbf6ade11bec71ce70dbaa476e9883264398651c58aadad749 0cc797a364857eefb9d8c277b2d8797be8db1c7fa62a5cd53245b611f6d048ed +996000 f7b87eb786f79e735e906e314053d44ca9e390f3e95ace03d9210540bf481ee9 b97629b917bf0cf5d8fea9f1fc2e70c68b7dd5e26e7d9d46e39ab007e0d1da1b ac28bfa8f6b7579a819de912938d16a18c6a14559efaeb7dc1ef83d52e620444 +996500 b558b1cf6b6c8433c5800f23ae615142084f8f3d928a40e409f874aabbaca98e cced61b2eef93c36342b81a9d83762f622a6bd502c0cc7dd1c0682a4724742eb bce90a34adae9a39878fd3cfc9e5435730384e0b2fa9819bc9a2633fcb647eac +997000 caaeb7a33c8889c80539ae6c7630467e1f9a63c7ad7e785b981a407da287a641 670fffa544fc0473595daef1fabde40074c4f7044d4dc30693940beaeccfc389 e6074a488e39ea5fe55b094d2d81d69df4f8345ab659c773b0e0ed6b2f2da9b1 +997500 8e34f4d6d0a279a37c8ba482b77251ad9f7fc96501553dab0680fcb22e6ede26 302b33d0ad1a64fef2ef8930018ada4c3c5a78c1c73cb8000c0d7761e47ee10c 335d19d5356567c6c95843110f969194ef4232b690d543e802a8f25d3e03e729 +998000 4d92ce92ad50fc20856ea205479db25276de24f146f131b15a84554d0aa6f9af 3a0b07fc0edc28355ff8d43ea3394e609fef61e0452c1a6dea2ddf15c0ded10d 8bca7a9c18f2762ceb021f3f53f6490e33468e27a31cf4533e5b5f3cea802bb3 +998500 9fa48484cb1aac18acaf940acefb7e016a01f2758bea1ebce66a20ce4f035bf9 d46c0a9835b479ae3f11573929492f282a89d3cd81de832bfbf621c1f447f4df 221d1d90f07fda3aa7c8e95da56284796600476a866316905991083187df30cf +999000 ffc5bce237b717abe7ce11f385387313ecc2aa4696c69619a5b4086a53ee3271 ff9b6e5ab60a595494e3acef825047568620b1c43e8e6113142603e7b0350082 116c978b4824176655fc3128846b3b28df9290434a2920370a4fde4ea5166813 +999500 6fcd2218fbb6bb99a7ab3ee9907cb2d91332f8050a43f540dd1b927ea7406d06 125f37d51d86d8fd684971d3ddf14658459571bd6d21d87a2b8a29aa79946ae9 87e1efa60065b9e9656bc24787b28043c1070748c997f283a9f04f9209047f33 +1000000 0eab5112b99ed6e8cf660a001c42d98c8080cb6366c7097eea2ff77dc1609f37 acb74f062691fcec64ec6ed73d0a383fa41a034d58367c8622fec495427df074 bbd3c4e736e39dcec4064fc9f486826379d79ed954c19359e18add4351492c91 +1000500 d1def6c86921155cf5563b6f8c4ce542cdd4fdf9754d4000dbacadf94048ae82 6f7bd3d0026433254bb0ec777cc7ada57e9f10918a0a422dacb183d2c35ef820 ed39141222abf2e2c4760fa9aa1918da3433f32f5a234d7d5bb2e8f7c2f39cc7 +1001000 895076795aca0adde7b87924fa062ba68e78c47288b2bb85f00e7e4d49db4b26 688a346250fe2ba536b9825274d23fe3ab45f80bdd79adb081f2e94982a5e4ab 0ec7a8295aa452c6ad63eb016f1a1574e29f733a03cc0150bff3f7d7508f3ade +1001500 5c22477fdd5bd95bd2d21c677164d7f5f0af91b4e57c40d3a4455a84bec21e57 5ad71bdbeee74ce1a181a3ae5e6369ee464104bc12fd976ceb5f17c118829070 aefd21dba77767131d6f6915420636d796b0ac24f6fdb8762c2cf24572d25924 +1002000 19c686c9af79a78c7cc99f40e01c1b6ef8e1a2fb2fa71be9534627a4d4f9a025 658279857f203a5c1e707bf87d65c3395b687f8dd865831d892ecb7cdc8779b1 5c2450dcb64d2b8a125db556cceb9b5ed77a1ca3a30b2c20664f09406cd8b4fe +1002500 6d44ea79ca8224f60c6e406dfe9c7b459b253173288fb27fd53f2459be869fe1 4d4cf2b50e60efd3830b0e19de7109bfcca8ef40807d483e32260b1a85a2ef9d 5b13f594e0b2a6ca92994eed708582f53d9ada9f61e9198bed811e435e68fc2c +1003000 e5b417ad3beff6e4f8864ea986901adc70cb998335784643accb38300ba26f33 f947088aa2b8ce56cc93358c4049c034128ca2f3e67330d0881ebf49e0748f11 5802e8c75cdd661f92146dbd83df5409cc9d537f584c8c75d2f5bd1d14e49435 +1003500 da0ed4a993783299c429b78e8702b1dc731cb587a331106925a410112ee6a241 0f0c1c4ceffb15f8a875034287aabb36c185962d010699ad1161ec4a82f98367 0595982bf5c066b4b3702ef403a8528a86b0b4780f4b9e8384eeffcf84cfd5c7 +1004000 764ac91a87f912be6230e1b59065b818bed0579c6ecb1f96a17e7303de702b39 2ab1ef7f085464ccc0245b130d84641be08b8fc885c1f15960ab72e486834cb5 ec4e13722178845b613ff902bab5806d92ec355f5c05e195716b87d5970e5fa1 +1004500 bdb68fc38ebf22d68dc2a984407588ed9c452a7aee062317ed760140148b0db1 49563018d17110ead9266c3efd001ac2c0965f31cb08ea8c69b9309a00e08822 cad664604a8bdb4e86beddc02608ffe42a254744b1d4b5dabca93fabded857c3 +1005000 98dd7428557fcb55e93aacc5ce52d4685a9ff114e27777124371bfbb82856a18 a429996bc47364fab997ca87316cc079a62290f061b8495b93a14fe24087c49d 7f17f657146ce62fad541c45f668f193b94276025e6a04e6be7d866870ce14b0 +1005500 0a94bafc026c86b317b33f8cd2661d6494b8f9b01a6931d771505ebd80ef3314 37566fb68bc84fa11fa17c73f90cbafa0ab29336a0ff0f98eefa590c7426869c 1b237de8296a75ece190c887768b4f54a926792e26a7c89fce387804a3827f18 +1006000 db286315d07b3d4cc4de96bf6b344be65c9406c6186318e32d10fd8d66d5e3ee 2f1984d31cf7ab600246083e52855afac8a6ff5bdf62badd04f6ec8c532dc5c8 546af916a106c2231a05259f3327e1ab74dea2878c19292b1f9d3b26218a063f +1006500 7ed79e53672acebe07b0a25853c34af6822ef69078c94de86137f16ef35a39e2 1d503606be0bf1c476e7154c2d632489d9b0ee7f13138a1face4d411a0e6f9a9 e65fc30f976eb4cb8025dccfea9aabc31294856e2c4d9abf26cee7dafb49d413 +1007000 98056fa1e52b11ee70eb294a962ef9288df96ea4ad8fc4a5166a58ffa67cf650 a802403c8ffeedfb9de8a5fc863730e39a06c142b04b3b88b791f12b3340741c c3e8ab95102df395fc770a236e77676c0f6fc6fe34ea93c55cefb561a13d21cc +1007500 037eea45d7e266fe26cf97846726facb73968441f3c3b0b8f384371335ca8b54 f919c88493be76b460431acafe67adf6c2cf18ad72549b93f51934791b628c22 de3565e0b9070742b491b3d3a67ebdc0952f730b6489fc63063e462b43032d97 +1008000 0ac8cae34eadd6a2b2b4f8c19dbe7b81b3bd432c7fa84a4635ed19c8109df8d1 7859a5b85c491881a7bf6f3d0d5dd0c0dfe381e2d76295608ae4a2e12ad52f40 85299c1a9cef6426c6d1644bedaba75c49db2fd764620ad1aae8c10f173ac37d +1008500 903511e59fc4c13cef0ba01903a85ad56a60406abcc5804fe0021d1f364f35f4 be8421e49bd2f3e64db5309ba30e8954d1cf68eb8ead03f5f820fa88bce8cb51 06f71da713bb2705ce46479537db6a8761be15f49425a5013f475ce941ed8440 +1009000 0c4432de0745d517d1bd48fb5bccd988985d77628c45f9bff545834b63986ac8 577c73b6278b78665f4315543688743a5c49ebe86f63f985e9e7989829030386 c12a778e6262fbfd3a4fc18821371bede78924cc02bf047ac561c3e26ed6f3b2 +1009500 e8ad9cb3b8e542229367fc34627ec8e1f6e4847a37552ebe2bcbc36eb0c0d955 5bab28311ec5b559f423c3e7980a1d55e5c0971682ea84ff9d6740ff9ad43195 28339cac8ce5f3c0a9d7942aec12339e6d2b0859b8ab75da7c61be7b5281955c +1010000 8c8b963aa26439dcf83d0a67799551fc5fa3b1fce2261db4374a913e50745184 d3c41f512eb318d2fb9c76dd883dde048ea1bae997bafb4013950b582d79f780 20267ef9a3ef52b03185ead600467e4da83c9f38e12b1a4506c171b00f02e0da +1010500 f3bb272a4c6145fd3a142e85744d9838c7e1ea33388c5501b76f2bf3fb6f2021 015a4e570fa61d5b9cb0d8404f237d56571600de80f4e9291fd69b5f981a52d5 877442676c9f93153345c6e7f48af95effe054947b0ab611d053e252f7d4a046 +1011000 e99b3e7d03403da96fa17a760491b2e627324e6e40c99c6291ee2477325506d2 59894713ba320d48c79325fedf70951bb8112781aa32679b55c49f6739d4549f b967907ae6fca462af16a9cbd31411e867699dba311409bb93dbb6aadc4d7df1 +1011500 624b57fa2f3c1be8a6df1d8d07162b6dcbfe4d5b5bab6ae76dab199518c997b5 b9b72cce7e651a9beeb7a0af57e82dd1a11ff0fe4df6c7935bd67d10978b7b91 bd0ff6fbdb52c282d8b3c3e0737fc6c51883d3ea77d630648b8d7b90ed54e995 +1012000 1b26bceffc486dad37b7b8ec5822a388cc5b24d884fc6463963f1bb432440981 308612e9d27755371409af57a2e7bbb53d9432ff575aa742854b074c8ee6f237 afb1196dcf4ca82ae70800e68f6f822c73be51068e7a650b23efc56273ab48a5 +1012500 1fe71ca40d446eef37d4c00d208ecf6f503e180e6f55c68dbb5fcb9e3d2eb746 bb77811625dd920f9ca60331a354187ec62026d596a06f49bf6aae63ed72da2e e6ab2be9399acffd7fa0c63699ac1625d5a8c2be7a08cc67af77ee51ee54c642 +1013000 332859dc2b9962c6f20ba5af9d3093ee01d1e034e8c1b2defbd65e81154a7f6e de3d066931f8e54297a44e6e2d44fed5829456960c2f5aab427c460522dba461 b166f455541bb19e0fb02c42c1d4932da389b8ca6177f690fe63e14329e61c4d +1013500 0e4af0f0df0ec61fa3a5af0aec7c4b4987d876be19be280f8a3046c36bb39a5b c198a22e2903158000099fdac41933c8ab9e0690a84988691aeeb0e1d1b53904 1db107ead91e75c67e0db283c3e88144d100ff191a64f6fc06b4e2338eb09c59 +1014000 1355b040605fa16e26640135a12f9ca9643a6ae6020b951f0150898d16b9afb2 c3c21ef46afe97464537f553d7dbff58e4da1057936c6f19709e0aeccae2867c e015f4147b8eee74bbd26cdb18d17cf99fd65a6b2ff74d9fcdd29f28b73b4fd8 +1014500 d4600ab85513dc5bedd837d88720fc5b336b72f89fd571eda9004ad474d50630 86f43b00faca5b4a65a815f9ac690263cc81af330cb0905aa9f50f4730c1bd64 4e2f0a33340982fa9a725ec71a9b0ab676b0f765b22f80f0538c4d9c1e7737e9 +1015000 0a4789562092c0fe5fc900254fa79fcae07c862aaafae8b1f0506d3b7f7b5b7e 976a0948697a861f02ff643aa4fd2ac3852b0f694ce3ea18e764e18abd8ceac6 11fadd2f1d937abc4ea283d854c7a42e1ff717efe9b93f11c7d3a86bb92c79b3 +1015500 9288fd9c568b760f0038e65bd5d5bbf43bd1a5cef8b4e60dffb190c60a9bcdb8 4c5e0a487721cd7bb588bb15ca20f610071dd4a96c0f9445fe37deb3af4b50f5 31969127d7349880ed8012923c8511be4881e5843882fd49095364d577b13151 +1016000 a2c07ee8e03f8f4915f90146a752a637be7a64afdc7dca46a2213a0aad16efcb 90df13acf7e85c2a43369b020626cc6a16d3909bce6c42116a584dd65d119c78 1afb05112bc4e0006fc82dc1b04393b27f52dc57e85ce15d277b0abbc31561c1 +1016500 c6d0413da86d3ca6e27ec349e8ae3cc63b38c2dbd1b1efb4621852fc55264fb5 7621412436df2d39de48cb0de98fde07ea39e7a191055f90f18cdb05c73db51f e4ffb5c5bc611832cae9ff659b49223f591c0431e73a0d9775b0bc3b740fc399 +1017000 dedb9981b4c85b114905c98692a951e73a0620094fc1ec65b584c8cedd18f0eb 7fad3d8a58d19856c7a8928a8a7408a4174022b3fd6627be6c784c822c72e790 cc519b1480c913cfc3c2e7708bdecc134af59db0a4e20fd2a431bb86df483f47 +1017500 34c9ed49379330dc3d1ca58f018ccafe3c706093b428a115a18661040767e145 03e7ea37256d09c6b89b4790257a156030032361d9f850eb6c0976623330e5ea 615c957d7d2ac1c25ba6735aa7856774b36e206f867f9fc81c09594e00103f4a +1018000 994e4293d08d8da39b62facd7f3fb82ef95605a27acd3ea15e0da47a0bab0f60 3648a62fbb596b4ad5a0c655baf9d30e5580e9fc76d5dcc9475e18bb374df4e9 6ec66f7d4020d0ce5f17f6a65d9b450654300f17b9a8eb86cba9729c0251f348 +1018500 1dd630cd6391c44c85c78a99e80cbdd55e6f493d2d82181e103d839bac021a70 a39f7fa1791b102d8927b847d9bbd2d04e10b6eee5881f55760fe2730a8c4807 ed7a0150a145a9608fb11c3deb7ee88fa8a30a1423139e6f3e280cb1ef6a5089 +1019000 f7d9073afa8d925eb6f8123fb74a00f380f937b0bcf0ff7d95f1f5a42d12b7e5 98467a98281be59593e2f92370868d35b36f2d59e46e8c82935c0f2f3b7a41cf 07f67fe39f4150037f98e6c4bd29afed07313df161d151dd4a6a3bc90de4cab6 +1019500 67c86a37a72ecc42e218914342df752279a75c6116c931d6c6d36e458b423596 cac3f08697af498999fca9c3669c5133f5f152fc71f76ff2f0849bd260772dc9 f9ed9419820af0ec217a418b3ee8892e9841c41c20b074630407375f3d2f4286 +1020000 78531e7178c89f87b6b37624e82a60a0e6d6a81c7829de6bf0d96ced1d506487 f32a845743c254db6b95911b171cc56e7a1e569a5b859c605083d8f3c5725779 1b6b483b54f05f78269615e62bf42a833b2b746424a42e7a0ec7168ed6e10a31 +1020500 e97e743b51d2ca155fb58e64a9e5a9fd8b306d844275e6915e2a961bec41edf6 96fba4d16e4722a99b3958d864b032fc55972bc5d2f781ccab23eb17be8bd9b2 9ea7b6a72f8360983662e1cd6385b9e04666613e00f02e582755453375fb0709 +1021000 1c8dc672143d2b0665aaac012d8473eeffbc03593f2bff19e5cd300dc1e3c0d0 ebde0b66d6d8203bff12f9c3d523b58be1375a8779a37f0026ed109770264e16 08e426d787e7e8e00b3d401c3d2cdddcfaac80a24912d51c952113e8d34c37db +1021500 19f4073201921beed8c8dcfea23064a5279d458be19dadc71f95d1e6860d2cf2 11f8a235b0a37a24a410be6649c1d99593a14835c1e769fedd6d93fba376e0af b30df098ecd266f92db73267ef08eb8adca49eaad8902fb15b3004e91f6e9413 +1022000 55346f3b9ad9b8c5b6eaf87ad3e665911ef7e6e2087bc2cac9cf18bb5b47ecc7 148ce0270dccc99dec7fbcd56e740dac0d2fdd9ecb28336d8f10f3f93e72e621 d56058a67216694f08e09837bf205abdfb714a90a1b33f84c891d556b69eae71 +1022500 13b87f0b3bccd3df87720f8d1305fea62c7f99eac08518d6ca4ec73f884b48ed 6a6820ecb56e7f823c3ad44889eef94e701c6ef730ef5bb1972630b1e0ff21c1 926d457cb5f5038e3dcda645a4da52d2869ef4c89c010cb4ea923893869fa540 +1023000 424224c1ededff18483f53c1801022f74fac2fed58474f8199a1dbcdfcf0b826 d359f2cbfd8363a46d3d603d1785b33e417d2077e48a3f36d7f6804b2c7f88f1 2097837835e58ca3295ba57d8ae5363a123a56fda2647fc0c638fc509c28dfb1 +1023500 6125ef9aa4514113036ab2f8ff15916d14e2207d47d5e2370cb5b7cc474156b5 548476c915898d2e9830d05f0ec53b514f7227f2e3028d6cc538d5c33e80dd98 a85852b5acdc540209b4b7170ff509413e353a482e7284a2d63abf307a7f5bfc +1024000 fd357daf81ed6c277315e15d1874b547cd65cc13bf826993edd19a54fb7aeeb1 301c910cb3993c6803243b6222d23775662bdda07502844133e1723994324594 16a4d5e08f85e9bba2f4e98a2437a9ba49f9bb5dfb5f63c0282f1b5f9bb815f3 +1024500 ae271907a6c47c94f7f7f2588e04428829cb37ad332d3239c71af1457f261628 d970f8e09a2c7fd2ba1cad97bf3fb51faebb596245c5f55e1b851849e66e5bb9 7abb1dec17399ebe7152d385679394bfaf8b98dd693196f1a0bd2ca19fb83eff +1025000 bf22939da65542b923c5291432d07ea2bd2a00ff167cb9d41f85ac51fff85587 5c8eb42b81967d7277a29176911d8199152c695f87711ce6400f2b8318b69c57 649849663e1fa75f7106948758af23244bac416d35b4ced3fd2e7dd5690140bf +1025500 21b3d481f19ec99cf0c341cd66b5cccbc1a7ed425ee7280ba90af9386d4e91f0 41362f4ee0b965287c917e198e7e95c69f07270f1340fe18d01b6154623d97d8 e178502e8afc4f21ee51c0da6f21827802c461eea56448d25f1404cbf42b82bd +1026000 f23c5c093cc19bc5dea0ceddff5107c7ff15713677374411429abb78cac42a91 0dac57c3e96e57a826ea4aacd642fec6948a6723ba07a58e276fb651bdcf352b bbb40616f0391f15647483fde7e59ee29e8626662f0aa9dc379506cec12703fa +1026500 345cf11b4d563109b2015319b036395b2b12801125cf254e6f5b68c0a6cd70c2 f0bc274a028bb81ebe15a9b71e864b875feba257ce6853841819303ced071e0a bccecec79419ab1fd7390b404836198ccb48a39dc207a77fd900617a757d7ec3 +1027000 acd07fc45909b03b24cd255627da907c89a851e3e381b717739d1263982401b7 17dad78ba692050cb485aec760af2b2d9daad8d9f1486e32a382fb03c7fe855a c4b57139cc21eaa56ef7fb2f6f3642ee7890b34918661a28b617b2096fe9d6d6 +1027500 207bd5e690189f2bbf82846ba98c1a0b00e495245823c6159c102019c004a82c 66af363746bdfa0318d1e2c47dbda7cd9d054924011a4fbdf9412fb010e1d4d6 c16264a03c120a8b681a8f06f933d5f6aaf7c33895e83d0bdc082d1ef7e3a39c +1028000 ed8104c58a22e33933a48881f4691046e2f27fa2968cae6b158fdc60f766c2cb b19ed2ab60fc83e97a2f41974620e63f86a702fec2bfa3ae616a07f3c8a66cd4 0a7c3cd130fdf9c86b42778d121586c1692d31ba6f20b0b04dbb95801797d862 +1028500 a8ec00772093f07ccaced49ee9c6d884d6a9a99494f134e504124c013bfb1667 4c460320c0683413394f0048a404ac14c85b08522c9f7e7c95ddc36be0737e93 f506033026705682c94d8e44aebed0d207e050944d83f658fefa1df41bf14714 +1029000 072dc699a6b2732f3b5eede2e4609bf33421b562e69a06a68dec7410f8dc17dc e140cf4044f9775fb650fb52609438faff24023310a3c0ffc8b3a7e1aa5ef07a 0549a9ab65210cffbc191bfa966b68410862049fa8414b5e87b00f85a6cc97b2 +1029500 1b91daa7a0be56efcd6ef7fc9abeeb20ec7e9e91b292e3841f8fd5904d9bb55a 816a5d038097153d2c0b78130d93e905f9fa1aab0431ba050b3c2d0983c278d7 7a3a0ed54f0f8df4ad2f4864b08ce812001bd9fbff6fd7bded5b1d582d13f2bc +1030000 60c0681496f782c6d175671a609d285350517adcf1351b13c5993690101b211c 98d79fedf73559704a2bc76c089dac5604ca5de734220992148b7419f8cf48b6 d97446ac79f5b498bc81d03d6563b6696b0f5a4db11b3f8bf4d53e625ef228b5 +1030500 c7290f8c90153a075f2957e7479522dc8b16b70427da55f51e6aeba41c86dbc6 82ac3d69040e6be1098fb05b4a50f88979b2518135024c0a129eeaa33e2a3024 8c8ecf230f23fe7364f9dbfea6dceb042a65d4d2b000e1f5ab6f84fdc01a2553 +1031000 10d5f1e3d7ebe4c1e0ac25c126939110ac48a9b03d8d48a299fa356f802cf5c2 2e2aebc460ba1bd99198559c4e3ad33b126b0e19a4dfb42c5eb35b6ecaa63737 6245b05af1438876861c8e1775f8e135a021ae14adc7ee5d3c4ec8b30cebfd29 +1031500 36faab3bdc61f3100234c00b4b537295768c2d23815813d169ae2df6b4c0c769 2f70b464e2c6a88cc966d392c0324e4dbfc50ed6a85f02f09cf14c2485f2f84e b189fb3e4cb7e86cd172866294cfbc4cb759bb8f350b8835a53ed7ebd419e6f6 +1032000 017ec62875e8d55eef392f0ef3b1807a184c872643ac98bd38ee650618b77b25 0a3b5e3fccb43dba43fb467f8d0d07f8921629fb0976b929ca4da686983a2deb ab1e4677a28c6dd28026ec874949eb480dac7ae6bd6d9174974cb125d430a669 +1032500 99ff5e99a1b61800e956c385dc96e653e42d4a04a4793ad7ac502b518d5213ef e3eebf3aeb13c3f16888f9203037f931efcc0441dbc8ad833d275461417e0b5f e8356d391e5214499afeee845cc93f2b797280a8c0f398fea831edf5c4055149 +1033000 a92f1f7987e1e91d78a8c107fdf9ee32a1e5d6c05c95ec946c3e80c645e9c3ee 528ca55f0fed1a23181382a79cd0018929612f84cbe0aa4954d28466c548f655 7b58191d1e838bb06560bbf57f883a5dbbb0a82da83c2d80a2f77cfd30cea5a0 +1033500 030e3cd7b93b70312a5ec6cbaac9f567358078422f5b53c197cc86d2519ab70b cdcbf7bd8b051a4eab6b41f351cd6f9573b8a9ae7408b1ab633457ad9491826a b752605382827e7074e446aa45510fb7432771a1caf9b6122717fa7fe004d9d7 +1034000 d15e32207ebde3b7911ebb3db34ca537b2f1e15cb1657544b30d13829390a3ba efc04e7c16e0ed1fd15e5d8c9068b77361e03feab82ebe7d73e0240877bfae72 8e618f8996635c8a7f62e323a584b9e33761d1025c887ff02e72119dedc270e8 +1034500 b9d7ff12e0b634c98dd84165b76639fc92b5c86cbf793d313f0fde5d203eb8a3 57c20ce8035f48f0e305fc7e239f86f33d6382b558d68a65e1a72eaaee1e3087 9c0eb7689751f5d0419e6735d941ea1c63d785c1fdc07e9b343df87344d86c95 +1035000 124827740a242e34f993652a37a666b497e2bef00ad5aa5f639458b50fd1c381 65da591da847364ffed7cb9b7953149fbde437a06d60d5e694adbbfd146b5e23 cc64df2f0d0cf33f8d087caf4b1ea8d0ee543e73acc36207b7dd62463d2f0f83 +1035500 a90b40499493a906b68e4741c5a551d45a74b6b88d77b74825dd7e86197eec87 a6684dffc164991b841c09901bd468b1b6cb38796c71cc32358c2d7ed0c06609 94966b59a95417fe1202430140605edf7647e6e35a911f5c821b1a420b897c04 +1036000 961b6558ea0c6f4a96f5020bd937b024e2315937044e94d7e99a833f15a9c0fb 2d5a5c1effbd7f67d84478e7be64718beee3ef6a95f4e34b0c239cffcaebd36d b3b00b3c22c35d8edb15d7f19d9e6df6bbae05706d923ade6bb4b9f8d85f86e4 +1036500 ac05f9f0469f980206088273193f50cf74792c57a4a9bc3ce526b840080fcda7 e93603305a5386d63734dc73f8df0c3a1e56da9d1fcdfca2960760f3d553d38a 3b5965457c65f4fa96b141b2383c3e8ea95650ce5d20bb0ed60db681c909d9c6 +1037000 e8d461c77555c99a60f1a92922f6b3b702ead412bf65baea1085339d9286b53d 1aaece9384d54cbc7640948f3fac7f5377cef6d87be8f523f5e45c8f9f10a5fb cefd2bc447ce665a2e2df4d5343ceb2ca3e95e2206efae2e871f8145c4cd76ef +1037500 394e689b23cdeab65a232d4789befc80e13b946f2cb7513b6f4401c21f2cf34f b869eb6a9da7a0d2ea4f039a8cac963aac4157ac76c0bd1b6db0a2db19dc3a4c 3f8ec545a75b6850d99530cf6fdefcb8bf6ab95d1eaa183b10ad58ce14293bae +1038000 d4914856b50ec1c683af57b7ad17dedb0d6d496b1c3fd9e8ac44254f5097da80 da3578419c83ca27aea9e5aded3f037ea1796130d12a7031b589ca9ffe5a5fb0 982d02d1adfbafaaeef3ead73a8b760ef8cc4c18913aa2990df5578627e0c63f +1038500 4ef9de168a9cdf6e4074492cd69b15621990a9b1a731154a27c1df6c6eaa2f93 da919b8ccf4214f215cbfdf08bb7e568cc9329097d2275628cf7e870d8c1e9d3 93617d68bab22ad289cde335ed90604618792bd53cb844254c861f8a0f1e38e2 +1039000 aabc1d300ccb7c5e20f99c58679d5801a86dfc53f489649a78d61d2780c1ed52 740ebeb1c46972cff11c9c488dcedb4b03b1b26af5bf11fd2f455cd50be8453f 886512ffb3b7ce603349d7ddca6f133e9de3b328f097b2a9b54933be8547e4b5 diff --git a/iguana/confs/BTCD_peers.txt b/iguana/confs/BTCD_peers.txt old mode 100644 new mode 100755 index 69592171a..4049e17f0 --- a/iguana/confs/BTCD_peers.txt +++ b/iguana/confs/BTCD_peers.txt @@ -1,4 +1,5 @@ 5.9.102.210 +89.248.160.236 89.248.160.237 89.248.160.238 89.248.160.239 @@ -6,6 +7,8 @@ 89.248.160.241 89.248.160.242 89.248.160.243 +89.248.160.244 +89.248.160.245 78.47.58.62 67.212.70.88 94.102.50.69 diff --git a/iguana/confs/BTC_hdrs.txt b/iguana/confs/BTC_hdrs.txt old mode 100644 new mode 100755 index 374f793ec..4b400eb88 --- a/iguana/confs/BTC_hdrs.txt +++ b/iguana/confs/BTC_hdrs.txt @@ -1,195 +1,207 @@ -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 +402004 +0 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f dece1ed3311faba0f3bc7792930799ecc20985ea95997c5e8edf1a876f17aed1 00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048 +2000 00000000dfd5d65c9d8561b4b8f60a63018fe3933ecb131fb37f905f87da951a 41e27d57bc7a3a7694e3cb13a92984b37dc4e98bf3f935b58c68227d0ee06702 0000000067217a46c49054bad67cda2da943607d326e89896786de10b07cb7c0 +4000 00000000922e2aa9e84a474350a3555f49f06061fd49df50a9352f156692a842 83c43672b8617e4c4a4bbfcfa99f8877fd9db36ed19e57ff7c686f182b60bfce 00000000a86f68e8de06c6b46623fdd16b7a11ad9651fa48ecbe8c731658dc06 +6000 00000000dbbb79792303bdd1c6c4d7ab9c21bba0667213c2eca955e11230c5a5 66f3cdb93a6b871f468a44456e12a11ba102cf76be74ccbc61d615ce9c076acb 0000000055fcaf04cb9a82bb86b46a21b15fcaa75ac8c18679b0234f79c4c615 +8000 0000000094fbacdffec05aea9847000522a258c269ae37a74a818afb96fc27d9 4f93ddc7cc1dd0427dbfd9ef7080b70e676553c566b358a807b9abd4006b2196 0000000072e011d1731643b13159a274aa0d4e15024d534e1f62804a018d242c +10000 0000000099c744455f58e6c6e98b671e1bf7f37346bfd4cf5d0274ad8ee660cb 9d4c6e97e3959c23f38ed37798743df5a4d47e34683cab54603f3000f934b511 00000000f01df1dbc52bce6d8d31167a8fef76f1a8eb67897469cf92205e806b +12000 0000000011d1d9f1af3e1d038cebba251f933102dbe181d46a7966191b3299ee 8b8feb0ba990705d4378e1b778e62db2d417c8985ae569b7fb3e6844e8a58852 000000009bf236ddb082304d8ad0954cd3292792c4958b643f2ec3c1ac3f026b +14000 000000002d9050318ec8112057423e30b9570b39998aacd00ca648216525fce3 9ccb85438e9350235b1d30c01ce0b2f3e408ddc5193e73badb3977a3d52cc134 00000000b44efc0402c4841e13c29e2843776abd8ca1a728b4d12a092966e87a +16000 00000000679a1ab3af6da03f13a0bc96d7215e65458b2d2edfa030b5b431e8b3 38f5879424c92f6160f4adf7bb8ca8d0002dd1a7ea82a47cff891ad2eba92468 00000000bfd11dbf1115ca74217c55ab3938e59b2cf91d862c00354b65023043 +18000 00000000f914f0d0692e56bd06565ac4de668251b6a29fe0535d1e0031cfd0de 476ef2170dbdb8ab3a921d8ffafcb87b521002dc33e50863a469b14f721bae1a 00000000d50b1d5fdcad186077855a0e5dcf357b246238eeeac208052a9ff3c5 +20000 00000000770ebe897270ca5f6d539d8afb4ea4f4e757761a34ca82e17207d886 23551ac19182c7d69112344013508171046ccdede1f5c4a5912e151bed6803fe 000000002434a3edf8dee4fe506d306c59d3bf41f73d979f30ed3f7b7c34d06c +22000 000000004625a14242beccb38c63a1f770a76ee5788764e6c0abd4129bbc1b9d 67ac3ab11d5d6bccec6805f1aa725b464c45b75cbbd2d29c7f35ecb599c220ba 0000000082b75cb83e6b30ffd99d598b2b3869ae31c38d56e6856cea95ddccbe +24000 00000000f04fccc81f37002707e9501a3f7bdcf25f65531f386a2da8af20122e b0ea761af31989e9f6766d8f3ed5e64af98661011b31b6e52cd223a715ba7351 00000000057136237ef09824c432d8151cc23bcb009cecf49ace17003fe574be +26000 000000006d6c151db6d4d67356d590a897a11cd7d8111ee989de6f2f548410bf 56aaf4660baebf6c881604875dfe216fb720330f27a8ec011aa97aa03c0d0783 000000006aee625129fc9ad7ba7930b89c80ebf22ce4448d5ebdd8609fdf0a3d +28000 00000000172c5ed49d7dfc29bf9a18a53fa2d050fa37aa210d6d4080fd0c7e67 999d77cd45d68a64d152b00d003953142d2685d3a19286844c05ae72b41df7c8 000000007fbe48fbcac0d33fb16cf7e254508e14cf51b1788d400b854660aa89 +30000 00000000de1250dc2df5cf4d877e055f338d6ed1ab504d5b71c097cdccd00e13 409f89a04968a0af18c834c55fc15685c24b26e4f07f1dcc129de4db3e77451e 0000000050a8248e6eda4db7b5919491746c06e2ca458b22c35d8d72b3f3e5b6 +32000 00000000049172ba3ec1b673cf13e3d0049c1c07bb103ed3fa300e3833480055 9c91128d2961310ee1eb83ab25e7c3468cfceb08a8689fd9ef27bacfbb73eeb3 00000000a34346ed69d4a8e1d9221c63943aed2338857e72a35ed3bc4fe249b6 +34000 00000000495968d19210d3be15bd24fdc19805a0ef15026b0bb4482b04a9da3c eaf2fe87514eaada77c27a8796dee58e55918ab4d3d97511eea08fc323064caf 0000000025dfa76b856cf6313669d4c6399099abf65402c2d849400427c60b04 +36000 0000000080c3deea35dc3df90a5fbe5f27db52f5e01018ae7d62f8b454c71335 d3092ecd06aeb81f6ef6e323b7ef660122dd72d9c33c6d7208c2acc30f417636 00000000351f0ae03b547ed0f9eb5e92f6cf6870aedf92e31487465e52d56af4 +38000 000000002dfebce284d1e08b6cf04452530891579b7377669865889498de8f3f 18a63c2239c8d7903b8ea3c153ad8ab8b723e705018a2e13ee5ca443ef11cd1e 0000000041b52b3217479dcac62e5cab86fc9f45511fdeeb0106bbd47e5b0851 +40000 00000000504d5fa0ad2cb90af16052a4eb2aea70fa1cba653b90a4583c5193e4 546d597a9a0648ef89a77811c4036ee380cdca1febb0e95da45003693e6b3d5e 000000004f5399dec71dd54b434bbb35a1c30488a37eadd9be7ee61399b4ac90 +42000 000000000f80c09687893406279f62da437a6a0b95b8dc096b30c10ce088fc64 3890d815c8a112f061307bc03683391523587a5edcf6b60c9656358e3c4aba97 000000001865924e539fd6744d6814fe81543d93000e7e9e70c4ed8c4c4d713f +44000 000000000122898b31073a770a97cf599c00672fc8d6ae15652235862f8b76d8 0a1e6031ac37b5b67989d210cfb64eee7268c4cc3d94c253e9618e8b3862b6bf 000000001611e0eb1961d279254766d3581143cb9144464df1d709805fb555bf +46000 000000001dd39771dbe4f9fc6da07327f13f894dd2c1a46cdfcedf930fbbc52b 73fde83c7450255681d866ba1d8ea043c7e5a6daf605093c2dde3430a926242f 000000000a882eb77d5d9a0abd7f189f64f9a18c06952d8e32f03df3c50dbfad +48000 000000000f3d40ea2bfa8d779010e52cff4720c072ec4b12ed576cf5cf93c947 9f34e4674f86609d74961eb54c1cc2f98f5590a6450863ea3e21e346719afd86 000000002085503169f527995fc46d02a5e33666493c46ed4516dcc0b96fd53f +50000 000000001aeae195809d120b5d66a39c83eb48792e068f8ea1fea19d84a4278a 6916dff98241e918e453f0eb52856de9aa9a960414b2993c8e97d75ff44cfc3e 000000001c920d495e1eeef2452b6d1c6c229a919b28196c103ecffebabee141 +52000 00000000082bc4398c4aa5bd8d9fc452d60d533ef68baabf594c9e7d6649049f ab884b30d7ed5872d1d90a2e25a8b095bb39434ae0f80a32adfc97eed69aaaf7 000000001ab16006f0e6372bd266b8dc97805aef21d0362048377cf03f80909e +54000 00000000144197f54afa21ae7db2bc93eee604432101fc0ebe7966a52bb27e61 17646473198bbeea3d60633c6d1c3380e5d119e1e9a2eb504abb615957a6836b 00000000100403d4ad879391f3fe2d80f2936eb2dd6389b81ade62ca6e3dd0bd +56000 000000000dfa452ea45e0426dd8914c35e24dfd4399037c5e6deb9f18f58d6d3 37e7e05cecd7df0602970dd7f985ed73ae216bd160994b4d07577881f299a4b6 00000000002157f86eb59fb1037319fa879c0afe087ed79e019cc29560a224b9 +58000 0000000013e3791d288d9db814c52fbdf240b2206eb8e19d7dc80013c60c0c00 088e663cf7476201f3faf37e38fd435ac69e7939c4b3dadc3a065ac7d0466147 000000000e52b80e848807d7d0a7085fd561b613e5045a492da9680d380f84b0 +60000 000000000b554c46f8eb7264d7d5e334382c6fc3098dabf734de37962ccd7495 7bf914410170e1fd75df6efc08af8617306a4cdea1d5c950101c700406783815 000000000ea6be82e57bd76b1dfaccd5de0ef63d9a0980310a5148bc4bdb6753 +62000 0000000006dd4bc72daabef992f860e703820de119af3e24a1ea6f6c81521011 bb58902ef76cab599d025523bf078110cbbcd99212f3b35953b637dbfb3b5630 00000000014597753c3e08e3b1d191c14dbaf96e6cf5727be128dfd4705b5afe +64000 0000000003d7055b51d7b9ab693de84c03201fe0396af61dbb30bf31445d3f55 e84093b7fa29447382f1354e788af857b14cd0d4b60f01c7211c8f537ef310c6 00000000005e61abe20a48deb7dc94ea3ff37ea7b5a57b1519fb708ea5967013 +66000 00000000071d7e8a0f4895e60c1073df9311d65a85244be1ee6369c9506281af 01318a72a31c85ca5b8b59fb235307588e85f3cbf892fa36d50f43887948ed48 00000000009cb106f888501f42e729cee5062c533f9a75d28736ba3290bd56dc +68000 0000000000d991791fdfdbccbbc2a73d2f86ccf78e2d0a7ce7675f40b5986b3e 08b4c9998a1a39c87016dd387d313a73a1d3d4917ec3941952780154436fe6bd 0000000001544eddcc2e3c5ef5f75c65c1adb99865f7f96b877ede591a5fd6b4 +70000 00000000002b8cd0faa58444df3ba2a22af2b5838c7e4a5b687444f913a575c2 42621404a60ced6d1bd83116a726657ca1c23450322e3dc8be8f82fef75b326b 00000000001337176fa420cb4a7717332d0994491bbed7fd797e45a02b3a7872 +72000 0000000000eb357d4c6fef6ad9a6fade126985ad36042a99cf215a4454545977 c4df76d0f20fd07e30b763b28e60ef25f00dafe41ebbe08dab7fefe730915034 00000000002ec11f3242aeba3465cc0a350722d355d42a6415222c82cb336bfd +74000 0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20 bd262f98ae8ff0c5a9fda8b744e000f67ab181f10e9daa192d05521505db3d25 00000000001ba557f4e72c127725d7ff26be2cb48519c007189d45691e650d0a +76000 0000000000571138ff757a28ddf9b56f28c4a461e170660bb5ae79a556069bb6 18762c4f10e41503af7c19f320ab05ecc0c6935d6976cf8c38123c294561edfd 0000000000393b1b3943fd383fc68e8f509265403345e3f6589d8683d4a1fe49 +78000 00000000001f3fe62641b473673c9ababbe207046a109f0861af95c905a918fa 61b897997332e2256ea43b37a6d838957181099b700818b7fbd6d0b990e79683 000000000000883080e6717f944f2ed3bb6f2fa0e2723a8486c476acc713a079 +80000 000000000043a8c0fd1d6f726790caa2a406010d19efd2780db27bdbbd93baf6 cdb9b85b40849062327de45286562a3014230fbdd615b332de6430072d63763e 00000000000036312a44ab7711afa46f475913fbd9727cf508ed4af3bc933d16 +82000 00000000000c9d1c4acc114afb58d55db5ec44a963263cf6247220b7a3f85c5c 5a91827586e71fa53b9cac1b98967fddfab0e732a1366cdd4131dcb29718fd1b 00000000001e0f5b8021e95bf59ef9279c45f5162a0e41074a145c5825385625 +84000 00000000001385326e30864192ba84ed2f9cbfadf0698655b1c25f93c92f22ad 1e82db93950b485af0c98a91f84f5e2db290852015d5b8deff93772f4b5dbac1 000000000002c05ab3ea86dc6a8167dd6be5450f6bd4efb431535f04c57d5ddb +86000 000000000000ff4e1adb14f07774dad6b34968a5e19d1a2fe1fc9157e7c2b85d 50800ab18837ee3f87c6edf73c625b26ea2133354d9bb9423670fe755174da5a 00000000001c1196186701c95370644621416e575bede6e0a7dc47525035277d +88000 00000000000ae9e98b82b39a912cdc0ebed97c26376780ac996c84d9ec3264a4 9dec8129d35ae538ac5fe73c0c4496f3e42c6673ac010f9edbf2296d3c09e168 000000000010454e08817326f7032770eb75062476e743cf2715b7510b9ec96e +90000 0000000000071694daf735a6b5da101d77a04c7e6008c680e461f0025ba7b7af 76a46a23998e76a022eaa9b7ce6a966153288c621432c25c047d479f8c4958a3 00000000000bbe48ef6c02c01e4cf6b332825e7943a0cc15a5678b0a92858a20 +92000 0000000000001df90b0c523a4d7e4731336b00cf4ba9d8e02d111523df80998c 158705b4874dd942efa31c146f7483fead8f2b8692469789247708a6cf19efe2 000000000007e96d8ebad5e4e36c737ca121a1bf77078cb815f6068e59cf9861 +94000 000000000002a4c42580d51f0ddfd867eaaa790781c484c633a69167d17b48ec 3474b1e5c321938d9091b0798efe7e18ab418658eb4b958841181c97da91ab88 00000000000271be2d9430a96ce054a55d6e7ea93970faf2dc256fc24f42a0fb +96000 000000000002c86b568cdd2d0f4b0430cccf42bcde3361f63a32e23b5d839e99 86e2f364192a51944f2cf0e35af7557e6b0e1fc578ab34204e57552259be5dd5 000000000007b4e174a5dd07f1a785a5d0a52faaffd9d610ff65f64270ea7674 +98000 000000000002272a6dfb695d9db936d813bf0055ae92e920c2791d4c5f7290f1 c0d37a94957444d44255048391dea29cf12ab99b294a14cc89429123ff4021d1 0000000000054030f5e323cd782b8030858356486a369701470f6b1ab5854e28 +100000 000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506 1012e9e419f5b93f096cec8df29b860bf0207e2ce09931d7d5c1a2eb6e030d67 00000000000080b66c911bd5ba14a74260057311eaeb1982802f7010f1a9f090 +102000 00000000000335c47dd6ae953912d172a4d9839355f2083165043bb6f43c2f58 3f00c2b2a78004e5f9e9d20b245f5aab5b5bca68345979b00b16116002769ee9 0000000000035107dce8eb675c6fa9a08c7617c109b3553ad8f208dda24065a6 +104000 000000000000a9887c91956b638bb3c0651321fdb24715354c3fc6633f5a16a3 16cf31820595a465b545bcc1190508ce091086d53b97b5e71bbff9d420bcb319 000000000002a850bc55fe565089f1631752e487d23e1e83f33dfecd12ae3ae5 +106000 00000000000058d919f52d255f394ed0aa3a344432676fd30f1aab4e10c22fad 2d3a18e763ddd1f6eabc79b722b5bd98097f0d2c89abb9f449c481e78749d983 0000000000009c097e197c7b517d36483026639676b01c14fcd681721721d300 +108000 00000000000167cea0b43ff7ce22f330d3e302832187eb31c61b15bb1511e118 5d8584db379287def00b37a2d6fc9bc381eb1b723c6ccb5f7f1ac2b8ba4d6dc1 000000000001110a03b89e33a6c0d71f89319cc1215997406bbc74ed9a6b12f4 +110000 000000000001bbda3f22ef8e476b470a2d3ae16821c23a6d22db77318d0799a9 d6eb660c646bea29b93ee23bc569178dbee16b36b182df7e99ba18dc08489374 0000000000018d067c617c2e262e544bae4807e413122b1f4814077a15ac57c6 +112000 0000000000001d69b3899a49f37799c375a7471829953d5470f468f48ff70432 6ef68447cb6145c71a404ce44e3e7f1e2c45c8ec8f78080dd6f7735ba6b75b2e 000000000001035d056c81d4edbdb2763e40739fd0b2f9cfa06f657299f4f66e +114000 0000000000003195a1e6dc48a540264d37e9ef79b552bd78ea4b93a3b6e7e449 084813c7a679421b7e1eeae9897fd25bad3dc19a1e702818ee0a94a1e5d01c42 00000000000086f38ecc2a8f8dff3bb9e1a2a642e965d4ad84e5c00e8cb7847c +116000 00000000000007ff257fb2edd3fdbd7b00c127a66dae1288fc5e26c402d13bf7 d2334cecec9805da62d511a4d2eb3743fb8f69c9d9141650947ff326a241ced0 0000000000009b84d74ddd7657bceb5f9705d25dd29b5afc5318a3c689472a73 +118000 000000000000774a7f8a7a12dc906ddb9e17e75d684f15e00f8767f9e8f36553 b969a1da29e137da960fcc3cd0fa4960fefda1bfeda87edb4a430e62b08eeacf 0000000000006013206f2e7e1d5694b0b4272b89229ca3f9dc2fa4ee6d19c4c4 +120000 0000000000000e07595fca57b37fea8522e95e0f6891779cfd34d7e537524471 7c49116af07a77ca3fc5f5003b68585b9b689eed77154c1af88be8b467506fee 000000000000218e1979853b278e527b6c447603942b461014964c4368c27482 +122000 0000000000002fe5f29af38282ac1c8f4ea2bf8a0855946150130419491b6c05 0efb5e74991e099c041ee1e22da6bdb06ad21df739595e2a8cf7e21a7163304e 0000000000004ce89031692cee278dc09e09aac24fb2ff514fcac80e4013a911 +124000 00000000000023e9a0523cfac29afe07a07acf81e273cd892c51ff8318846620 962c0106ebfe5e7d2b356fcd2f78a2180a6e136660cdcc85b195aadd311f291b 00000000000021fb283d1722b29e809e80e837b89e25d159362166161dbd0fe0 +126000 000000000000166b7d480aada35af1e6f9a2835d68f9c2fbd272073dc6c9d5fb 15471893042686f902f90d6f2c0f3dd617fcc662abffb433bc608a9c261ea746 0000000000000205c2c2b5aa7dbe0bccd98bffd4af38f9c38c0ba9aa8df704eb +128000 00000000000003b8ddd8692769e1965554a8bb030863e0566a28bc0dc952864e 3026d964b955a13f24bf1f795469f839da4a89bdef0de03372c5305494c9388e 0000000000000ae8912250b0d92a9fc63f021f490b8e359d01ad883298f99c06 +130000 00000000000011906b491883ab0f16f0e690b133ca860b199b775c3cf6581c21 e8b17a15e52032cc813e52b283ea9afa020a166a105f8eb86e8202c8747d7476 000000000000012f983ccf25fca1659dc99a24a455a60a7fe3e848475a0b67f7 +132000 00000000000000a7a0483857f0d951983ff2834a47c38fdcc22563ac0f8f707b 14a632498c78a609adc8cc4f2eacc23ca48cd4e18f7ed2652c5f143810a593c3 000000000000029054ecc6a343125f6f526f774c7189caad04bf299124acc2a3 +134000 00000000000007e3e442ce1423496a064a7c34342ba98be164ac0c9f9b872213 e1dc2c77415d565b094abe960ab93118a6b8c4340f15ef57de7f61d45ee03e52 000000000000067ecbc0c0a94418dfe5fc75bd6e04473aeef9b53973720f1679 +136000 00000000000004da0d6d69fd474fa08fe2ff3111ff1e9e01f72899dcd9d897f0 00030c8c4775f8a50c3da2622f653024d45e2cfffaa6a202a50cae7da8ccc596 00000000000009a3aab1d1d5c4f1fbddf45a3c1d0484fcb5f0773d0755f42353 +138000 0000000000000044c7b6a5511c0b2ae64ec545abccac8053f31cf7bba23bb886 37372808d4a8d98e1a82d630db5ff9a6b2d5e190d28d7ca70f2acbb55af312a9 0000000000000285b609d3491293ee7ad5e3fc3155d0d59b066522c752e539cc +140000 000000000000086e28cf4717a80066def0ec26c53d660582bd997221fef297db 372dcb64d18db0dfb6ea202f6718a40b5886bd69f4bbbaf760c14b2cb9bd125d 0000000000000697dee71229cfbce9ac011b900f65702f62ccb09849f7556e88 +142000 00000000000006379826f5f10cd23739b9c29f87ca10f199f9f4b72006311f85 c0cba7384d1aecba968211e8d91859f80c901574bbfa5a6abae9bbcfdaa5894a 000000000000024966c57274fd19fe22bd4d03326a4e64a6150e496e09fa265b +144000 0000000000000681a73f1bb50454cee419048d24e1091bcddadded89df53fd07 3922c45217b67d3245660060e7b6ff7a13ecc1eb66b7d62e4826834afdf0d0b2 000000000000026ba4c837d96f9f1260e64733054949f22d9189d27003c10ef9 +146000 0000000000000188cbeebda87456f040370995dc11eb3a1e76b1577b6e0b588d d49ec8d5f2b91e3bec87165770d8355d78e1934a8916637df186420bc1ff95f9 000000000000036479e4b26fc6b54b728f505df6ec956c68c34deea22f5f79ac +148000 00000000000008be94b219a94752bde6a6a1c5b9d72abf2aaab53df7d93c5fa6 efa0fd50c1e7d8dc91040031052abe3cc851ab4c6675e3a4ce724d95c478d34c 00000000000006994cfacc4d85ed1c84921eff8673e4463ed71a1df22ec6c662 +150000 0000000000000a3290f20e75860d505ce0e948a1d1d846bec7e39015d242884b 5d8aea62e24c35e0266a24ec1200f47daf86fd8f3977ce7ab7132745a403e4fb 000000000000006b1c90f01554b0aa0b2b3adbe339b175c23b8b8ce8b503a89f +152000 0000000000000aca2b3a267dab498adc48afd15b60cbf21fa58dc26c86a6dc13 fe846c807abd35fb49fbb1d78136c0edf0debdb45ed086155f00504e72b9a7aa 000000000000049f8324c2da6a67441d11b6d3303529354351a9bdad9d4d8f1f +154000 0000000000000a7446d1a63b8229670aa02d1d9fdfd729b89107fe5d88dacd8e 44fcd84719ce3be98a7d64e0ee3bc21d4e2cf0de2365370eb71d434ed9baaa85 0000000000000cfad9660f9068486ca4fc83ba6e5fcef0ecefc8c7eeb2e0e15a +156000 00000000000002adfcffbd5f09744ae3b930597dd0ea684cd37b816783ba3762 7233ce2c246f20142d71b3972b9f6d8b51dc15ad134ace83ecc24e2fd9f8da28 0000000000000c5103789361bed6a8fd64d45f81c63dc3eca73d4c73a2f02779 +158000 00000000000000e50d56f13c7ce64183386abcac63462ca745b711be27568f52 b60615c9c91eb51eb52c8bc80782d6bb528a19ed309b957d28c1fc20372b31e0 0000000000000cdbef919d1caf804a847486022f9b24f368a47061718550bf01 +160000 000000000000066c6e629b2fb49c7fcc52b82fe9833f328e0c3943856facf231 7dd93cd9bc029e52f8f2ba78ea2029a920e8fe7cab865d055e4737ef257f56e8 00000000000008754857069b7a1df3acd1643a7ffe1623eceebcb7346ffd6a63 +162000 00000000000001a83f5b20cd132f38f792fc02a17eb14d494c780ea9d1c82acc f87730a51ef49bf3dd51f6435344f9a01f939b00c3a280fedbe643d031432ef4 00000000000007df40fd05a7b78bf3a920786711de165006d7c9750ea4043dbe +164000 00000000000005a38f162cf308edea0a0a5d000bdb2073cba2386ebb1df7a2cf 06cd95a118d1293cd9aed19fa23bafb1fff0045d1dee3754f6442719706e0cfd 000000000000094d462f1a0dbca9187bca75238108e11433be19c9c92da29a25 +166000 00000000000003b3402f35327d144a465f3768d6e6cb06cd8a2d8fc1328b2477 e3282f15a892df27073c8c0fc76fa4648b624d47db47dfdcc1ac21d5ebdbaf0f 00000000000003dddc13fe8cd12a0b31f6a7c23a42da5052c3d65ab4b764a84c +168000 000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763 524d8a0ef4e2aff9bb36851dfa1b359efe49f8848834fbe0791931c8942282f3 0000000000000a40136ba56d6b514769534831e9ba805fef4d122f6c8d6da51c +170000 000000000000051f68f43e9d455e72d9c4e4ce52e8a00c5e24c07340632405cb b9f6e63a249962e7e4a422104077e0396dc2ab8d4a120806a7eec97d676b8d7c 000000000000074cb2c7d9585396b1f64b7e2c6bdb33e354b8e580c21238b76a +172000 0000000000000837e82c3a4ebe35a1d1d943e056234dba7c629922c6d4052d4c c1c8170cb5acba5dcef1ce4b12f3e08db2acece327461af6d92bd557ed82fa8a 0000000000000443d106c7a849bf6c703002756994eb9c93bbfb20b54ed05ac1 +174000 0000000000000504d3e701deb624eee4370f50c3d688fd1c27be5bbef07d76dd 6fb97ccb59c9c83166a6599be85879f97e46997daea452a895bfe23b6e645429 00000000000004fad4496c734994dc487c1397f22545287ff848b1a819f68303 +176000 00000000000004659b5b8602b2132b62973994079a1c828df6ef8d6427e4686b 24ebfb8a7f8996c1ce2d3441420e898aa6fb6b7f6a1a11a30ee708585af56d8c 000000000000094af92e179f0401e679bdccab2e475072a60d28872ce735b3b8 +178000 00000000000009eae2697a7aaf57e730b707b9f4530449c16d924d534d41f297 8fc623c7e53b100d697a24e3193411d0cafc14af70f20aa79c27ef5348e9996e 000000000000048b777caca656fc0a79aaa095e3b13c1717f9d420efaee17faa +180000 00000000000004ff83b6c10460b239ef4a6aa320e5fffd6c7bcedefa8c78593c 9e0f0850e7deb21dc15a0676c2d55b2fcb73b66bc9f02e1b878966cee4a74aa8 00000000000002b833041fa0a23d7f8c2442781ff33062fe5c483288cf151e74 +182000 000000000000068dce12903c1447e4c5b60311b61e443a25d5fc82c77f4f9a8f de9a4ba8ef86cab92ab5f6b5d6d8c180671036e603999b2a0b983b3eb5415d2b 0000000000000a6291a6ced756c7b8b46e75fd01d75fabb1c10d76ebab5dbdb2 +184000 000000000000060405a235c6b968ccb18fd6b3800ae9742c2524e28863367359 25b40a18d6e6dc6966618e0636a16cd3b13d321632ced8f3935c9597a98d75df 000000000000017c48347973112e2f48dd6ebad919d5385782b55b0341610a01 +186000 000000000000072ede9629fd1fd1af3cc2baa0e637f1959f34884be0e160dd1c 4cab848ccdaa00419273ef25ee9e64c164f6919ba04fb1fdd54106f1afbe5f72 00000000000008db6520c33d4d75470b1a5fc5ab34670655b6a18f0ca7b860d1 +188000 000000000000004cf0c72d6dedfde88ca4c3dae129563210072ee68acded0ab1 68f7e02181e36a230abf6983f967813b89a0e0f98674158a50db6996e29db510 00000000000000b5944dddd5dacf2665d004e5a10283df8b9a387725315c70e7 +190000 0000000000000708bf3b261ffc963b6a768d915f9cfc9ec0a6c2a09969efad1a 4c2cea5a930fe3af893a641eaf1f92899f4453af2b11455515c57406ecfa27dc 000000000000086f0e0e1666a9f1874988cc16d1bdf3045524d72a0cf72684d0 +192000 00000000000000af130d565291ba49208c546685c69b48a293aaf06387fc22ef 9d58ad9678fae8bf7866d6edcccdc6678e8da63aab98df7f5bcf641aa9bf24be 00000000000002b1e750d5b58c4d7976ecc430fac70b24b4a8b4246867b43b00 +194000 000000000000046242d4984ecf2217e9afa113f2835bffbff118f2df4d80b216 22376dfb11c837c1d70067afd38bd70554e6576fdadbab4d65c113d869899aca 0000000000000368a27aba8f6ca19496fcaf1e74728f34a6befd4b28ce734681 +196000 00000000000006ae59396d4a289e83fe1b9967630752a5799f064620af7836a9 a0101abab5da4a3947d441bd4838c1dc04fa824c67feb850384899e5f116af56 00000000000000a0b861ff4767ada7d0310823e9316af4208275237554c247d0 +198000 000000000000000f2ad431ff18ab1673d911395c8fa1f6801e054c5dcb54f8fb 1c7d1751d862cc8c87213435c51d9b1f6992945a097ed059c626b87cfbdc6efa 00000000000005e980307d69776708a2899ea7af6fa376d15b0676dcef00eee2 +200000 000000000000034a7dedef4a161fa058a2d67a173a90155f3a2fe6fc132e0ebf 380b65fa49998421330f6187ec57d31a132c9d1ac3e119f9a55c095b7f65f746 00000000000002e3269b8a00caf315115297c626f954770e8398470d7f387e1c +202000 00000000000003282fe1d5533e4275fd9f51e6ba0352ec01f32914e9fbaeaf55 b65f823ad7e038d1dc64c4144e87f5f77f1910351122549ee79ab7600ee2227a 00000000000003acd024ceb34c283d9a71883d1c5a74d50608a9636d2c6fdfba +204000 0000000000000423eb625dc140272ab97fea3ba6baf1dc56de77deabcc492872 eb34c90dec6b2173136c797b36b0115a9448a68c047bcaba89df75f0c4891b93 000000000000020aef81dcf0ef072f2f8f77c9e0fe57efd67442ccceef89b323 +206000 0000000000000130b815d40fd6d8851438cd21ac9e428615ba03a1285ef1374c 568b3aa80c5504f24059cd0fc9f177b33480c33eaab9041f7c976fcdfa7d4bdf 00000000000002dea49a5d979239cefef6bc38777d7faa9542b73df4e6f9ee6c +208000 000000000000001db5a1515a5f8534c941b1628f60466e6b709b3b320254afff 11800801a4cc43da007a66aa7d7d96dd947086bee56917a6f786bb4fee5746cf 00000000000000b689b3f2bf7d6da132855d5eb8859c440cb09ef591b2c835ff +210000 000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e 91ffd7a5cf624d50981c4db059fef7cb148e5bdbf81fac67fd9599e5be55d3fa 0000000000000198b7aa4172cdd1e5d80207535da5a2d4acd80242c07729dc21 +212000 00000000000003d906e4131c39f7655b72df40146d2967f5d75113a09610de61 6ce91205ac2f4832d1c7cc99b9a935b80a52af6db0089d2276e4dab5427c9bf6 00000000000004bd7804653f46d187cbc1dd55b9d3fc4285ab450b7175453a38 +214000 00000000000003e6427f9fafa8b0e1af0859f15cea90d911f64445d296a2781a f2c92f620050c691b8bb71976dbfd6c660a90f5ca5dd5723ae9add7e057f2d12 0000000000000246c4afd6fd3204ee2d81595ef621e3cbb3e36a651904c464b7 +216000 00000000000001f79a2db15d0ec6d951729e044749372caf504679bba5b1e65e 265dd035294ae9ec29783deb5d1488d506fa341a202980b3388e18ca037843b5 00000000000002b5171738a006b7d9a3157990e13427e29da9a0172e3cfd51aa +218000 0000000000000569070e338293af66258adba29dcdd5f33212314dff752ff458 826c3a82b4fbc764b486ca1df08bfd3209fba9ab9b37f3fe77f529c49eacbe85 0000000000000427e9d7228b14d95965b2424a73fb2d46aee0dd3f064c36cf71 +220000 000000000000002fdd2c741ed50bc3975a640ca419081711f30f553939641303 fbb6729ca1783f40e5f7bd0937f4969158d671dc0a03850ddfcf2746dfa04057 000000000000010d60d852a95461b8204241633a372490b38b33fa6fafa82df5 +222000 00000000000002c752a481ce0c45450ab046e640d38d6532178721e7700d8148 e4cbaf6e4174fbd3f1d361396f5d136851b4f6542ea7fddbf8d8025a5c203986 00000000000001e591318e4a6b4fd712e7cfd4e8a87bb65ea1b3c0a3f5a87ee2 +224000 0000000000000107ee276d037218bf1780dbf6d4256bd7e05c66ca133bbc9ac5 4f33a3a088c3ece8d87905a2c14baff172b4cafcf22b1dbdc61ad570adfffbe8 000000000000039882763f89f40690e59c60124f94f3d3cb33f48a6869bac408 +226000 000000000000012c614cf477c3b155d339f29d565c0258f9846c2f4dd402ff9b fdde99179a5cc0891675e550a3803c903b65acd5c4a223cc188b4598e158c506 0000000000000083785252ea71c4d69ab32aa45334721fb116bdec493fd72687 +228000 00000000000000efc4311c93fafbccedb6fdc682b566cba9519f1736b9788a67 960fbe213f3d6384eea60ce0c0cdbfda4af95e6d276596f05ed412edd7dd0ee5 00000000000000e62201a56eba803dc5510affd2cf7cbb35d8ea90a513ec5eaa +230000 000000000000012cfb19f5662707816e122ad60dd9b1cd646c6c9899be2c9667 74f1a551b24a3b99c6df3328285be3256b410df8e534a1fe06c88485e0a705b8 0000000000000200641676d2831f4ce9f0f900d0a60d72df7b78d09dbe91e777 +232000 000000000000018f47636e1c3a946db77624880ae484ffb0233f5aac6316b3bb 532e37e6cdf476e407938b13ebd723793e57677639368d32bc378767d343384c 000000000000017bf6d8208debd93d57c0bc951c0f032741fc1733bca49bb0c2 +234000 00000000000000597f9263ea97bed4d3b10fbd55733a73bd1027f1a9b6c1451a 7e5e7cce998ee02fc54ac72faa03d127a8959d346e028b04d0eb24f7b09194ad 000000000000001fc3ed9921095a06a7bc3ed2db0400341a6ff7a12ec4f08912 +236000 00000000000000f2f5e55e89dde082cecc9b4a46a10bbb4197f5e35b16612db5 4cc95beafc27959fef3e9d31c47112e6ab83a12843cc35bfe341f94b92f5995f 00000000000000a661436a3afba0ae9027f8ec858b45c87c309b22f1e53493b3 +238000 000000000000010014007d4b51ab60063684665401e448c6b0b1971a7398a442 0d8403176d4a29713df8b2bb56f1457e927391e9cc4e83122770cba48611de3a 0000000000000089c8544766168f329b696c69b273419fc305722475f738be85 +240000 000000000000000e7ad69c72afc00dc4e05fc15ae3061c47d3591d07c09f2928 6ba437006735b0f9856fff92c4cb943a03f89022aa06321eb39484e8ad0b521d 000000000000006e77df3985d9f69d92289b28bd3510e8b124ec24f2bc91142f +242000 00000000000000c95233d37a8c78dff10afecb14060347151b7eb7a04a2a5a3c 4f837013584761696fa661ebeb6dd7824a71db18ab0cb8785aa43e2fdbe7d9ca 00000000000000ccb81f6bb82efc9e2adbf5525bb9d638a1fa7981fc5a9d0a3e +244000 000000000000006ded1526017d5b87ca22e1bd0da3921872cc99e9ec77ee5166 3ad2d2fde08f4b714d4bf7bce1e8aba066c27f8b7fe604e4903c940c52674b0c 000000000000003e7b0ba0ab332ef6659061f86fe63002f81d14cdd2b787b48d +246000 000000000000004c318a3ad2ebac28d140fada215b11f5b7d8e9151ff0b000af eccdaaffdadc837852f64c344ecbf0cca417df84a73435ca7ea7ce21245e87f0 00000000000000349dd94eadbc44ee38ecbf5e97227e37f3c9a7ad24f7ec8dfe +248000 000000000000004d945017c14b75a3a58a2aa6772cacbfcaf907b3bee6d7f344 8903f33f0671e4d616c52a9b7ff9fcfa52f2d8693de4d861171f9a9a4ebf60b4 00000000000000172fb9615729d960ebd66864c60f04f564e6b2464142460a58 +250000 000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214 fca9f44b3b916d15b3f443c421ca9ba2ab375fb4e04c67fa0376356bda89507c 000000000000001b3f536a81be90d5cbe8b79c2c1df53d1f91540cf5cb5a7c58 +252000 00000000000000200e99940b296ded4ce16462bba1950453b29abf313ba7cc47 e73cc4a756a24389065d1449aced46be359a3dde08d21771d6acc4cca13f7bfc 000000000000001ce1ddfafb3d2d71c7be37dc51a069f6fd3835ed5d0bd3cc3c +254000 000000000000004753be91559a2c74c6cb8a5d2be6db1df2ca0b2385697e53ff 53b9c0602531b91799388b526a92a080f416a050b11672d1d0445fa679675774 00000000000000305aaf9a4a98b6762204fba13dae98142875ff7557a51cb176 +256000 00000000000000252b217c0ce5c4d96b825b90dacbe8e4dcf5f6a8ba6749f3c2 3f5c51e6a34ee0efb91e840422f1a0cb9d369159ee3a60878af73275f8513fa2 000000000000002ab7b60009c3d6a4bfad05ad27e27fb0aea72fb9a3bd3ab9d2 +258000 00000000000000159f682a983465761f471dd24300746efe8db5642411f1b631 768d77dcefe6edb2ea15685557687aa1d56090364caa056a50500e9dbc003057 000000000000001b86532884bb74b3d170f05aa29367aebff48e139d561e2c35 +260000 000000000000001fb91fbcebaaba0e2d926f04908d798a8b598c3bd962951080 a3dce35682fb3ab81208ee85e060fca7df01ac1f1571963cc282aadba5dc7ae5 0000000000000006bda8a9646243754929a49cbe92a1312ad9623468cf99b9f3 +262000 000000000000001002ac67e026c523c3779b1ff2e3b9e2b7bfa6022ee1afae2a c84f3300243a15c28cb92da4a463a222994b4161ad7924d3ed4a229d2bea6ba2 00000000000000153388f79e68c8a5b974c6b73d0666ed6d75461af43c75aa81 +264000 000000000000000d05c31485c532503939ca0b88d7e322dff79900ee6cdd5ed4 0fbc45e463dd17169de0fa15142c8cc76b2e17ae63337522eedf481e67dede59 0000000000000007f58dd8567278c80bb9f964c293f02589e83dfceb8775fa60 +266000 0000000000000009d755c65d58c7c1fde9167ba632a85574de3bb11c8a862e35 2ec325ba811b0f3ab51d3634509e01163fcda807fb4283b22ff9df612640d05f 000000000000000c29b5b02f59257025f48808779bca45a0f1414344fcf59807 +268000 000000000000000048974ba0669938f7f8463650cd5c48c027aafd88c00a46af 8db51a37cf62199eaddb7b4c6eb8f3123ed0b86a5794e893e40973c96661b2b0 0000000000000001134627e5ac79f7fce271a5fdca76d5470758247ed65020f3 +270000 0000000000000002a775aec59dc6a9e4bb1c025cf1b8c2195dd9dc3998c827c5 c2346a70b37186219035dc71a1646401c8ba43c4e7acd77331e0fbdefce3b76e 00000000000000072c426558ed4a3431bfad3398b8b114aca7c0581337992105 +272000 00000000000000050a89e2ffb28757d35e14615f23b981eca68906c8c71f65f2 c65c9f220b58b16cca0692250d1e0cad5ab362f4ebed32341c48607e6fda97ab 00000000000000005ae2b9dd4ea05866eb5f5e8a8ea54e25a217a9c6bbb5024f +274000 0000000000000003fe2d3425e9f9b906f02f40b3db90d908ba0fbd1e44cf43f8 30ce70e30cdc5a67101f02b4f3a5c03a6884115dbcdc7575c9d67074410a0c53 0000000000000001dd30fc52fbfb29a7e7fa0c40da666b2ac5b010cc7acb3674 +276000 0000000000000004b8ed801f8a09ba8c1248a5b1dd1533a35124a80438573f59 e1c5aab0f6644074f689bbf82342ed9506b1a0870e16693f8ac4262998defa15 00000000000000017c2574b167a6be0482d330d8b3788c3ecf30aea1ce52a579 +278000 0000000000000001bcadd1e4b4d01063a17347dfca126c63893d2aa37d82eb7f 64b4ff707207f3cc5ee178ae31fd21657cd40058e4b229c73eeffdf0ee2a3554 00000000000000013efa0ef2b6d85ee121367173cc9d7eb375717e9782f4a6cf +280000 0000000000000001c091ada69f444dc0282ecaabe4808ddbb2532e5555db0c03 e2b966c103fc51cde523784e0ced0ee2cd3278b2e7b3df1f63a33f6b25a01ca1 0000000000000000bc7b8f8b4a60aeb73c05de005797af3b78e84d61c93f3d15 +282000 0000000000000002337ad25e6a9767420766309cfea79f13dd9c910bcf5ca063 f240c2cd23349a0e763f38e584f1dc0bbf1d90472771442fe7884d4985067ee9 00000000000000012781d061268f7e1fd21424013a0b48fb5b2e4b47ad44f353 +284000 0000000000000000eac86582f121e5431734e2ea36bf73347022c99c1adae37f 2d1a44421e7e34d10bb7b5c32a59c9c5a3b14573e3d0a46c90e322bb05161dc3 0000000000000001d6b73ce478f8801d837f94d3a8462e67e9c5d7898b5cfce7 +286000 00000000000000004388ae444347bde423f2f3aa6ef335b50909f5bc27d31ea3 e4ed93975428acd1ef1ef7bb927ac1daf20fb8c2d6adab05336992b6b0d0f4c7 00000000000000012f5d301e9e40642ff62d5ac36be969aa7ac5f3f4fec8087d +288000 00000000000000003c395f08779c3ac1301488b8a18c0999c008129a55610785 3b6fafbfdfc0b5178fa61259550f1b2103a5540487a626fdde1b6d9a0ba167a7 000000000000000125929e53afa23bbd42082294ea2035244570f993f4fc93d8 +290000 0000000000000000fa0b2badd05db0178623ebf8dd081fe7eb874c26e27d0b3b c58364e3c15d72620ef6e6a109ffa90f96e245c2ca97ce9a7dba1853fa82d3ac 00000000000000006fa3f3b92c95c83ddd9026af8e00227c2acd34b35a7bb290 +292000 0000000000000000620671231acb6a68134a0396235dcb0e53f4fc82bbaa1184 facb26fe1435fbbfc5a310535d2908aef9062c0a6fd9b68916079a8023caf2fb 0000000000000000b55300241bf11d4e59066bdf0af3baa1d5e61fef4a897305 +294000 0000000000000000cb2540b3f00ce422887904c75b24bf75b8a73817302a4138 b809bb53b2bfe7a4f5cc8799f0ed01ae9c7ad62e84337dedbaa254b645bd8d22 0000000000000000b2b41965d8307c588f5fcb4833ad51a7bb98009a4932d222 +296000 00000000000000009570102278e59ecf045c16ec8c8a5ea85bf823d0ec72e3d0 65ee22d627de991a1bbb6a0991a651f104402ced579619eb0f7a377d55773e7a 0000000000000000a330622827ca24512b9be55a9be6a489e5c5c22fdb735d9d +298000 000000000000000047d2f2eb7278e3f4aded9acaf502f5ec27bab5018b5871f2 017018dc979c71efe3f45156cf325f526282b12e166ddf89d268eeb58ecb2dd1 0000000000000000889350c2e7875fd9d66961571d80f4d8a1b09cb24c27f3fb +300000 000000000000000082ccf8f1557c5d40b21edabb18d2d691cfbf87118bac7254 f7d092ed2a8dde8b8d9cddd1506113821128e2e159b853639deab2900c4fa120 000000000000000049a0914d83df36982c77ac1f65ade6a52bdced2ce312aba9 +302000 0000000000000000072268c9bb18603566ed5012378c29bb4d37e34cead7448d 120995054ebb9c08b074422fba9ef42e8bb2bc30cd60258c844b966505f19a8c 000000000000000073fae68fe1d836d0267e1223de5d84f95adf177f5e16a337 +304000 00000000000000003558a1ceec3f5338c0e887b4171410195a7fa0a81bcaa628 19e4344dc468e4e7c8dc4007d8ceff0addaed303635905de439366142697ea06 000000000000000035b5ce4b07d7e44c04d197aa38db69d34707e6887b319f47 +306000 00000000000000002bb3265a8bf67ec2aa436c297ac7e56fcedd4dbaecccacc0 ac5028bfbcb9b75d7d6899a4011df8b145eeb608f5a49416bbef4bfc5c4a9abb 00000000000000005c3cad291bfb86105e4b7c480f630a2a4752d3277d9624b7 +308000 00000000000000001d55aa114bddd81938d09e2dccd432dec59a4078ca0bc0f4 7e4d47a510a28d57b7f11345446c8e54c6a6229d8b5769cd379ca605233d134e 00000000000000002584ecfe801597c83fc011536fbcbfba8dd4375eef09e4c6 +310000 0000000000000000125a28cc9e9209ddb75718f599a8039f6c9e7d9f1fb021e0 4648a8ed4221390d9a2c0fed720057624e3d33315588c4cc2bc9b8033d8c446d 00000000000000000e50e42984c1baafc6cf4d3e4d74d37e056dfa79fc63b5c6 +312000 00000000000000002bd1fa27964e31fe9861b40940e7ece2cfa359765b219a49 e9d2bd7f66ce893da7326ee58375c74646d42a908e8c4836316e557d2427669a 00000000000000002f3e589b149d8143eac0e65221f46ebc81413bea2ea696cf +314000 000000000000000008ae6cb20997f3c4aacc50ee2f0d08a0c3691907fe7357a3 58ca25e3391f26df92c47b9e5f6e19852248734b369cbba90b73c5e99e746470 0000000000000000291b836b50bb1ed8c086095ea8161635655685e42a45c9cb +316000 00000000000000000d77a89ab1069e47d1213ae509de95ee0d9ab095a725f7d7 7afd93faff66fc592596cb8bc2eee09e0a0f3e7f594b9655953b24922d3bb75d 00000000000000001c08ce6cb65c5e41420500579753d2249d22e8fa31aa03f7 +318000 00000000000000002583a647dc5f084a312e12bb90a70c3fe1eb1e4d419f35b6 498e6e0c39a2b4e3e112d0f79db25bfa7b482df8826a817e893738f9393b19c2 000000000000000025cf9c14a1e976f0e2c827ee18eb7273c24a5a4b53d10e83 +320000 000000000000000015aab005b28a326ade60f07515c33517ea5cb598f28fb7ea c4e88ac94f5537333d613291ce13a4161d96533fba812ba61748b95d02095695 00000000000000001bbfee4521419de4f79c19580027b00f9739ee7b2f0b5c57 +322000 0000000000000000177da809382f93ca1c4336811e4a910050689d317d62264e 5acfc8fe0a05892c2c92f047ba55547f125245877c2d12c6aff9f1d74a60e088 000000000000000009e46e2aa51bfa1fa0e6961ad8ee28b03716fc0616937cb3 +324000 00000000000000000b9880c40075d763b2a5f04fc01444a6278c5d2d442cda0b ab36c74346782a0047a2276e588492a5609d3fd7fc4f2a26645c70166db0f124 00000000000000001377803fa65444713dab6cae2c10172727775bb425c6a160 +326000 00000000000000001e95e7216072cd53353b964054b592f7ce84d3743aab125a 61a2e1cba22bc04a885f62544518c46f0eb4e7a39668028d67ff48b2aadb9b7b 000000000000000002ca091c068e0adfa158fadaa03ccf70af7d06ef2a563e98 +328000 000000000000000009cb9a303d105e7b96b36546a3196f6f79ece4b43712cbb2 3a7260ef08d756e217dbac41123a2d9c29e9449ceeed9690c4f67bc9f891011f 000000000000000010139d8c1bfa1933154b6ab111d827736f704cf91fa0e322 +330000 00000000000000000faabab19f17c0178c754dbed023e6c871dcaf74159c5f02 3f57d68b53b69e52e5d284e7566c2d0575c4bafb08e7de1cc0f9defbab5d78e6 00000000000000000271d56cb074731c2ffe250c9f9482ba47ab1a898122199a +332000 00000000000000001799255bc0c35f91f7d4fddfbf7e84dedf94fc59cde9b7f2 d833c527d933a4443bd9776ecf69d12f386cbe74d025812cb0eee5582098c962 0000000000000000084f645a8b53cfa7ec7faee3fabf3d1a853152584aa9c2c7 +334000 000000000000000008d1ff7b7673837e9d7e1324dc7ab8498405ea583f43f53d d28c040b4daea020a13a9720212ee698905b106bb985b46fa7fe3aaa3a45586c 0000000000000000199cd3ccb5feefff667d6ade51eb5e92531018d5b9cf197f +336000 0000000000000000125e3e6f327edcd7163b486efc16e79b8a996270127b54df 204e1ee93f97f61493e1de727c872cbfc11b7c51c42aca4f78e49ead1fffa7ad 000000000000000011bbfbfe73d56175a1906ca1eec461876887123e3f69a42e +338000 00000000000000001983dc4a87df627b63cdce28e5321cb867fbbb74c0e87e8e a10621d27b01bd6be869a6972b56505b2833076c33b04e8b5722e09b35091de1 0000000000000000030d9281927559e9ac954e63032101239f91108375eb4e61 +340000 00000000000000000d9b2508615d569e18f00c034d71474fc44a43af8d4a5003 3925a6d41b5ba3ee2bb450f109e6e0741fd3e21776ca9d1fd78ac3ae721e24a5 000000000000000017e6362910c6efd4dafe37d551a17db50608f19f52fb7bca +342000 0000000000000000007220892af98a563a1c891c756e94be3f14edddcf637c3e d4406c4644692a1e617b7e140714bfac57b4d5c1da5efcbabcf8867675cb7d07 000000000000000007a0870fbf18c6b9f23c623f7f332c1a06bcc1a260399940 +344000 000000000000000005f0a16f5a9f95eeb95c5eed0eb221e8f5dc5a9943a03aee 0b62e591128428eb437643cc5047e000149f30003ee8c7e1ce4cf57faf6d713f 00000000000000000b7c96af32f1e4317e3069ea4bfb02697caa6dbde7216f9a +346000 0000000000000000068d33fd865621cb7eedbf05c6b235191fa1cb8ee2c797d7 9b868fb539094f9e9185fe1d7683f0d6712247a64ffea660ac384ab6abead41c 00000000000000000f0b165c17e8dffc545815d7ea4be64efabf3a0d23014350 +348000 00000000000000001598a651988bb3a45237c4f801cf8049be20f74aed8e827a f88007d47bcb3ce6f2940440ec98237963376db32cb7cb7ab5d68b40717f3b27 00000000000000001462b7aeedcf2b5aac482d416c707d651d5465ac090002c0 +350000 0000000000000000053cf64f0400bb38e0c4b3872c38795ddde27acb40a112bb e59c9c36cc8fe49a7fc817551bec3eaebda6a5a21f337dc1f77fddeaf1c4c7a4 0000000000000000075f18b37aa8c6fe753d6804bb03ae91ba0d86c9cac3fd67 +352000 00000000000000001635a4b5f27d2ec458f7bca550d71f490b93e98e7a07cbca c191dbe07764711eff7795883414db7d14381de453776edfb75abd6f3e7bb013 000000000000000008d042a9fb824233bc40aa214bace9c05534d741580da39d +354000 00000000000000000cf8af9be2709e9d7adf2c33b3789aeeff517987f4be22e8 4b1e12b9f948003447d072f31f0531794e578d918f024580fbbb52f29d412463 000000000000000005ce357b2bb22f3e2e770a89d9f81af07e65aa28b11034bf +356000 0000000000000000138ce5493b612b0e90b66e2a76714088d6b3e6a4770215af dd4d81753ecf9b2ea599ede6307c8b4e0f7eea8dd9c677887d16c980270d13b9 0000000000000000153c94e6c7510bf67944d7b11e56de38c4c06850ee19c047 +358000 0000000000000000073aceefab8c381c3c4edb4f87a6d5d2ae32184278218429 9167ed0d73ec659f60b8b526b66078ec5c2eb263b7957a2bc1d16c36566d749c 00000000000000000c203f910ac1def0be1d848535518369e159a73002574a2c +360000 00000000000000000ca6e07cf681390ff888b7f96790286a440da0f2b87c8ea6 64d55132d7d41efd3c82522714f8ffc48d16b97ef1319de1b773d8e683ac70d1 0000000000000000144eda4e110a9389cb8e6a301366445ffee980862faff5bc +362000 00000000000000000bfcad6c331dd152cfc713e9e0790978a10e0bfda3e030d5 18a58a96470360af27c405f7aa63392676e77b723f524186926bf72b649c7070 000000000000000002f032a6c1d8fcc634946d36c10e1e1501d5b954eb82f726 +364000 00000000000000000e20bcf213a0bbd6be88d5fede6b060c737f7f8b7f1df504 09ec4fe62e9741db9583a5c93ea9b19663c84d0c97f34407e2e5905eac6fadd5 000000000000000004cb2acf1a28acd9d1e06d71357ed177ad61b9e6b8562ea4 +366000 0000000000000000138e108e780fdb71eb4cad533b46445ab6befbf9687f561f 02440f43691a61e3b6748396acab0cd04d6e2f7c52da764bb5ab8ff2f5b52551 00000000000000000affaf111f8dc332f8b2c3390c9a073d938dd1bdc5aec5ec +368000 00000000000000000d39970aac12754eb89c2dcfda539b65562e5c3fec102c24 6ef2048848f4ba32f43a8c9ae7c96ad44dac0cfb96344434acc96afcd57dbb3b 0000000000000000125427dedb152b12f85f1158054c6239b68169177e2155b9 +370000 000000000000000002cad3026f68357229dd6eaa6bcef6fe5166e1e53b039b8c 64bf9a93317f4241810ad1fd317b3353941c4c1d45e393485681b817204bcf23 000000000000000001ba6a172df04cb3a90e8badc70b7fdbd4a7b903695bf47e +372000 0000000000000000028093cc8035a6bc4e0d1b40932c2f8b50312a3fc86bf3da 1667a87afc743f41a0731091f2762b73d82cd28244fac555cf26623ee0922543 00000000000000000f2e596350c35a8a69c1f74416c19352cbacf7ef6f5baebe +374000 00000000000000001016aa3783721673bebbcd1efa49946b52cceb09a81465a6 083a4b6e7c05729940cbc80f545dc03eb45ad8c1b9990cbccbb80788835ded3a 0000000000000000029c559f066604a8e5ed21932434eefa57c8c9e6d6cb9e30 +376000 0000000000000000106e9e99cf4fce4e8a4abc97f3e883956e26d76b3a1133ce 1d5cccf38607557a1f0529cc6e1e447a6c179e1dbb9312f4fb8e6e75c11fb434 00000000000000000600fd599dddf15b50f48b66ccdea01ea56d2c093192062e +378000 00000000000000000516cd5b5f4b7e528d6e61c643595cc818f1d02f53da4281 a6816997bbb1524ad10392a1749a2ff4dbcfde9a54ce6e7a5eb020d33c0421be 00000000000000000aa09631f3e8649893da2525f739b6b088c76dc8e898e4e2 +380000 00000000000000000b06cee3cee10d2617e2024a996f5c613f7d786b15a571ff 6e6daa40b94422f281dbe453dbb9a66607593d5255dcd89ac17da7126a0719e4 00000000000000000bf2da5c23edccaa70ee183262cae2354f18f8a3201afa53 +382000 000000000000000003cf98590769bde40ffcd6800733ab47dd406d8203e65a89 dd7ef79f7cc85f27f2fc778e458e42669b1a0edc6fda9de066b75ab72859dc13 00000000000000000c43df306ac280360bb0592d2a56f2b1a9e4c8e870907bf9 +384000 000000000000000005dc7ea53e2f6eeb09798cc9d2214f09d249661c36c288b3 e58fa7e82c9b78bc96e506097a62546f80a8714575eed182322b5dadc08fdb48 0000000000000000033898c26a795ca3d35096d2d3e025823776277db16d977b +386000 00000000000000000d94c8c0b0ddec874d2a597e988154733d9ea614292c08bb 1744bde331acb42ff7fa8dc19cbfd8fa82272905fa9f7be058701cf2dc494bec 000000000000000007a2bea4f81d4172715f7ebdad1ad4021e3cb1d1c7da7c21 +388000 000000000000000003c5e9f4f84dc78b5ca96b7f2d89e9063b5f74543b42b9d5 5265b61950210ab7c9680de11d7be5bb02d3b5d3be97af2627c0cc0308104927 0000000000000000040a0115208109fa1a4a80f351e7aa474cb26c80506740be +390000 00000000000000000520000e60b56818523479ada2614806ba17ce0bbe6eaded 46bab737096a1e1bf800d9a0429688c8e676f3a480c850b3a5622bf580366703 0000000000000000055265fb53f189394aaa2c88ca37548c693c17965c9a45e2 +392000 00000000000000000850dc9d4a9a8d45d618d8f0dcbbdcc8a6fa88a6a90dfe1c 21d7a6c6c4b6e3c389c9d0046512b348d1f2246b8d9d5004bc1244cafd7d066a 000000000000000005b076c1bf4bb3c1bbf331c0d1a01461e9429a1b71f40821 +394000 000000000000000009ae6157a480e351cdeb8be494362a3bf3cd1c4feedf8ad6 e871c05b4794191df935d8a585fbabba5cb981ff5936d49a1078aa8ad925802f 000000000000000006d90033ca2d3e257db9853761609cf17b00cc6a6e705f48 +396000 0000000000000000079226c668cd1db713fb78ffc127b422e12b47baf205b478 f9542a8a8185328b82984691a41509cf245d008d875d158e6d770b703c08b5fa 000000000000000008e53dbc34ec365608efc9592fd982d616a9ef5258c72483 +398000 000000000000000001c6bd9d2dbccc3f16ddb534119de0aeb7d0a8c87f78e001 e73b9cb5fb81415bbe18e2601f261aeb8fe843d53ecf708219da5bfe096df418 0000000000000000029b38bdf2fb2b7ab210931ef90b0886f09d7000f54ee23d +400000 000000000000000004ec466ce4732fe6f1ed1cddc2ed4b328fff5224276e3f6f 6a5623df8be9c601913923a45a15138c81f2735aeb58930706cb6b5a729ae890 000000000000000005421b1b2ee6d06d037557d7f5ec96852542413cfed40c22 +402000 0000000000000000001b7da4ed218caf465ca9bb08a33712e8fc3fa508e6264c a713821d1bbb65b279f1b3419e9ee55faf8edc18af03d027089abc31b8789b69 000000000000000006e4cba5d6971fe5dd734dc68e158bf0a6f4d78c11d0e91f +404000 000000000000000004f9f0d6320d54c1f108130998e5bfb911f521ddf34da82c 65638c1d27075ca7bddf5f5bf7e6a1bc53b1ee60aa678c629091e3da60fe59a8 000000000000000001da1eeb6fa89a81b7534309e3dafa425db27e4e4e3bb972 +406000 000000000000000003b3efcefc5eaaef3b21671228233be52db1a080022462c1 9f141ccc21d86aa7ae67a18f7b405d6c4a24a367e4fe5c3bcaea08cfb20de64e 0000000000000000031c610eb5a810af32b531569c5fe681d0c2ddb7ae56be80 +408000 000000000000000003cc3d3e5b5d9b577b83c2b8d6f4257398c8f4aa8b2be649 0859f04d6ff78a9a631d5747e29d40e72defc3b4bcb58b046f73bc8bbd7aa50f 000000000000000004f62eeb625ddf5604eb9c3d9e5f214b643d23be2b83a99c +410000 0000000000000000060d7ea100ecb75c0a4dc482d05ff19ddaa8046b4b80a458 diff --git a/iguana/confs/BTC_peers.txt b/iguana/confs/BTC_peers.txt index abb52b839..99fc65790 100644 --- a/iguana/confs/BTC_peers.txt +++ b/iguana/confs/BTC_peers.txt @@ -1,137 +1,444 @@ +5.9.102.210 +144.76.136.19 +148.251.240.254 +148.251.6.18 +136.243.23.208 +136.243.17.66 +5.9.28.10 +78.47.121.249 +178.162.211.12 +188.40.61.208 +148.251.151.48 +5.196.65.56 +176.9.29.76 +37.58.60.177 +83.81.138.160 +188.40.93.205 +104.155.53.130 +178.162.215.231 +148.251.221.163 +62.210.253.10 +195.154.164.46 +185.82.23.218 +94.23.252.166 +195.154.163.75 +62.210.204.29 +136.243.13.76 +82.165.16.114 +80.86.92.70 +88.198.44.145 +213.5.36.58 +91.121.70.66 +136.243.61.143 +5.9.140.149 +62.107.200.30 +95.128.48.209 +185.38.184.62 +82.95.204.10 +96.240.33.91 +159.122.150.208 +46.28.205.67 +95.211.197.74 +136.243.139.96 +192.243.215.4 +37.187.247.50 +52.29.99.196 +80.57.227.14 +83.249.63.93 +188.165.210.62 +148.251.181.82 +90.104.150.191 +91.205.173.237 +144.76.70.163 +159.122.37.122 +141.0.158.41 +62.210.74.110 +78.46.193.75 +149.210.205.174 +5.9.145.8 +95.211.104.246 +139.162.196.240 +108.185.114.134 +89.36.212.55 +159.8.161.37 +5.196.65.205 +173.56.108.53 +176.31.216.47 +61.35.225.19 +185.101.107.142 +40.117.227.228 +62.210.82.206 +104.155.82.34 +70.35.98.39 +73.221.182.127 +84.200.2.6 +96.126.123.143 +82.73.154.77 +212.112.159.64 +217.79.191.72 +85.93.203.192 +107.6.174.152 +93.190.138.234 +188.166.19.37 +37.97.141.116 +213.47.171.165 +145.129.31.147 +46.229.165.154 +178.79.179.49 +5.79.72.76 +78.193.96.155 +52.30.166.153 +5.196.69.107 +148.251.122.162 +85.25.196.59 +5.39.75.32 +169.57.140.252 +85.214.204.55 +5.39.174.119 +93.186.197.146 +52.28.19.80 +52.72.156.74 +89.46.74.126 +188.138.88.42 +80.229.151.187 +81.136.30.26 +82.217.214.215 +195.154.173.26 +98.208.76.134 +149.210.169.223 +81.138.88.97 +79.127.240.99 +52.7.106.177 +94.7.221.2 +73.25.181.210 +195.154.164.243 +46.183.216.215 +80.218.130.117 +98.125.79.158 +130.185.144.213 +46.50.234.179 +50.206.138.176 +76.120.20.22 +54.201.80.160 +163.172.7.30 +52.11.33.24 +112.118.13.88 +128.199.174.62 +46.101.29.96 +95.211.168.221 +169.54.98.38 +51.255.42.173 +109.236.91.86 +24.96.241.48 +206.221.184.235 +5.149.251.67 +92.222.180.14 +50.35.14.160 +101.200.72.211 +176.36.68.69 +173.252.46.16 +128.199.50.89 +173.62.215.217 +185.81.164.187 +71.245.189.11 +52.90.128.203 +62.238.34.125 +36.2.119.80 +96.234.214.85 +74.122.237.124 +52.49.168.48 +104.196.57.143 +193.10.64.85 +188.165.246.217 +86.86.139.48 +5.249.159.58 +123.56.91.81 +141.134.69.253 +75.109.245.15 +198.204.224.106 +71.202.149.229 +67.167.76.248 +169.54.79.200 +161.202.233.171 +159.203.110.178 +78.46.238.87 +50.116.59.236 +54.172.84.78 +144.76.43.181 +212.186.244.2 +95.174.83.89 +213.107.69.133 +192.81.249.110 +153.120.156.83 +176.9.103.226 +98.250.82.63 +68.197.233.152 +99.231.225.222 +82.221.108.21 +70.75.20.127 +212.83.138.114 +138.201.27.171 +151.80.21.57 +94.100.208.234 +198.178.123.147 +204.152.207.114 +207.226.141.253 +52.26.127.162 +198.27.81.24 +192.52.167.188 +122.58.50.139 +54.200.14.112 +195.239.1.66 +64.121.3.163 +52.192.211.14 108.58.252.82 +85.95.228.141 +85.25.194.28 +77.57.59.174 +5.9.85.14 +73.254.38.48 +68.228.159.39 +95.241.163.69 +37.187.111.147 +86.15.59.160 +24.220.159.80 +52.48.21.145 +54.173.214.35 +62.138.0.233 +130.83.160.187 +23.236.144.69 +209.73.158.58 +83.183.17.191 +86.246.166.172 +213.136.75.205 +109.169.68.140 +45.32.235.62 +72.177.4.164 +103.60.126.81 +45.32.240.41 +98.127.84.204 +137.226.109.169 +91.121.123.107 +52.10.170.186 +188.212.43.10 +5.61.40.21 +96.127.202.148 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 +73.28.33.209 +5.189.181.97 +162.245.217.133 +79.165.235.119 +173.79.124.213 +176.36.37.62 +54.232.98.22 +52.48.23.201 +108.61.188.168 +83.227.173.83 +159.122.150.194 +37.187.4.9 +185.121.170.160 +104.58.20.16 +63.142.255.160 +147.83.72.91 +185.122.56.247 +94.214.2.74 +52.37.69.165 +100.2.192.110 +104.168.248.132 +50.206.138.178 +5.249.151.47 +46.166.164.223 +78.245.193.210 +71.192.10.200 +83.249.79.101 +176.223.201.198 +88.115.28.12 +81.169.244.142 +85.3.93.45 +109.235.69.142 +185.58.193.97 +74.83.140.242 +46.229.238.187 +92.221.127.99 +89.46.70.209 +82.78.191.165 +85.166.189.122 +185.65.132.119 +178.199.96.108 +109.251.161.121 +5.189.162.70 +123.2.57.36 +92.63.110.16 +142.4.213.204 +108.59.9.167 +73.191.226.169 +104.168.62.209 +85.172.79.190 +82.118.233.111 +173.12.181.181 +104.234.246.67 +23.89.201.181 +73.5.77.186 +80.241.219.44 +54.172.84.89 +194.237.158.153 +2.227.253.109 +192.95.56.199 +54.86.114.40 +198.100.144.182 +107.191.39.221 +69.30.244.210 +104.196.22.0 +114.215.192.186 +52.62.33.159 +91.152.150.35 +169.54.79.201 +73.150.59.209 +52.91.222.10 +52.23.159.174 +71.184.65.44 +195.154.134.78 +85.214.234.254 +185.7.32.111 +52.90.57.21 +199.233.246.220 +119.9.119.139 +149.3.91.183 +104.236.91.250 +108.61.157.125 +108.49.39.239 +46.101.103.235 +86.106.93.109 +54.172.114.28 +213.174.156.65 +54.169.131.166 +52.90.9.14 +198.58.125.193 +62.194.9.18 +52.70.112.111 +81.132.41.243 +216.189.153.172 +52.68.68.148 +107.191.33.83 +78.130.213.74 +5.196.46.249 +64.189.174.5 +78.121.69.23 +4.15.180.30 +73.158.217.222 +108.173.69.240 +66.128.118.35 +174.27.72.80 +211.103.126.194 +99.55.142.44 +125.21.163.79 +203.29.87.136 +199.66.175.101 +107.191.41.89 +67.183.245.116 +50.126.86.251 +169.38.69.194 +72.181.158.116 +173.74.40.32 +121.99.178.161 +174.57.190.26 +24.182.133.130 +192.169.6.102 +24.44.55.98 +185.35.67.75 +216.189.149.50 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 +75.109.245.28 +210.84.33.37 +54.223.72.115 +69.50.171.205 +95.213.187.218 +95.165.168.168 +194.87.1.232 +119.81.11.73 +192.187.114.190 +204.28.124.82 +82.3.187.22 +169.57.28.116 +70.183.119.69 +198.50.138.53 +67.221.193.55 +162.243.132.6 +218.161.44.5 +104.168.248.130 +100.36.105.243 +50.30.46.177 +104.237.138.120 +24.253.96.23 +71.252.137.242 +192.99.12.223 +24.28.81.162 +198.84.253.45 +52.8.99.184 +173.31.158.113 +98.219.248.107 +139.196.241.246 +65.49.51.61 +173.179.37.8 +73.74.104.224 +38.124.124.141 +104.168.158.185 +75.74.28.26 +173.224.246.184 +190.153.217.238 +96.37.9.173 +23.245.116.86 +192.203.228.71 +91.177.60.251 +208.111.48.132 +207.255.42.202 +24.69.65.191 +69.30.214.34 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 +52.10.150.72 +50.82.159.245 +54.175.75.186 +158.69.226.147 +50.30.37.103 +98.7.26.60 +175.126.148.99 +52.36.208.42 +71.199.193.202 +192.169.7.83 +1.234.70.35 +173.192.31.142 +76.175.8.222 +52.8.184.157 +65.182.236.136 +119.240.36.151 +31.170.178.235 +185.112.157.157 +45.79.78.56 +104.236.15.195 +23.253.148.208 +54.165.213.225 +104.197.104.142 +46.229.165.140 +158.69.149.39 +70.33.217.30 +31.41.247.133 +104.205.18.189 +184.70.15.166 +70.88.53.161 +85.70.234.114 +67.205.112.207 +91.193.121.154 +96.56.145.250 +96.44.156.201 +184.58.162.35 +69.94.30.177 +110.10.130.17 +81.175.241.116 +23.252.120.136 +68.145.236.222 +142.227.120.102 +89.157.100.135 +138.201.30.201 +109.72.32.30 +76.102.14.28 +52.26.124.186 diff --git a/iguana/css/bootstrap.css b/iguana/css/bootstrap.css index cd1c616ad..0be9eef29 100755 --- a/iguana/css/bootstrap.css +++ b/iguana/css/bootstrap.css @@ -2,4 +2,12 @@ * Bootstrap v3.3.4 (http://getbootstrap.com) * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - *//*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff!important}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date],input[type=time],input[type=datetime-local],input[type=month]{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px \9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.form-group-sm .form-control{height:30px;line-height:30px}select[multiple].form-group-sm .form-control,textarea.form-group-sm .form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:5px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.form-group-lg .form-control{height:46px;line-height:46px}select[multiple].form-group-lg .form-control,textarea.form-group-lg .form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:10px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.33px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.active,.btn-default.focus,.btn-default:active,.btn-default:focus,.btn-default:hover,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.active,.btn-primary.focus,.btn-primary:active,.btn-primary:focus,.btn-primary:hover,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.active,.btn-success.focus,.btn-success:active,.btn-success:focus,.btn-success:hover,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.active,.btn-info.focus,.btn-info:active,.btn-info:focus,.btn-info:hover,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.active,.btn-warning.focus,.btn-warning:active,.btn-warning:focus,.btn-warning:hover,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.active,.btn-danger.focus,.btn-danger:active,.btn-danger:focus,.btn-danger:hover,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px solid}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px)and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:2;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px 15px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding:48px 0}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{min-height:16.43px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-weight:400;line-height:1.4;filter:alpha(opacity=0);opacity:0}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-weight:400;line-height:1.42857143;text-align:left;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2)}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000;perspective:1000}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;margin-top:-10px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px)and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px)and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px)and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px)and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px)and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px)and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px)and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px)and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px)and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px)and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} \ No newline at end of file + *//*! normalize.css v3.0.2 | MIT License | git.io/normalize */ +th.sorted.ascending:after { + content: " \2191"; +} + +th.sorted.descending:after { + content: " \2193"; +} +html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff!important}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:500px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date],input[type=time],input[type=datetime-local],input[type=month]{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px \9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.form-group-sm .form-control{height:30px;line-height:30px}select[multiple].form-group-sm .form-control,textarea.form-group-sm .form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:5px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.form-group-lg .form-control{height:46px;line-height:46px}select[multiple].form-group-lg .form-control,textarea.form-group-lg .form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:10px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.33px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.active,.btn-default.focus,.btn-default:active,.btn-default:focus,.btn-default:hover,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.active,.btn-primary.focus,.btn-primary:active,.btn-primary:focus,.btn-primary:hover,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.active,.btn-success.focus,.btn-success:active,.btn-success:focus,.btn-success:hover,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.active,.btn-info.focus,.btn-info:active,.btn-info:focus,.btn-info:hover,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.active,.btn-warning.focus,.btn-warning:active,.btn-warning:focus,.btn-warning:hover,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.active,.btn-danger.focus,.btn-danger:active,.btn-danger:focus,.btn-danger:hover,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px solid}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px)and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:2;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px 15px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding:48px 0}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{min-height:16.43px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-weight:400;line-height:1.4;filter:alpha(opacity=0);opacity:0}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-weight:400;line-height:1.42857143;text-align:left;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2)}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000;perspective:1000}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;margin-top:-10px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px)and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px)and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px)and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px)and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px)and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px)and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px)and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px)and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px)and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px)and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} \ No newline at end of file diff --git a/iguana/css/googleFonts.css b/iguana/css/googleFonts.css old mode 100644 new mode 100755 diff --git a/iguana/css/googleIcons.css b/iguana/css/googleIcons.css old mode 100644 new mode 100755 diff --git a/iguana/css/googleTheme.css b/iguana/css/googleTheme.css old mode 100644 new mode 100755 diff --git a/iguana/css/jquery.dropdown.css b/iguana/css/jquery.dropdown.css old mode 100644 new mode 100755 diff --git a/iguana/css/ripples.css b/iguana/css/ripples.css old mode 100644 new mode 100755 diff --git a/iguana/databases/cdb-0.75/CHANGES b/iguana/databases/cdb-0.75/CHANGES new file mode 100644 index 000000000..a7d65cf03 --- /dev/null +++ b/iguana/databases/cdb-0.75/CHANGES @@ -0,0 +1,16 @@ +20000215 + api: rewrote almost everything from scratch. tnx Ken Lalonde for + suggesting mmap. +20000216 + ui: cdbget supports skip. + version: cdb 0.70, beta. +20000219 + bug: cdb_make_addbegin() didn't explicitly return 0. impact: + database creation could fail on systems that didn't + follow the traditional C return behavior. fix: obvious. + tnx Uwe Ohse. + internal: increased bspace in cdb_make.h from 1024 to 8192. + internal: switched cdbmake to PUTC, GETC. 3x speedup here. + internal: added testzero to rts. + ui: posplus() sets nomem if it passes 4GB. + version: cdb 0.75, beta. diff --git a/iguana/databases/cdb-0.75/FILES b/iguana/databases/cdb-0.75/FILES new file mode 100644 index 000000000..baceb8677 --- /dev/null +++ b/iguana/databases/cdb-0.75/FILES @@ -0,0 +1,78 @@ +README +TODO +CHANGES +VERSION +FILES +SYSDEPS +TARGETS +conf-cc +conf-ld +conf-home +Makefile +cdbget.c +cdbmake.c +cdbdump.c +cdbstats.c +cdbtest.c +cdbmake-12.sh +cdbmake-sv.sh +cdb.h +cdb.c +cdb_hash.c +cdb_make.h +cdb_make.c +rts.sh +rts.tests +rts.exp +testzero.c +random.cdb +choose.sh +warn-auto.sh +find-systype.sh +trycpp.c +x86cpuid.c +alloc.c +alloc.h +auto-str.c +auto_home.h +buffer.c +buffer.h +buffer_0.c +buffer_1.c +buffer_1s.c +buffer_2.c +buffer_copy.c +buffer_get.c +buffer_put.c +byte.h +byte_copy.c +byte_cr.c +byte_diff.c +error.c +error.h +error_str.c +exit.h +fmt.h +fmt_ulong.c +hier.c +install.c +instcheck.c +open.h +open_read.c +open_trunc.c +readwrite.h +scan.h +scan_ulong.c +seek.h +seek_cur.c +seek_set.c +str.h +str_len.c +strerr.h +strerr_die.c +strerr_sys.c +tryulong32.c +uint32.h1 +uint32.h2 +uint32_pack.c +uint32_unpack.c diff --git a/iguana/databases/cdb-0.75/Makefile b/iguana/databases/cdb-0.75/Makefile new file mode 100644 index 000000000..27d97011a --- /dev/null +++ b/iguana/databases/cdb-0.75/Makefile @@ -0,0 +1,320 @@ +# Don't edit Makefile! Use conf-* for configuration. + +SHELL=/bin/sh + +default: it + +alloc.a: \ +makelib alloc.o + ./makelib alloc.a alloc.o + +alloc.o: \ +compile alloc.c alloc.h error.h + ./compile alloc.c + +auto-str: \ +load auto-str.o buffer.a unix.a byte.a + ./load auto-str buffer.a unix.a byte.a + +auto-str.o: \ +compile auto-str.c buffer.h readwrite.h exit.h + ./compile auto-str.c + +auto_home.c: \ +auto-str conf-home + ./auto-str auto_home `head -1 conf-home` > auto_home.c + +auto_home.o: \ +compile auto_home.c + ./compile auto_home.c + +buffer.a: \ +makelib strerr_sys.o buffer.o buffer_put.o buffer_2.o strerr_die.o \ +buffer_get.o buffer_copy.o buffer_1.o buffer_0.o buffer_1s.o + ./makelib buffer.a strerr_sys.o buffer.o buffer_put.o \ + buffer_2.o strerr_die.o buffer_get.o buffer_copy.o \ + buffer_1.o buffer_0.o buffer_1s.o + +buffer.o: \ +compile buffer.c buffer.h + ./compile buffer.c + +buffer_0.o: \ +compile buffer_0.c readwrite.h buffer.h + ./compile buffer_0.c + +buffer_1.o: \ +compile buffer_1.c readwrite.h buffer.h + ./compile buffer_1.c + +buffer_1s.o: \ +compile buffer_1s.c readwrite.h buffer.h + ./compile buffer_1s.c + +buffer_2.o: \ +compile buffer_2.c readwrite.h buffer.h + ./compile buffer_2.c + +buffer_copy.o: \ +compile buffer_copy.c buffer.h + ./compile buffer_copy.c + +buffer_get.o: \ +compile buffer_get.c buffer.h byte.h error.h + ./compile buffer_get.c + +buffer_put.o: \ +compile buffer_put.c buffer.h str.h byte.h error.h + ./compile buffer_put.c + +byte.a: \ +makelib byte_copy.o byte_cr.o str_len.o fmt_ulong.o uint32_unpack.o \ +byte_diff.o uint32_pack.o scan_ulong.o + ./makelib byte.a byte_copy.o byte_cr.o str_len.o \ + fmt_ulong.o uint32_unpack.o byte_diff.o uint32_pack.o \ + scan_ulong.o + +byte_copy.o: \ +compile byte_copy.c byte.h + ./compile byte_copy.c + +byte_cr.o: \ +compile byte_cr.c byte.h + ./compile byte_cr.c + +byte_diff.o: \ +compile byte_diff.c byte.h + ./compile byte_diff.c + +cdb.a: \ +makelib cdb.o cdb_hash.o cdb_make.o + ./makelib cdb.a cdb.o cdb_hash.o cdb_make.o + +cdb.o: \ +compile cdb.c readwrite.h error.h seek.h byte.h cdb.h uint32.h + ./compile cdb.c + +cdb_hash.o: \ +compile cdb_hash.c cdb.h uint32.h + ./compile cdb_hash.c + +cdb_make.o: \ +compile cdb_make.c readwrite.h seek.h error.h alloc.h cdb.h uint32.h \ +cdb_make.h buffer.h uint32.h + ./compile cdb_make.c + +cdbdump: \ +load cdbdump.o buffer.a unix.a byte.a + ./load cdbdump buffer.a unix.a byte.a + +cdbdump.o: \ +compile cdbdump.c uint32.h fmt.h buffer.h strerr.h + ./compile cdbdump.c + +cdbget: \ +load cdbget.o cdb.a buffer.a unix.a byte.a + ./load cdbget cdb.a buffer.a unix.a byte.a + +cdbget.o: \ +compile cdbget.c exit.h scan.h str.h buffer.h strerr.h cdb.h uint32.h + ./compile cdbget.c + +cdbmake: \ +load cdbmake.o cdb.a alloc.a buffer.a unix.a byte.a + ./load cdbmake cdb.a alloc.a buffer.a unix.a byte.a + +cdbmake-12: \ +warn-auto.sh cdbmake-12.sh conf-home + cat warn-auto.sh cdbmake-12.sh \ + | sed s}HOME}"`head -1 conf-home`"}g \ + > cdbmake-12 + chmod 755 cdbmake-12 + +cdbmake-sv: \ +warn-auto.sh cdbmake-sv.sh conf-home + cat warn-auto.sh cdbmake-sv.sh \ + | sed s}HOME}"`head -1 conf-home`"}g \ + > cdbmake-sv + chmod 755 cdbmake-sv + +cdbmake.o: \ +compile cdbmake.c error.h open.h strerr.h cdb_make.h buffer.h \ +uint32.h cdb.h uint32.h + ./compile cdbmake.c + +cdbstats: \ +load cdbstats.o cdb.a buffer.a unix.a byte.a + ./load cdbstats cdb.a buffer.a unix.a byte.a + +cdbstats.o: \ +compile cdbstats.c uint32.h fmt.h buffer.h strerr.h seek.h cdb.h \ +uint32.h + ./compile cdbstats.c + +cdbtest: \ +load cdbtest.o cdb.a buffer.a unix.a byte.a + ./load cdbtest cdb.a buffer.a unix.a byte.a + +cdbtest.o: \ +compile cdbtest.c uint32.h fmt.h buffer.h strerr.h seek.h cdb.h \ +uint32.h + ./compile cdbtest.c + +check: \ +it instcheck + ./instcheck + +compile: \ +warn-auto.sh conf-cc + ( cat warn-auto.sh; \ + echo exec "`head -1 conf-cc`" '-c $${1+"$$@"}' \ + ) > compile + chmod 755 compile + +error.o: \ +compile error.c error.h + ./compile error.c + +error_str.o: \ +compile error_str.c error.h + ./compile error_str.c + +fmt_ulong.o: \ +compile fmt_ulong.c fmt.h + ./compile fmt_ulong.c + +hier.o: \ +compile hier.c auto_home.h + ./compile hier.c + +install: \ +load install.o hier.o auto_home.o buffer.a unix.a byte.a + ./load install hier.o auto_home.o buffer.a unix.a byte.a + +install.o: \ +compile install.c buffer.h strerr.h error.h open.h readwrite.h exit.h + ./compile install.c + +instcheck: \ +load instcheck.o hier.o auto_home.o buffer.a unix.a byte.a + ./load instcheck hier.o auto_home.o buffer.a unix.a byte.a + +instcheck.o: \ +compile instcheck.c strerr.h error.h readwrite.h exit.h + ./compile instcheck.c + +it: \ +prog install instcheck + +load: \ +warn-auto.sh conf-ld + ( cat warn-auto.sh; \ + echo 'main="$$1"; shift'; \ + echo exec "`head -1 conf-ld`" \ + '-o "$$main" "$$main".o $${1+"$$@"}' \ + ) > load + chmod 755 load + +makelib: \ +warn-auto.sh systype + ( cat warn-auto.sh; \ + echo 'main="$$1"; shift'; \ + echo 'rm -f "$$main"'; \ + echo 'ar cr "$$main" $${1+"$$@"}'; \ + case "`cat systype`" in \ + sunos-5.*) ;; \ + unix_sv*) ;; \ + irix64-*) ;; \ + irix-*) ;; \ + dgux-*) ;; \ + hp-ux-*) ;; \ + sco*) ;; \ + *) echo 'ranlib "$$main"' ;; \ + esac \ + ) > makelib + chmod 755 makelib + +open_read.o: \ +compile open_read.c open.h + ./compile open_read.c + +open_trunc.o: \ +compile open_trunc.c open.h + ./compile open_trunc.c + +prog: \ +cdbget cdbmake cdbdump cdbstats cdbtest cdbmake-12 cdbmake-sv rts \ +testzero + +rts: \ +warn-auto.sh rts.sh conf-home + cat warn-auto.sh rts.sh \ + | sed s}HOME}"`head -1 conf-home`"}g \ + > rts + chmod 755 rts + +scan_ulong.o: \ +compile scan_ulong.c scan.h + ./compile scan_ulong.c + +seek_cur.o: \ +compile seek_cur.c seek.h + ./compile seek_cur.c + +seek_set.o: \ +compile seek_set.c seek.h + ./compile seek_set.c + +setup: \ +it install + ./install + +str_len.o: \ +compile str_len.c str.h + ./compile str_len.c + +strerr_die.o: \ +compile strerr_die.c buffer.h exit.h strerr.h + ./compile strerr_die.c + +strerr_sys.o: \ +compile strerr_sys.c error.h strerr.h + ./compile strerr_sys.c + +systype: \ +find-systype.sh conf-cc conf-ld trycpp.c x86cpuid.c + ( cat warn-auto.sh; \ + echo CC=\'`head -1 conf-cc`\'; \ + echo LD=\'`head -1 conf-ld`\'; \ + cat find-systype.sh; \ + ) | sh > systype + +testzero: \ +load testzero.o cdb.a alloc.a buffer.a unix.a byte.a + ./load testzero cdb.a alloc.a buffer.a unix.a byte.a + +testzero.o: \ +compile testzero.c uint32.h scan.h strerr.h cdb_make.h buffer.h \ +uint32.h + ./compile testzero.c + +uint32.h: \ +tryulong32.c compile load uint32.h1 uint32.h2 + ( ( ./compile tryulong32.c && ./load tryulong32 && \ + ./tryulong32 ) >/dev/null 2>&1 \ + && cat uint32.h2 || cat uint32.h1 ) > uint32.h + rm -f tryulong32.o tryulong32 + +uint32_pack.o: \ +compile uint32_pack.c uint32.h + ./compile uint32_pack.c + +uint32_unpack.o: \ +compile uint32_unpack.c uint32.h + ./compile uint32_unpack.c + +unix.a: \ +makelib error.o open_read.o open_trunc.o error_str.o seek_set.o \ +seek_cur.o + ./makelib unix.a error.o open_read.o open_trunc.o \ + error_str.o seek_set.o seek_cur.o diff --git a/iguana/databases/cdb-0.75/README b/iguana/databases/cdb-0.75/README new file mode 100644 index 000000000..f65d42925 --- /dev/null +++ b/iguana/databases/cdb-0.75/README @@ -0,0 +1,7 @@ +cdb 0.75, beta. +20000219 +Copyright 2000 +D. J. Bernstein + +cdb home page: http://cr.yp.to/cdb.html +Installation instructions: http://cr.yp.to/cdb/install.html diff --git a/iguana/databases/cdb-0.75/SYSDEPS b/iguana/databases/cdb-0.75/SYSDEPS new file mode 100644 index 000000000..d8e1bcf3c --- /dev/null +++ b/iguana/databases/cdb-0.75/SYSDEPS @@ -0,0 +1,3 @@ +VERSION +systype +uint32.h diff --git a/iguana/databases/cdb-0.75/TARGETS b/iguana/databases/cdb-0.75/TARGETS new file mode 100644 index 000000000..951687050 --- /dev/null +++ b/iguana/databases/cdb-0.75/TARGETS @@ -0,0 +1,66 @@ +load +compile +uint32.h +cdbget.o +systype +makelib +cdb.o +cdb_hash.o +cdb_make.o +cdb.a +strerr_sys.o +buffer.o +buffer_put.o +buffer_2.o +strerr_die.o +buffer_get.o +buffer_copy.o +buffer_1.o +buffer_0.o +buffer_1s.o +buffer.a +error.o +open_read.o +open_trunc.o +error_str.o +seek_set.o +seek_cur.o +unix.a +byte_copy.o +byte_cr.o +str_len.o +fmt_ulong.o +uint32_unpack.o +byte_diff.o +uint32_pack.o +scan_ulong.o +byte.a +cdbget +cdbmake.o +alloc.o +alloc.a +cdbmake +cdbdump.o +cdbdump +cdbstats.o +cdbstats +cdbtest.o +cdbtest +cdbmake-12 +cdbmake-sv +rts +testzero.o +testzero +prog +install.o +hier.o +auto-str.o +auto-str +auto_home.c +auto_home.o +install +instcheck.o +instcheck +it +setup +check diff --git a/iguana/databases/cdb-0.75/TODO b/iguana/databases/cdb-0.75/TODO new file mode 100644 index 000000000..3725be678 --- /dev/null +++ b/iguana/databases/cdb-0.75/TODO @@ -0,0 +1 @@ +more rts diff --git a/iguana/databases/cdb-0.75/VERSION b/iguana/databases/cdb-0.75/VERSION new file mode 100644 index 000000000..7001427ad --- /dev/null +++ b/iguana/databases/cdb-0.75/VERSION @@ -0,0 +1 @@ +cdb 0.75 diff --git a/iguana/databases/cdb-0.75/alloc.c b/iguana/databases/cdb-0.75/alloc.c new file mode 100644 index 000000000..e8aede5a2 --- /dev/null +++ b/iguana/databases/cdb-0.75/alloc.c @@ -0,0 +1,32 @@ +#include "alloc.h" +#include "error.h" +//extern char *malloc(); +//extern void free(); + +#define ALIGNMENT 16 /* XXX: assuming that this alignment is enough */ +#define SPACE 4096 /* must be multiple of ALIGNMENT */ + +typedef union { char irrelevant[ALIGNMENT]; double d; } aligned; +static aligned realspace[SPACE / ALIGNMENT]; +#define space ((char *) realspace) +static unsigned int avail = SPACE; /* multiple of ALIGNMENT; 0<=avail<=SPACE */ + +/*@null@*//*@out@*/char *alloc(n) +unsigned int n; +{ + char *x; + n = ALIGNMENT + n - (n & (ALIGNMENT - 1)); /* XXX: could overflow */ + if (n <= avail) { avail -= n; return space + avail; } + x = malloc(n); + if (!x) errno = error_nomem; + return x; +} + +void alloc_free(x) +char *x; +{ + if (x >= space) + if (x < space + SPACE) + return; /* XXX: assuming that pointers are flat */ + free(x); +} diff --git a/iguana/databases/cdb-0.75/alloc.h b/iguana/databases/cdb-0.75/alloc.h new file mode 100644 index 000000000..d44adb952 --- /dev/null +++ b/iguana/databases/cdb-0.75/alloc.h @@ -0,0 +1,9 @@ +#ifndef ALLOC_H +#define ALLOC_H +#include + +extern /*@null@*//*@out@*/char *alloc(); +extern void alloc_free(); +extern int alloc_re(); + +#endif diff --git a/iguana/databases/cdb-0.75/auto-str b/iguana/databases/cdb-0.75/auto-str new file mode 100755 index 000000000..dc772f730 Binary files /dev/null and b/iguana/databases/cdb-0.75/auto-str differ diff --git a/iguana/databases/cdb-0.75/auto-str.c b/iguana/databases/cdb-0.75/auto-str.c new file mode 100644 index 000000000..f1063ed25 --- /dev/null +++ b/iguana/databases/cdb-0.75/auto-str.c @@ -0,0 +1,45 @@ +#include "buffer.h" +#include "readwrite.h" +#include "exit.h" + +char buf1[256]; +buffer ss1 = BUFFER_INIT(write,1,buf1,sizeof(buf1)); + +void puts(s) +char *s; +{ + if (buffer_puts(&ss1,s) == -1) _exit(111); +} + +int main(argc,argv) +int argc; +char **argv; +{ + char *name; + char *value; + unsigned char ch; + char octal[4]; + + name = argv[1]; + if (!name) _exit(100); + value = argv[2]; + if (!value) _exit(100); + + puts("char "); + puts(name); + puts("[] = \"\\\n"); + + while ( (ch= *value++) != 0 ) + { + puts("\\"); + octal[3] = 0; + octal[2] = '0' + (ch & 7); ch >>= 3; + octal[1] = '0' + (ch & 7); ch >>= 3; + octal[0] = '0' + (ch & 7); + puts(octal); + } + + puts("\\\n\";\n"); + if (buffer_flush(&ss1) == -1) _exit(111); + _exit(0); +} diff --git a/iguana/databases/cdb-0.75/auto_home.c b/iguana/databases/cdb-0.75/auto_home.c new file mode 100644 index 000000000..e2128c5ff --- /dev/null +++ b/iguana/databases/cdb-0.75/auto_home.c @@ -0,0 +1,3 @@ +char auto_home[] = "\ +\057\165\163\162\057\154\157\143\141\154\ +"; diff --git a/iguana/databases/cdb-0.75/auto_home.h b/iguana/databases/cdb-0.75/auto_home.h new file mode 100644 index 000000000..a756cd063 --- /dev/null +++ b/iguana/databases/cdb-0.75/auto_home.h @@ -0,0 +1,6 @@ +#ifndef AUTO_HOME_H +#define AUTO_HOME_H + +extern char auto_home[]; + +#endif diff --git a/iguana/databases/cdb-0.75/buffer.c b/iguana/databases/cdb-0.75/buffer.c new file mode 100644 index 000000000..8833f715b --- /dev/null +++ b/iguana/databases/cdb-0.75/buffer.c @@ -0,0 +1,10 @@ +#include "buffer.h" + +void buffer_init(buffer *s,ssize_t (*op)(),int fd,char *buf,unsigned int len) +{ + s->x = buf; + s->fd = fd; + s->op = op; + s->p = 0; + s->n = len; +} diff --git a/iguana/databases/cdb-0.75/buffer.h b/iguana/databases/cdb-0.75/buffer.h new file mode 100644 index 000000000..7f5fb5dba --- /dev/null +++ b/iguana/databases/cdb-0.75/buffer.h @@ -0,0 +1,58 @@ +#ifndef BUFFER_H +#define BUFFER_H +#include +#include + +typedef struct buffer { + char *x; + unsigned int p; + unsigned int n; + int fd; + ssize_t (*op)(); +} buffer; + +#define BUFFER_INIT(op,fd,buf,len) { (buf), 0, (len), (fd), (op) } +#define BUFFER_INSIZE 8192 +#define BUFFER_OUTSIZE 8192 + +extern void buffer_init(buffer *,ssize_t (*)(),int,char *,unsigned int); + +extern int buffer_flush(buffer *); +extern int buffer_put(buffer *,char *,unsigned int); +extern int buffer_putalign(buffer *,char *,unsigned int); +extern int buffer_putflush(buffer *,char *,unsigned int); +extern int buffer_puts(buffer *,char *); +extern int buffer_putsalign(buffer *,char *); +extern int buffer_putsflush(buffer *,char *); + +#define buffer_PUTC(s,c) \ + ( ((s)->n != (s)->p) \ + ? ( (s)->x[(s)->p++] = (c), 0 ) \ + : buffer_put((s),&(c),1) \ + ) + +extern int buffer_get(buffer *,char *,unsigned int); +extern int buffer_bget(buffer *,char *,unsigned int); +extern int buffer_feed(buffer *); + +extern char *buffer_peek(buffer *); +extern void buffer_seek(buffer *,unsigned int); + +#define buffer_PEEK(s) ( (s)->x + (s)->n ) +#define buffer_SEEK(s,len) ( ( (s)->p -= (len) ) , ( (s)->n += (len) ) ) + +#define buffer_GETC(s,c) \ + ( ((s)->p > 0) \ + ? ( *(c) = (s)->x[(s)->n], buffer_SEEK((s),1), 1 ) \ + : buffer_get((s),(c),1) \ + ) + +extern int buffer_copy(buffer *,buffer *); + +extern buffer *buffer_0; +extern buffer *buffer_0small; +extern buffer *buffer_1; +extern buffer *buffer_1small; +extern buffer *buffer_2; + +#endif diff --git a/iguana/databases/cdb-0.75/buffer_0.c b/iguana/databases/cdb-0.75/buffer_0.c new file mode 100644 index 000000000..f44914c88 --- /dev/null +++ b/iguana/databases/cdb-0.75/buffer_0.c @@ -0,0 +1,12 @@ +#include "readwrite.h" +#include "buffer.h" + +ssize_t buffer_0_read(int32_t fd,char *buf,int32_t len) +{ + if (buffer_flush(buffer_1) == -1) return -1; + return read(fd,buf,len); +} + +char buffer_0_space[BUFFER_INSIZE]; +static buffer it = BUFFER_INIT(buffer_0_read,0,buffer_0_space,sizeof buffer_0_space); +buffer *buffer_0 = ⁢ diff --git a/iguana/databases/cdb-0.75/buffer_1.c b/iguana/databases/cdb-0.75/buffer_1.c new file mode 100644 index 000000000..3104e22c6 --- /dev/null +++ b/iguana/databases/cdb-0.75/buffer_1.c @@ -0,0 +1,6 @@ +#include "readwrite.h" +#include "buffer.h" + +char buffer_1_space[BUFFER_OUTSIZE]; +static buffer it = BUFFER_INIT(write,1,buffer_1_space,sizeof buffer_1_space); +buffer *buffer_1 = ⁢ diff --git a/iguana/databases/cdb-0.75/buffer_1s.c b/iguana/databases/cdb-0.75/buffer_1s.c new file mode 100644 index 000000000..92f06216a --- /dev/null +++ b/iguana/databases/cdb-0.75/buffer_1s.c @@ -0,0 +1,6 @@ +#include "readwrite.h" +#include "buffer.h" + +char buffer_1small_space[256]; +static buffer it = BUFFER_INIT(write,1,buffer_1small_space,sizeof buffer_1small_space); +buffer *buffer_1small = ⁢ diff --git a/iguana/databases/cdb-0.75/buffer_2.c b/iguana/databases/cdb-0.75/buffer_2.c new file mode 100644 index 000000000..297825cd8 --- /dev/null +++ b/iguana/databases/cdb-0.75/buffer_2.c @@ -0,0 +1,6 @@ +#include "readwrite.h" +#include "buffer.h" + +char buffer_2_space[256]; +static buffer it = BUFFER_INIT(write,2,buffer_2_space,sizeof buffer_2_space); +buffer *buffer_2 = ⁢ diff --git a/iguana/databases/cdb-0.75/buffer_copy.c b/iguana/databases/cdb-0.75/buffer_copy.c new file mode 100644 index 000000000..dc4d4b172 --- /dev/null +++ b/iguana/databases/cdb-0.75/buffer_copy.c @@ -0,0 +1,16 @@ +#include "buffer.h" + +int buffer_copy(buffer *bout,buffer *bin) +{ + int n; + char *x; + + for (;;) { + n = buffer_feed(bin); + if (n < 0) return -2; + if (!n) return 0; + x = buffer_PEEK(bin); + if (buffer_put(bout,x,n) == -1) return -3; + buffer_SEEK(bin,n); + } +} diff --git a/iguana/databases/cdb-0.75/buffer_get.c b/iguana/databases/cdb-0.75/buffer_get.c new file mode 100644 index 000000000..0368b8a00 --- /dev/null +++ b/iguana/databases/cdb-0.75/buffer_get.c @@ -0,0 +1,67 @@ +#include "buffer.h" +#include "byte.h" +#include "error.h" + +static int oneread(ssize_t (*op)(),int fd,char *buf,unsigned int len) +{ + int32_t r; + + for (;;) { + r = (int32_t)op(fd,buf,len); + if (r == -1) if (errno == error_intr) continue; + return r; + } +} + +static int getthis(buffer *s,char *buf,unsigned int len) +{ + if (len > s->p) len = s->p; + s->p -= len; + byte_copy(buf,len,s->x + s->n); + s->n += len; + return len; +} + +int buffer_feed(buffer *s) +{ + int r; + + if (s->p) return s->p; + r = oneread(s->op,s->fd,s->x,s->n); + if (r <= 0) return r; + s->p = r; + s->n -= r; + if (s->n > 0) byte_copyr(s->x + s->n,r,s->x); + return r; +} + +int buffer_bget(buffer *s,char *buf,unsigned int len) +{ + int r; + + if (s->p > 0) return getthis(s,buf,len); + if (s->n <= len) return oneread(s->op,s->fd,buf,s->n); + r = buffer_feed(s); if (r <= 0) return r; + return getthis(s,buf,len); +} + +int buffer_get(buffer *s,char *buf,unsigned int len) +{ + int r; + + if (s->p > 0) return getthis(s,buf,len); + if (s->n <= len) return oneread(s->op,s->fd,buf,len); + r = buffer_feed(s); if (r <= 0) return r; + return getthis(s,buf,len); +} + +char *buffer_peek(buffer *s) +{ + return s->x + s->n; +} + +void buffer_seek(buffer *s,unsigned int len) +{ + s->n += len; + s->p -= len; +} diff --git a/iguana/databases/cdb-0.75/buffer_put.c b/iguana/databases/cdb-0.75/buffer_put.c new file mode 100644 index 000000000..4417212df --- /dev/null +++ b/iguana/databases/cdb-0.75/buffer_put.c @@ -0,0 +1,91 @@ +#include "buffer.h" +#include "str.h" +#include "byte.h" +#include "error.h" + +static int32_t allwrite(ssize_t (*op)(),int fd,char *buf,unsigned int len) +{ + int32_t w; + + while (len) + { + w = (int32_t)op(fd,buf,len); + if ( w == -1 ) + { + if ( errno == error_intr ) continue; + return -1; // note that some data may have been written + } + if ( w == 0 ) + ; // luser's fault + buf += w; + len -= w; + } + return 0; +} + +int buffer_flush(buffer *s) +{ + int p; + + p = s->p; + if (!p) return 0; + s->p = 0; + return allwrite(s->op,s->fd,s->x,p); +} + +int buffer_putalign(buffer *s,char *buf,unsigned int len) +{ + unsigned int n; + + while (len > (n = s->n - s->p)) { + byte_copy(s->x + s->p,n,buf); s->p += n; buf += n; len -= n; + if (buffer_flush(s) == -1) return -1; + } + /* now len <= s->n - s->p */ + byte_copy(s->x + s->p,len,buf); + s->p += len; + return 0; +} + +int buffer_put(buffer *s,char *buf,unsigned int len) +{ + unsigned int n; + + n = s->n; + if (len > n - s->p) { + if (buffer_flush(s) == -1) return -1; + /* now s->p == 0 */ + if (n < BUFFER_OUTSIZE) n = BUFFER_OUTSIZE; + while (len > s->n) { + if (n > len) n = len; + if (allwrite(s->op,s->fd,buf,n) == -1) return -1; + buf += n; + len -= n; + } + } + /* now len <= s->n - s->p */ + byte_copy(s->x + s->p,len,buf); + s->p += len; + return 0; +} + +int buffer_putflush(buffer *s,char *buf,unsigned int len) +{ + if (buffer_flush(s) == -1) return -1; + return allwrite(s->op,s->fd,buf,len); +} + +int buffer_putsalign(buffer *s,char *buf) +{ + return buffer_putalign(s,buf,str_len(buf)); +} + +int buffer_puts(buffer *s,char *buf) +{ + return buffer_put(s,buf,str_len(buf)); +} + +int buffer_putsflush(buffer *s,char *buf) +{ + return buffer_putflush(s,buf,str_len(buf)); +} diff --git a/iguana/databases/cdb-0.75/byte.h b/iguana/databases/cdb-0.75/byte.h new file mode 100644 index 000000000..de06c699d --- /dev/null +++ b/iguana/databases/cdb-0.75/byte.h @@ -0,0 +1,13 @@ +#ifndef BYTE_H +#define BYTE_H + +extern unsigned int byte_chr(); +extern unsigned int byte_rchr(); +extern void byte_copy(); +extern void byte_copyr(); +extern int byte_diff(); +extern void byte_zero(); + +#define byte_equal(s,n,t) (!byte_diff((s),(n),(t))) + +#endif diff --git a/iguana/databases/cdb-0.75/byte_copy.c b/iguana/databases/cdb-0.75/byte_copy.c new file mode 100644 index 000000000..eaad11b34 --- /dev/null +++ b/iguana/databases/cdb-0.75/byte_copy.c @@ -0,0 +1,14 @@ +#include "byte.h" + +void byte_copy(to,n,from) +register char *to; +register unsigned int n; +register char *from; +{ + for (;;) { + if (!n) return; *to++ = *from++; --n; + if (!n) return; *to++ = *from++; --n; + if (!n) return; *to++ = *from++; --n; + if (!n) return; *to++ = *from++; --n; + } +} diff --git a/iguana/databases/cdb-0.75/byte_cr.c b/iguana/databases/cdb-0.75/byte_cr.c new file mode 100644 index 000000000..3e7a1d544 --- /dev/null +++ b/iguana/databases/cdb-0.75/byte_cr.c @@ -0,0 +1,16 @@ +#include "byte.h" + +void byte_copyr(to,n,from) +register char *to; +register unsigned int n; +register char *from; +{ + to += n; + from += n; + for (;;) { + if (!n) return; *--to = *--from; --n; + if (!n) return; *--to = *--from; --n; + if (!n) return; *--to = *--from; --n; + if (!n) return; *--to = *--from; --n; + } +} diff --git a/iguana/databases/cdb-0.75/byte_diff.c b/iguana/databases/cdb-0.75/byte_diff.c new file mode 100644 index 000000000..cdbd76066 --- /dev/null +++ b/iguana/databases/cdb-0.75/byte_diff.c @@ -0,0 +1,16 @@ +#include "byte.h" + +int byte_diff(s,n,t) +register char *s; +register unsigned int n; +register char *t; +{ + for (;;) { + if (!n) return 0; if (*s != *t) break; ++s; ++t; --n; + if (!n) return 0; if (*s != *t) break; ++s; ++t; --n; + if (!n) return 0; if (*s != *t) break; ++s; ++t; --n; + if (!n) return 0; if (*s != *t) break; ++s; ++t; --n; + } + return ((int)(unsigned int)(unsigned char) *s) + - ((int)(unsigned int)(unsigned char) *t); +} diff --git a/iguana/databases/cdb-0.75/cdb.c b/iguana/databases/cdb-0.75/cdb.c new file mode 100644 index 000000000..86bc6ab8a --- /dev/null +++ b/iguana/databases/cdb-0.75/cdb.c @@ -0,0 +1,136 @@ +/* Public domain. */ +#include +#include +#include +#include +#include "readwrite.h" +#include "error.h" +#include "seek.h" +#include "byte.h" +#include "cdb.h" + +void cdb_free(struct cdb *c) +{ + if (c->map) { + munmap(c->map,c->size); + c->map = 0; + } +} + +void cdb_findstart(struct cdb *c) +{ + c->loop = 0; +} + +void cdb_init(struct cdb *c,int fd) +{ + struct stat st; + char *x; + + cdb_free(c); + cdb_findstart(c); + c->fd = fd; + + if (fstat(fd,&st) == 0) + if (st.st_size <= 0xffffffff) { + x = mmap(0,st.st_size,PROT_READ,MAP_SHARED,fd,0); + if (x + 1) { + c->size = (uint32_t)st.st_size; + c->map = x; + } + } +} + +int cdb_read(struct cdb *c,char *buf,unsigned int len,uint32 pos) +{ + if (c->map) { + if ((pos > c->size) || (c->size - pos < len)) goto FORMAT; + byte_copy(buf,len,c->map + pos); + } + else { + if (seek_set(c->fd,pos) == -1) return -1; + while (len > 0) { + int32_t r; + do + r = (int32_t)read(c->fd,buf,len); + while ((r == -1) && (errno == error_intr)); + if (r == -1) return -1; + if (r == 0) goto FORMAT; + buf += r; + len -= r; + } + } + return 0; + + FORMAT: + errno = error_proto; + return -1; +} + +static int match(struct cdb *c,char *key,unsigned int len,uint32 pos) +{ + char buf[32]; + int n; + + while (len > 0) { + n = sizeof buf; + if (n > len) n = len; + if (cdb_read(c,buf,n,pos) == -1) return -1; + if (byte_diff(buf,n,key)) return 0; + pos += n; + key += n; + len -= n; + } + return 1; +} + +int cdb_findnext(struct cdb *c,char *key,unsigned int len) +{ + char buf[8]; + uint32 pos; + uint32 u; + + if (!c->loop) { + u = cdb_hash(key,len); + if (cdb_read(c,buf,8,(u << 3) & 2047) == -1) return -1; + uint32_unpack(buf + 4,&c->hslots); + if (!c->hslots) return 0; + uint32_unpack(buf,&c->hpos); + c->khash = u; + u >>= 8; + u %= c->hslots; + u <<= 3; + c->kpos = c->hpos + u; + } + + while (c->loop < c->hslots) { + if (cdb_read(c,buf,8,c->kpos) == -1) return -1; + uint32_unpack(buf + 4,&pos); + if (!pos) return 0; + c->loop += 1; + c->kpos += 8; + if (c->kpos == c->hpos + (c->hslots << 3)) c->kpos = c->hpos; + uint32_unpack(buf,&u); + if (u == c->khash) { + if (cdb_read(c,buf,8,pos) == -1) return -1; + uint32_unpack(buf,&u); + if (u == len) + switch(match(c,key,len,pos + 8)) { + case -1: + return -1; + case 1: + uint32_unpack(buf + 4,&c->dlen); + c->dpos = pos + 8 + len; + return 1; + } + } + } + + return 0; +} + +int cdb_find(struct cdb *c,char *key,unsigned int len) +{ + cdb_findstart(c); + return cdb_findnext(c,key,len); +} diff --git a/iguana/databases/cdb-0.75/cdb.h b/iguana/databases/cdb-0.75/cdb.h new file mode 100644 index 000000000..ff998103f --- /dev/null +++ b/iguana/databases/cdb-0.75/cdb.h @@ -0,0 +1,37 @@ +/* Public domain. */ + +#ifndef CDB_H +#define CDB_H + +#include "uint32.h" + +#define CDB_HASHSTART 5381 +extern uint32 cdb_hashadd(uint32,unsigned char); +extern uint32 cdb_hash(char *,unsigned int); + +struct cdb { + char *map; /* 0 if no map is available */ + int fd; + uint32 size; /* initialized if map is nonzero */ + uint32 loop; /* number of hash slots searched under this key */ + uint32 khash; /* initialized if loop is nonzero */ + uint32 kpos; /* initialized if loop is nonzero */ + uint32 hpos; /* initialized if loop is nonzero */ + uint32 hslots; /* initialized if loop is nonzero */ + uint32 dpos; /* initialized if cdb_findnext() returns 1 */ + uint32 dlen; /* initialized if cdb_findnext() returns 1 */ +} ; + +extern void cdb_free(struct cdb *); +extern void cdb_init(struct cdb *,int fd); + +extern int cdb_read(struct cdb *,char *,unsigned int,uint32); + +extern void cdb_findstart(struct cdb *); +extern int cdb_findnext(struct cdb *,char *,unsigned int); +extern int cdb_find(struct cdb *,char *,unsigned int); + +#define cdb_datapos(c) ((c)->dpos) +#define cdb_datalen(c) ((c)->dlen) + +#endif diff --git a/iguana/databases/cdb-0.75/cdb_hash.c b/iguana/databases/cdb-0.75/cdb_hash.c new file mode 100644 index 000000000..d8e3cb8f2 --- /dev/null +++ b/iguana/databases/cdb-0.75/cdb_hash.c @@ -0,0 +1,21 @@ +/* Public domain. */ + +#include "cdb.h" + +uint32 cdb_hashadd(uint32 h,unsigned char c) +{ + h += (h << 5); + return h ^ c; +} + +uint32 cdb_hash(char *buf,unsigned int len) +{ + uint32 h; + + h = CDB_HASHSTART; + while (len) { + h = cdb_hashadd(h,*buf++); + --len; + } + return h; +} diff --git a/iguana/databases/cdb-0.75/cdb_make.c b/iguana/databases/cdb-0.75/cdb_make.c new file mode 100644 index 000000000..790c7bdac --- /dev/null +++ b/iguana/databases/cdb-0.75/cdb_make.c @@ -0,0 +1,156 @@ +/* Public domain. */ + +#include "readwrite.h" +#include "seek.h" +#include "error.h" +#include "alloc.h" +#include "cdb.h" +#include "str.h" +#include "open.h" +#include "cdb_make.h" + +int cdb_make_start(struct cdb_make *c,int fd) +{ + c->head = 0; + c->split = 0; + c->hash = 0; + c->numentries = 0; + c->fd = fd; + c->pos = sizeof c->final; + buffer_init(&c->b,write,fd,c->bspace,sizeof c->bspace); + return seek_set(fd,c->pos); +} + +static int posplus(struct cdb_make *c,uint32 len) +{ + uint32 newpos = c->pos + len; + if (newpos < len) { errno = error_nomem; return -1; } + c->pos = newpos; + return 0; +} + +int cdb_make_addend(struct cdb_make *c,unsigned int keylen,unsigned int datalen,uint32 h) +{ + struct cdb_hplist *head; + + head = c->head; + if (!head || (head->num >= CDB_HPLIST)) { + head = (struct cdb_hplist *) alloc(sizeof(struct cdb_hplist)); + if (!head) return -1; + head->num = 0; + head->next = c->head; + c->head = head; + } + head->hp[head->num].h = h; + head->hp[head->num].p = c->pos; + ++head->num; + ++c->numentries; + if (posplus(c,8) == -1) return -1; + if (posplus(c,keylen) == -1) return -1; + if (posplus(c,datalen) == -1) return -1; + return 0; +} + +int cdb_make_addbegin(struct cdb_make *c,unsigned int keylen,unsigned int datalen) +{ + char buf[8]; + + if (keylen > 0xffffffff) { errno = error_nomem; return -1; } + if (datalen > 0xffffffff) { errno = error_nomem; return -1; } + + uint32_pack(buf,keylen); + uint32_pack(buf + 4,datalen); + if (buffer_putalign(&c->b,buf,8) == -1) return -1; + return 0; +} + +int cdb_make_add(struct cdb_make *c,char *key,unsigned int keylen,char *data,unsigned int datalen) +{ + if (cdb_make_addbegin(c,keylen,datalen) == -1) return -1; + if (buffer_putalign(&c->b,key,keylen) == -1) return -1; + if (buffer_putalign(&c->b,data,datalen) == -1) return -1; + return cdb_make_addend(c,keylen,datalen,cdb_hash(key,keylen)); +} + +int cdb_make_finish(struct cdb_make *c) +{ + char buf[8]; + int i; + uint32 len; + uint32 u; + uint32 memsize; + uint32 count; + uint32 where; + struct cdb_hplist *x; + struct cdb_hp *hp; + + for (i = 0;i < 256;++i) + c->count[i] = 0; + + for (x = c->head;x;x = x->next) { + i = x->num; + while (i--) + ++c->count[255 & x->hp[i].h]; + } + + memsize = 1; + for (i = 0;i < 256;++i) { + u = c->count[i] * 2; + if (u > memsize) + memsize = u; + } + + memsize += c->numentries; /* no overflow possible up to now */ + u = (uint32) 0 - (uint32) 1; + u /= sizeof(struct cdb_hp); + if (memsize > u) { errno = error_nomem; return -1; } + + c->split = (struct cdb_hp *) alloc(memsize * sizeof(struct cdb_hp)); + if (!c->split) return -1; + + c->hash = c->split + c->numentries; + + u = 0; + for (i = 0;i < 256;++i) { + u += c->count[i]; /* bounded by numentries, so no overflow */ + c->start[i] = u; + } + + for (x = c->head;x;x = x->next) { + i = x->num; + while (i--) + c->split[--c->start[255 & x->hp[i].h]] = x->hp[i]; + } + + for (i = 0;i < 256;++i) { + count = c->count[i]; + + len = count + count; /* no overflow possible */ + uint32_pack(c->final + 8 * i,c->pos); + uint32_pack(c->final + 8 * i + 4,len); + + for (u = 0;u < len;++u) + c->hash[u].h = c->hash[u].p = 0; + + hp = c->split + c->start[i]; + for (u = 0;u < count;++u) { + where = (hp->h >> 8) % len; + while (c->hash[where].p) + if (++where == len) + where = 0; + c->hash[where] = *hp++; + } + + for (u = 0;u < len;++u) { + uint32_pack(buf,c->hash[u].h); + uint32_pack(buf + 4,c->hash[u].p); + if (buffer_putalign(&c->b,buf,8) == -1) return -1; + if (posplus(c,8) == -1) return -1; + } + } + + if (buffer_flush(&c->b) == -1) return -1; + if (seek_begin(c->fd) == -1) return -1; + return buffer_putflush(&c->b,c->final,sizeof c->final); +} + diff --git a/iguana/databases/cdb-0.75/cdb_make.h b/iguana/databases/cdb-0.75/cdb_make.h new file mode 100644 index 000000000..b8bbe4d0f --- /dev/null +++ b/iguana/databases/cdb-0.75/cdb_make.h @@ -0,0 +1,39 @@ +/* Public domain. */ + +#ifndef CDB_MAKE_H +#define CDB_MAKE_H + +#include "buffer.h" +#include "uint32.h" + +#define CDB_HPLIST 1000 + +struct cdb_hp { uint32 h; uint32 p; } ; + +struct cdb_hplist { + struct cdb_hp hp[CDB_HPLIST]; + struct cdb_hplist *next; + int num; +} ; + +struct cdb_make { + char bspace[8192]; + char final[2048]; + uint32 count[256]; + uint32 start[256]; + struct cdb_hplist *head; + struct cdb_hp *split; /* includes space for hash */ + struct cdb_hp *hash; + uint32 numentries; + buffer b; + uint32 pos; + int fd; +} ; + +extern int cdb_make_start(struct cdb_make *,int); +extern int cdb_make_addbegin(struct cdb_make *,unsigned int,unsigned int); +extern int cdb_make_addend(struct cdb_make *,unsigned int,unsigned int,uint32); +extern int cdb_make_add(struct cdb_make *,char *,unsigned int,char *,unsigned int); +extern int cdb_make_finish(struct cdb_make *); + +#endif diff --git a/iguana/databases/cdb-0.75/cdbdump b/iguana/databases/cdb-0.75/cdbdump new file mode 100755 index 000000000..e6a82ca2b Binary files /dev/null and b/iguana/databases/cdb-0.75/cdbdump differ diff --git a/iguana/databases/cdb-0.75/cdbdump.c b/iguana/databases/cdb-0.75/cdbdump.c new file mode 100644 index 000000000..75a4e413c --- /dev/null +++ b/iguana/databases/cdb-0.75/cdbdump.c @@ -0,0 +1,84 @@ +#include +#include "uint32.h" +#include "fmt.h" +#include "buffer.h" +#include "strerr.h" + +#define FATAL "cdbdump: fatal: " + +void die_write(void) +{ + strerr_die2sys(111,FATAL,"unable to write output: "); +} +void put(char *buf,unsigned int len) +{ + if (buffer_put(buffer_1,buf,len) == -1) die_write(); +} +void putflush(void) +{ + if (buffer_flush(buffer_1) == -1) die_write(); +} + +uint32 pos = 0; + +void get(char *buf,unsigned int len) +{ + int r; + while (len > 0) { + r = buffer_get(buffer_0,buf,len); + if (r == -1) + strerr_die2sys(111,FATAL,"unable to read input: "); + if (r == 0) + strerr_die2x(111,FATAL,"unable to read input: truncated file"); + pos += r; + buf += r; + len -= r; + } +} + +char buf[512]; + +void copy(uint32 len) +{ + unsigned int x; + + while (len) { + x = sizeof buf; + if (len < x) x = len; + get(buf,x); + put(buf,x); + len -= x; + } +} + +void getnum(uint32 *num) +{ + get(buf,4); + uint32_unpack(buf,num); +} + +char strnum[FMT_ULONG]; + +int main() +{ + uint32 eod; + uint32 klen; + uint32 dlen; + + getnum(&eod); + while (pos < 2048) getnum(&dlen); + + while (pos < eod) { + getnum(&klen); + getnum(&dlen); + put("+",1); put(strnum,fmt_ulong(strnum,klen)); + put(",",1); put(strnum,fmt_ulong(strnum,dlen)); + put(":",1); copy(klen); + put("->",2); copy(dlen); + put("\n",1); + } + + put("\n",1); + putflush(); + _exit(0); +} diff --git a/iguana/databases/cdb-0.75/cdbget b/iguana/databases/cdb-0.75/cdbget new file mode 100755 index 000000000..8acd7e906 Binary files /dev/null and b/iguana/databases/cdb-0.75/cdbget differ diff --git a/iguana/databases/cdb-0.75/cdbget.c b/iguana/databases/cdb-0.75/cdbget.c new file mode 100644 index 000000000..2823e8f98 --- /dev/null +++ b/iguana/databases/cdb-0.75/cdbget.c @@ -0,0 +1,69 @@ +#include + +#include "exit.h" +#include "scan.h" +#include "str.h" +#include "buffer.h" +#include "strerr.h" +#include "cdb.h" + +#define FATAL "cdbget: fatal: " + +void die_read(void) +{ + strerr_die2sys(111,FATAL,"unable to read input: "); +} +void die_write(void) +{ + strerr_die2sys(111,FATAL,"unable to write output: "); +} +void die_usage(void) +{ + strerr_die1x(111,"cdbget: usage: cdbget key [skip]"); +} + +static struct cdb c; +char buf[1024]; + +int32_t main(int argc,char **argv) +{ + char *key; + int r; + uint32 pos; + uint32 len; + unsigned long u = 0; + + if (!*argv) die_usage(); + + if (!*++argv) die_usage(); + key = *argv; + + if (*++argv) { + scan_ulong(*argv,&u); + } + + cdb_init(&c,0); + cdb_findstart(&c); + + for (;;) { + r = cdb_findnext(&c,key,str_len(key)); + if (r == -1) die_read(); + if (!r) _exit(100); + if (!u) break; + --u; + } + + pos = cdb_datapos(&c); + len = cdb_datalen(&c); + + while (len > 0) { + r = sizeof buf; + if (r > len) r = len; + if (cdb_read(&c,buf,r,pos) == -1) die_read(); + if (buffer_put(buffer_1small,buf,r) == -1) die_write(); + pos += r; + len -= r; + } + if (buffer_flush(buffer_1small) == -1) die_write(); + _exit(0); +} diff --git a/iguana/databases/cdb-0.75/cdbmake b/iguana/databases/cdb-0.75/cdbmake new file mode 100755 index 000000000..057beb007 Binary files /dev/null and b/iguana/databases/cdb-0.75/cdbmake differ diff --git a/iguana/databases/cdb-0.75/cdbmake-12 b/iguana/databases/cdb-0.75/cdbmake-12 new file mode 100755 index 000000000..1083a89a0 --- /dev/null +++ b/iguana/databases/cdb-0.75/cdbmake-12 @@ -0,0 +1,10 @@ +#!/bin/sh +# WARNING: This file was auto-generated. Do not edit! +awk ' + /^[^#]/ { + print "+" length($1) "," length($2) ":" $1 "->" $2 + } + END { + print "" + } +' | /usr/local/bin/cdbmake "$@" diff --git a/iguana/databases/cdb-0.75/cdbmake-12.sh b/iguana/databases/cdb-0.75/cdbmake-12.sh new file mode 100644 index 000000000..05df6987b --- /dev/null +++ b/iguana/databases/cdb-0.75/cdbmake-12.sh @@ -0,0 +1,8 @@ +awk ' + /^[^#]/ { + print "+" length($1) "," length($2) ":" $1 "->" $2 + } + END { + print "" + } +' | HOME/bin/cdbmake "$@" diff --git a/iguana/databases/cdb-0.75/cdbmake-sv b/iguana/databases/cdb-0.75/cdbmake-sv new file mode 100755 index 000000000..0c97e1603 --- /dev/null +++ b/iguana/databases/cdb-0.75/cdbmake-sv @@ -0,0 +1,24 @@ +#!/bin/sh +# WARNING: This file was auto-generated. Do not edit! +awk ' + { + if (split($0,x,"#")) { + f = split(x[1],y) + if (f >= 2) { + if (split(y[2],z,"/") >= 2) { + a = "@" z[1] "/" z[2] + print "+" length(a) "," length(y[1]) ":" a "->" y[1] + for (i = 1;i <= f;i += 1) { + if (i != 2) { + a = y[i] "/" z[2] + print "+" length(a) "," length(z[1]) ":" a "->" z[1] + } + } + } + } + } + } + END { + print "" + } +' | /usr/local/bin/cdbmake "$@" diff --git a/iguana/databases/cdb-0.75/cdbmake-sv.sh b/iguana/databases/cdb-0.75/cdbmake-sv.sh new file mode 100644 index 000000000..241d46c9e --- /dev/null +++ b/iguana/databases/cdb-0.75/cdbmake-sv.sh @@ -0,0 +1,22 @@ +awk ' + { + if (split($0,x,"#")) { + f = split(x[1],y) + if (f >= 2) { + if (split(y[2],z,"/") >= 2) { + a = "@" z[1] "/" z[2] + print "+" length(a) "," length(y[1]) ":" a "->" y[1] + for (i = 1;i <= f;i += 1) { + if (i != 2) { + a = y[i] "/" z[2] + print "+" length(a) "," length(z[1]) ":" a "->" z[1] + } + } + } + } + } + } + END { + print "" + } +' | HOME/bin/cdbmake "$@" diff --git a/iguana/databases/cdb-0.75/cdbmake.c b/iguana/databases/cdb-0.75/cdbmake.c new file mode 100644 index 000000000..69740000f --- /dev/null +++ b/iguana/databases/cdb-0.75/cdbmake.c @@ -0,0 +1,112 @@ +#include +#include +#include "error.h" +#include "open.h" +#include "strerr.h" +#include "cdb_make.h" +#include "cdb.h" + +#define FATAL "cdbmake: fatal: " + +char *fn; +char *fntmp; + +void die_usage(void) +{ + strerr_die1x(100,"cdbmake: usage: cdbmake f ftmp"); +} +void die_write(void) +{ + strerr_die4sys(111,FATAL,"unable to create ",fntmp,": "); +} +void die_read(void) +{ + strerr_die2sys(111,FATAL,"unable to read input: "); +} +void die_readformat(void) +{ + strerr_die2x(111,FATAL,"unable to read input: bad format"); +} + +inline void get(char *ch) +{ + switch(buffer_GETC(buffer_0,ch)) { + case 0: die_readformat(); + case -1: die_read(); + } +} + +static struct cdb_make c; + +int main(int argc,char **argv) +{ + unsigned int klen; + unsigned int dlen; + unsigned int i; + uint32 h; + int fd; + char ch; + + if (!*argv) die_usage(); + + if (!*++argv) die_usage(); + fn = *argv; + + if (!*++argv) die_usage(); + fntmp = *argv; + + fd = open_trunc(fntmp); + if (fd == -1) die_write(); + + if (cdb_make_start(&c,fd) == -1) die_write(); + + for (;;) { + get(&ch); + if (ch == '\n') break; + if (ch != '+') die_readformat(); + klen = 0; + for (;;) { + get(&ch); + if (ch == ',') break; + if ((ch < '0') || (ch > '9')) die_readformat(); + if (klen > 429496720) { errno = error_nomem; die_write(); } + klen = klen * 10 + (ch - '0'); + } + dlen = 0; + for (;;) { + get(&ch); + if (ch == ':') break; + if ((ch < '0') || (ch > '9')) die_readformat(); + if (dlen > 429496720) { errno = error_nomem; die_write(); } + dlen = dlen * 10 + (ch - '0'); + } + + if (cdb_make_addbegin(&c,klen,dlen) == -1) die_write(); + h = CDB_HASHSTART; + for (i = 0;i < klen;++i) { + get(&ch); + if (buffer_PUTC(&c.b,ch) == -1) die_write(); + h = cdb_hashadd(h,ch); + } + get(&ch); + if (ch != '-') die_readformat(); + get(&ch); + if (ch != '>') die_readformat(); + for (i = 0;i < dlen;++i) { + get(&ch); + if (buffer_PUTC(&c.b,ch) == -1) die_write(); + } + if (cdb_make_addend(&c,klen,dlen,h) == -1) die_write(); + + get(&ch); + if (ch != '\n') die_readformat(); + } + + if (cdb_make_finish(&c) == -1) die_write(); + if (fsync(fd) == -1) die_write(); + if (close(fd) == -1) die_write(); /* NFS silliness */ + if (rename(fntmp,fn) == -1) + strerr_die6sys(111,FATAL,"unable to rename ",fntmp," to ",fn,": "); + + _exit(0); +} diff --git a/iguana/databases/cdb-0.75/cdbstats b/iguana/databases/cdb-0.75/cdbstats new file mode 100755 index 000000000..69eae8521 Binary files /dev/null and b/iguana/databases/cdb-0.75/cdbstats differ diff --git a/iguana/databases/cdb-0.75/cdbstats.c b/iguana/databases/cdb-0.75/cdbstats.c new file mode 100644 index 000000000..6d3588da0 --- /dev/null +++ b/iguana/databases/cdb-0.75/cdbstats.c @@ -0,0 +1,127 @@ +#include +#include "uint32.h" +#include "fmt.h" +#include "buffer.h" +#include "strerr.h" +#include "seek.h" +#include "cdb.h" +#include "str.h" + +#define FATAL "cdbstats: fatal: " + +void die_read(void) +{ + strerr_die2sys(111,FATAL,"unable to read input: "); +} +void die_readformat(void) +{ + strerr_die2x(111,FATAL,"unable to read input: truncated file"); +} +void die_write(void) +{ + strerr_die2sys(111,FATAL,"unable to write output: "); +} +void put(char *buf,unsigned int len) +{ + if (buffer_put(buffer_1small,buf,len) == -1) die_write(); +} +void putflush(void) +{ + if (buffer_flush(buffer_1small) == -1) die_write(); +} + +uint32 pos = 0; + +void get(char *buf,unsigned int len) +{ + int r; + while (len > 0) { + r = buffer_get(buffer_0,buf,len); + if (r == -1) die_read(); + if (r == 0) die_readformat(); + pos += r; + buf += r; + len -= r; + } +} + +void getnum(uint32 *num) +{ + char buf[4]; + get(buf,4); + uint32_unpack(buf,num); +} + +char strnum[FMT_ULONG]; + +void putnum(char *label,unsigned long count) +{ + unsigned int i; + put(label,str_len(label)); + for (i = fmt_ulong(0,count);i < 10;++i) put(" ",1); + put(strnum,fmt_ulong(strnum,count)); + put("\n",1); +} + +char key[1024]; + +static struct cdb c; + +static unsigned long numrecords; +static unsigned long numd[11]; + +int main() +{ + uint32 eod; + uint32 klen; + uint32 dlen; + seek_pos rest; + int r; + + cdb_init(&c,0); + + getnum(&eod); + while (pos < 2048) getnum(&dlen); + + while (pos < eod) { + getnum(&klen); + getnum(&dlen); + if (klen > sizeof key) { + while (klen) { get(key,1); --klen; } + } + else { + get(key,klen); + rest = seek_cur(0); + cdb_findstart(&c); + do { + switch(cdb_findnext(&c,key,klen)) { + case -1: die_read(); + case 0: die_readformat(); + } + } while (cdb_datapos(&c) != pos); + if (!c.loop) die_readformat(); + ++numrecords; + if (c.loop > 10) + ++numd[10]; + else + ++numd[c.loop - 1]; + if (seek_set(0,rest) == -1) die_read(); + } + while (dlen) { get(key,1); --dlen; } + } + + putnum("records ",numrecords); + putnum("d0 ",numd[0]); + putnum("d1 ",numd[1]); + putnum("d2 ",numd[2]); + putnum("d3 ",numd[3]); + putnum("d4 ",numd[4]); + putnum("d5 ",numd[5]); + putnum("d6 ",numd[6]); + putnum("d7 ",numd[7]); + putnum("d8 ",numd[8]); + putnum("d9 ",numd[9]); + putnum(">9 ",numd[10]); + putflush(); + _exit(0); +} diff --git a/iguana/databases/cdb-0.75/cdbtest b/iguana/databases/cdb-0.75/cdbtest new file mode 100755 index 000000000..45f4c33b0 Binary files /dev/null and b/iguana/databases/cdb-0.75/cdbtest differ diff --git a/iguana/databases/cdb-0.75/cdbtest.c b/iguana/databases/cdb-0.75/cdbtest.c new file mode 100644 index 000000000..68eeabc24 --- /dev/null +++ b/iguana/databases/cdb-0.75/cdbtest.c @@ -0,0 +1,122 @@ +#include + +#include "uint32.h" +#include "str.h" +#include "fmt.h" +#include "buffer.h" +#include "strerr.h" +#include "seek.h" +#include "cdb.h" + +#define FATAL "cdbtest: fatal: " + +void die_read(void) +{ + strerr_die2sys(111,FATAL,"unable to read input: "); +} +void die_write(void) +{ + strerr_die2sys(111,FATAL,"unable to write output: "); +} +void put(char *buf,unsigned int len) +{ + if (buffer_put(buffer_1small,buf,len) == -1) die_write(); +} +void putflush(void) +{ + if (buffer_flush(buffer_1small) == -1) die_write(); +} + +uint32 pos = 0; + +void get(char *buf,unsigned int len) +{ + int r; + while (len > 0) { + r = buffer_get(buffer_0,buf,len); + if (r == -1) die_read(); + if (r == 0) + strerr_die2x(111,FATAL,"unable to read input: truncated file"); + pos += r; + buf += r; + len -= r; + } +} + +void getnum(uint32 *num) +{ + char buf[4]; + get(buf,4); + uint32_unpack(buf,num); +} + +char strnum[FMT_ULONG]; + +void putnum(char *label,unsigned long count) +{ + put(label,str_len(label)); + put(strnum,fmt_ulong(strnum,count)); + put("\n",1); +} + +char key[1024]; + +unsigned long numuntested = 0; +unsigned long numnotfound = 0; +unsigned long numotherpos = 0; +unsigned long numbadlen = 0; +unsigned long numfound = 0; + +static struct cdb c; + +int main() +{ + uint32 eod; + uint32 klen; + uint32 dlen; + seek_pos rest; + int r; + + cdb_init(&c,0); + + getnum(&eod); + while (pos < 2048) getnum(&dlen); + + while (pos < eod) { + getnum(&klen); + getnum(&dlen); + if (klen > sizeof key) { + ++numuntested; + while (klen) { get(key,1); --klen; } + } + else { + get(key,klen); + rest = seek_cur(0); + switch(cdb_find(&c,key,klen)) { + case -1: + die_read(); + case 0: + ++numnotfound; + break; + default: + if (cdb_datapos(&c) != pos) + ++numotherpos; + else + if (cdb_datalen(&c) != dlen) + ++numbadlen; + else + ++numfound; + } + if (seek_set(0,rest) == -1) die_read(); + } + while (dlen) { get(key,1); --dlen; } + } + + putnum("found: ",numfound); + putnum("different record: ",numotherpos); + putnum("bad length: ",numbadlen); + putnum("not found: ",numnotfound); + putnum("untested: ",numuntested); + putflush(); + _exit(0); +} diff --git a/iguana/databases/cdb-0.75/choose.sh b/iguana/databases/cdb-0.75/choose.sh new file mode 100644 index 000000000..feff2dac6 --- /dev/null +++ b/iguana/databases/cdb-0.75/choose.sh @@ -0,0 +1,18 @@ + +result="$4" + +case "$1" in + *c*) ./compile $2.c >/dev/null 2>&1 || result="$3" ;; +esac + +case "$1" in + *l*) ./load $2 >/dev/null 2>&1 || result="$3" ;; +esac + +case "$1" in + *r*) ./$2 >/dev/null 2>&1 || result="$3" ;; +esac + +rm -f $2.o $2 + +exec cat "$result" diff --git a/iguana/databases/cdb-0.75/compile b/iguana/databases/cdb-0.75/compile new file mode 100755 index 000000000..0d3fa38d8 --- /dev/null +++ b/iguana/databases/cdb-0.75/compile @@ -0,0 +1,3 @@ +#!/bin/sh +# WARNING: This file was auto-generated. Do not edit! +exec gcc -O2 -c ${1+"$@"} diff --git a/iguana/databases/cdb-0.75/conf-cc b/iguana/databases/cdb-0.75/conf-cc new file mode 100644 index 000000000..7f41e187e --- /dev/null +++ b/iguana/databases/cdb-0.75/conf-cc @@ -0,0 +1,3 @@ +gcc -O2 + +This will be used to compile .c files. diff --git a/iguana/databases/cdb-0.75/conf-home b/iguana/databases/cdb-0.75/conf-home new file mode 100644 index 000000000..2e468c797 --- /dev/null +++ b/iguana/databases/cdb-0.75/conf-home @@ -0,0 +1,3 @@ +/usr/local + +This is the cdb home directory. Programs will be installed in .../bin. diff --git a/iguana/databases/cdb-0.75/conf-ld b/iguana/databases/cdb-0.75/conf-ld new file mode 100644 index 000000000..1d0518a96 --- /dev/null +++ b/iguana/databases/cdb-0.75/conf-ld @@ -0,0 +1,3 @@ +gcc + +This will be used to link .o files into an executable. diff --git a/iguana/databases/cdb-0.75/error.c b/iguana/databases/cdb-0.75/error.c new file mode 100644 index 000000000..e1ab13ca0 --- /dev/null +++ b/iguana/databases/cdb-0.75/error.c @@ -0,0 +1,109 @@ +#include +#include "error.h" + +/* warning: as coverage improves here, should update error_{str,temp} */ + +int error_intr = +#ifdef EINTR +EINTR; +#else +-1; +#endif + +int error_nomem = +#ifdef ENOMEM +ENOMEM; +#else +-2; +#endif + +int error_noent = +#ifdef ENOENT +ENOENT; +#else +-3; +#endif + +int error_txtbsy = +#ifdef ETXTBSY +ETXTBSY; +#else +-4; +#endif + +int error_io = +#ifdef EIO +EIO; +#else +-5; +#endif + +int error_exist = +#ifdef EEXIST +EEXIST; +#else +-6; +#endif + +int error_timeout = +#ifdef ETIMEDOUT +ETIMEDOUT; +#else +-7; +#endif + +int error_inprogress = +#ifdef EINPROGRESS +EINPROGRESS; +#else +-8; +#endif + +int error_wouldblock = +#ifdef EWOULDBLOCK +EWOULDBLOCK; +#else +-9; +#endif + +int error_again = +#ifdef EAGAIN +EAGAIN; +#else +-10; +#endif + +int error_pipe = +#ifdef EPIPE +EPIPE; +#else +-11; +#endif + +int error_perm = +#ifdef EPERM +EPERM; +#else +-12; +#endif + +int error_acces = +#ifdef EACCES +EACCES; +#else +-13; +#endif + +int error_nodevice = +#ifdef ENXIO +ENXIO; +#else +-14; +#endif + +int error_proto = +#ifdef EPROTO +EPROTO; +#else +-15; +#endif diff --git a/iguana/databases/cdb-0.75/error.h b/iguana/databases/cdb-0.75/error.h new file mode 100644 index 000000000..e3cc2ae36 --- /dev/null +++ b/iguana/databases/cdb-0.75/error.h @@ -0,0 +1,25 @@ +#ifndef ERROR_H +#define ERROR_H + +extern int errno; + +extern int error_intr; +extern int error_nomem; +extern int error_noent; +extern int error_txtbsy; +extern int error_io; +extern int error_exist; +extern int error_timeout; +extern int error_inprogress; +extern int error_wouldblock; +extern int error_again; +extern int error_pipe; +extern int error_perm; +extern int error_acces; +extern int error_nodevice; +extern int error_proto; + +extern char *error_str(int); +extern int error_temp(int); + +#endif diff --git a/iguana/databases/cdb-0.75/error_str.c b/iguana/databases/cdb-0.75/error_str.c new file mode 100644 index 000000000..92255ecb7 --- /dev/null +++ b/iguana/databases/cdb-0.75/error_str.c @@ -0,0 +1,271 @@ +#include +#include "error.h" + +#define X(e,s) if (i == e) return s; + +char *error_str(int i) +{ + X(0,"no error") + X(error_intr,"interrupted system call") + X(error_nomem,"out of memory") + X(error_noent,"file does not exist") + X(error_txtbsy,"text busy") + X(error_io,"input/output error") + X(error_exist,"file already exists") + X(error_timeout,"timed out") + X(error_inprogress,"operation in progress") + X(error_again,"temporary failure") + X(error_wouldblock,"input/output would block") + X(error_pipe,"broken pipe") + X(error_perm,"permission denied") + X(error_acces,"access denied") + X(error_nodevice,"device not configured") + X(error_proto,"protocol error") +#ifdef ESRCH + X(ESRCH,"no such process") +#endif +#ifdef E2BIG + X(E2BIG,"argument list too long") +#endif +#ifdef ENOEXEC + X(ENOEXEC,"exec format error") +#endif +#ifdef EBADF + X(EBADF,"file descriptor not open") +#endif +#ifdef ECHILD + X(ECHILD,"no child processes") +#endif +#ifdef EDEADLK + X(EDEADLK,"operation would cause deadlock") +#endif +#ifdef EFAULT + X(EFAULT,"bad address") +#endif +#ifdef ENOTBLK + X(ENOTBLK,"not a block device") +#endif +#ifdef EBUSY + X(EBUSY,"device busy") +#endif +#ifdef EXDEV + X(EXDEV,"cross-device link") +#endif +#ifdef ENODEV + X(ENODEV,"device does not support operation") +#endif +#ifdef ENOTDIR + X(ENOTDIR,"not a directory") +#endif +#ifdef EISDIR + X(EISDIR,"is a directory") +#endif +#ifdef EINVAL + X(EINVAL,"invalid argument") +#endif +#ifdef ENFILE + X(ENFILE,"system cannot open more files") +#endif +#ifdef EMFILE + X(EMFILE,"process cannot open more files") +#endif +#ifdef ENOTTY + X(ENOTTY,"not a tty") +#endif +#ifdef EFBIG + X(EFBIG,"file too big") +#endif +#ifdef ENOSPC + X(ENOSPC,"out of disk space") +#endif +#ifdef ESPIPE + X(ESPIPE,"unseekable descriptor") +#endif +#ifdef EROFS + X(EROFS,"read-only file system") +#endif +#ifdef EMLINK + X(EMLINK,"too many links") +#endif +#ifdef EDOM + X(EDOM,"input out of range") +#endif +#ifdef ERANGE + X(ERANGE,"output out of range") +#endif +#ifdef EALREADY + X(EALREADY,"operation already in progress") +#endif +#ifdef ENOTSOCK + X(ENOTSOCK,"not a socket") +#endif +#ifdef EDESTADDRREQ + X(EDESTADDRREQ,"destination address required") +#endif +#ifdef EMSGSIZE + X(EMSGSIZE,"message too long") +#endif +#ifdef EPROTOTYPE + X(EPROTOTYPE,"incorrect protocol type") +#endif +#ifdef ENOPROTOOPT + X(ENOPROTOOPT,"protocol not available") +#endif +#ifdef EPROTONOSUPPORT + X(EPROTONOSUPPORT,"protocol not supported") +#endif +#ifdef ESOCKTNOSUPPORT + X(ESOCKTNOSUPPORT,"socket type not supported") +#endif +#ifdef EOPNOTSUPP + X(EOPNOTSUPP,"operation not supported") +#endif +#ifdef EPFNOSUPPORT + X(EPFNOSUPPORT,"protocol family not supported") +#endif +#ifdef EAFNOSUPPORT + X(EAFNOSUPPORT,"address family not supported") +#endif +#ifdef EADDRINUSE + X(EADDRINUSE,"address already used") +#endif +#ifdef EADDRNOTAVAIL + X(EADDRNOTAVAIL,"address not available") +#endif +#ifdef ENETDOWN + X(ENETDOWN,"network down") +#endif +#ifdef ENETUNREACH + X(ENETUNREACH,"network unreachable") +#endif +#ifdef ENETRESET + X(ENETRESET,"network reset") +#endif +#ifdef ECONNABORTED + X(ECONNABORTED,"connection aborted") +#endif +#ifdef ECONNRESET + X(ECONNRESET,"connection reset") +#endif +#ifdef ENOBUFS + X(ENOBUFS,"out of buffer space") +#endif +#ifdef EISCONN + X(EISCONN,"already connected") +#endif +#ifdef ENOTCONN + X(ENOTCONN,"not connected") +#endif +#ifdef ESHUTDOWN + X(ESHUTDOWN,"socket shut down") +#endif +#ifdef ETOOMANYREFS + X(ETOOMANYREFS,"too many references") +#endif +#ifdef ECONNREFUSED + X(ECONNREFUSED,"connection refused") +#endif +#ifdef ELOOP + X(ELOOP,"symbolic link loop") +#endif +#ifdef ENAMETOOLONG + X(ENAMETOOLONG,"file name too long") +#endif +#ifdef EHOSTDOWN + X(EHOSTDOWN,"host down") +#endif +#ifdef EHOSTUNREACH + X(EHOSTUNREACH,"host unreachable") +#endif +#ifdef ENOTEMPTY + X(ENOTEMPTY,"directory not empty") +#endif +#ifdef EPROCLIM + X(EPROCLIM,"too many processes") +#endif +#ifdef EUSERS + X(EUSERS,"too many users") +#endif +#ifdef EDQUOT + X(EDQUOT,"disk quota exceeded") +#endif +#ifdef ESTALE + X(ESTALE,"stale NFS file handle") +#endif +#ifdef EREMOTE + X(EREMOTE,"too many levels of remote in path") +#endif +#ifdef EBADRPC + X(EBADRPC,"RPC structure is bad") +#endif +#ifdef ERPCMISMATCH + X(ERPCMISMATCH,"RPC version mismatch") +#endif +#ifdef EPROGUNAVAIL + X(EPROGUNAVAIL,"RPC program unavailable") +#endif +#ifdef EPROGMISMATCH + X(EPROGMISMATCH,"program version mismatch") +#endif +#ifdef EPROCUNAVAIL + X(EPROCUNAVAIL,"bad procedure for program") +#endif +#ifdef ENOLCK + X(ENOLCK,"no locks available") +#endif +#ifdef ENOSYS + X(ENOSYS,"system call not available") +#endif +#ifdef EFTYPE + X(EFTYPE,"bad file type") +#endif +#ifdef EAUTH + X(EAUTH,"authentication error") +#endif +#ifdef ENEEDAUTH + X(ENEEDAUTH,"not authenticated") +#endif +#ifdef ENOSTR + X(ENOSTR,"not a stream device") +#endif +#ifdef ETIME + X(ETIME,"timer expired") +#endif +#ifdef ENOSR + X(ENOSR,"out of stream resources") +#endif +#ifdef ENOMSG + X(ENOMSG,"no message of desired type") +#endif +#ifdef EBADMSG + X(EBADMSG,"bad message type") +#endif +#ifdef EIDRM + X(EIDRM,"identifier removed") +#endif +#ifdef ENONET + X(ENONET,"machine not on network") +#endif +#ifdef ERREMOTE + X(ERREMOTE,"object not local") +#endif +#ifdef ENOLINK + X(ENOLINK,"link severed") +#endif +#ifdef EADV + X(EADV,"advertise error") +#endif +#ifdef ESRMNT + X(ESRMNT,"srmount error") +#endif +#ifdef ECOMM + X(ECOMM,"communication error") +#endif +#ifdef EMULTIHOP + X(EMULTIHOP,"multihop attempted") +#endif +#ifdef EREMCHG + X(EREMCHG,"remote address changed") +#endif + return "unknown error"; +} diff --git a/iguana/databases/cdb-0.75/exit.h b/iguana/databases/cdb-0.75/exit.h new file mode 100644 index 000000000..39011c88d --- /dev/null +++ b/iguana/databases/cdb-0.75/exit.h @@ -0,0 +1,6 @@ +#ifndef EXIT_H +#define EXIT_H + +extern void _exit(); + +#endif diff --git a/iguana/databases/cdb-0.75/find-systype.sh b/iguana/databases/cdb-0.75/find-systype.sh new file mode 100644 index 000000000..0955c32fa --- /dev/null +++ b/iguana/databases/cdb-0.75/find-systype.sh @@ -0,0 +1,159 @@ +# oper-:arch-:syst-:chip-:kern- +# oper = operating system type; e.g., sunos-4.1.4 +# arch = machine language; e.g., sparc +# syst = which binaries can run; e.g., sun4 +# chip = chip model; e.g., micro-2-80 +# kern = kernel version; e.g., sun4m +# dependence: arch --- chip +# \ \ +# oper --- syst --- kern +# so, for example, syst is interpreted in light of oper, but chip is not. +# anyway, no slashes, no extra colons, no uppercase letters. +# the point of the extra -'s is to ease parsing: can add hierarchies later. +# e.g., *:i386-*:*:pentium-*:* would handle pentium-100 as well as pentium, +# and i386-486 (486s do have more instructions, you know) as well as i386. +# the idea here is to include ALL useful available information. + +exec 2>/dev/null + +sys="`uname -s | tr '/:[A-Z]' '..[a-z]'`" +if [ x"$sys" != x ] +then + unamer="`uname -r | tr /: ..`" + unamem="`uname -m | tr /: ..`" + unamev="`uname -v | tr /: ..`" + + case "$sys" in + bsd.os) + # in bsd 4.4, uname -v does not have useful info. + # in bsd 4.4, uname -m is arch, not chip. + oper="$sys-$unamer" + arch="$unamem" + syst="" + chip="`sysctl -n hw.model`" + kern="" + ;; + freebsd) + # see above about bsd 4.4 + oper="$sys-$unamer" + arch="$unamem" + syst="" + chip="`sysctl -n hw.model`" # hopefully + kern="" + ;; + netbsd) + # see above about bsd 4.4 + oper="$sys-$unamer" + arch="$unamem" + syst="" + chip="`sysctl -n hw.model`" # hopefully + kern="" + ;; + linux) + # as in bsd 4.4, uname -v does not have useful info. + oper="$sys-$unamer" + syst="" + chip="$unamem" + kern="" + case "$chip" in + i386|i486|i586|i686) + arch="i386" + ;; + alpha) + arch="alpha" + ;; + esac + ;; + aix) + # naturally IBM has to get uname -r and uname -v backwards. dorks. + oper="$sys-$unamev-$unamer" + arch="`arch | tr /: ..`" + syst="" + chip="$unamem" + kern="" + ;; + sunos) + oper="$sys-$unamer-$unamev" + arch="`(uname -p || mach) | tr /: ..`" + syst="`arch | tr /: ..`" + chip="$unamem" # this is wrong; is there any way to get the real info? + kern="`arch -k | tr /: ..`" + ;; + unix_sv) + oper="$sys-$unamer-$unamev" + arch="`uname -m`" + syst="" + chip="$unamem" + kern="" + ;; + *) + oper="$sys-$unamer-$unamev" + arch="`arch | tr /: ..`" + syst="" + chip="$unamem" + kern="" + ;; + esac +else + $CC -c trycpp.c + $LD -o trycpp trycpp.o + case `./trycpp` in + nextstep) + oper="nextstep-`hostinfo | sed -n 's/^[ ]*NeXT Mach \([^:]*\):.*$/\1/p'`" + arch="`hostinfo | sed -n 's/^Processor type: \(.*\) (.*)$/\1/p' | tr /: ..`" + syst="" + chip="`hostinfo | sed -n 's/^Processor type: .* (\(.*\))$/\1/p' | tr ' /:' '...'`" + kern="" + ;; + *) + oper="unknown" + arch="" + syst="" + chip="" + kern="" + ;; + esac + rm -f trycpp.o trycpp +fi + +case "$chip" in +80486) + # let's try to be consistent here. (BSD/OS) + chip=i486 + ;; +i486DX) + # respect the hyphen hierarchy. (FreeBSD) + chip=i486-dx + ;; +i486.DX2) + # respect the hyphen hierarchy. (FreeBSD) + chip=i486-dx2 + ;; +Intel.586) + # no, you nitwits, there is no such chip. (NeXTStep) + chip=pentium + ;; +i586) + # no, you nitwits, there is no such chip. (Linux) + chip=pentium + ;; +i686) + # STOP SAYING THAT! (Linux) + chip=ppro +esac + +if $CC -c x86cpuid.c +then + if $LD -o x86cpuid x86cpuid.o + then + x86cpuid="`./x86cpuid | tr /: ..`" + case "$x86cpuid" in + ?*) + chip="$x86cpuid" + ;; + esac + fi +fi +rm -f x86cpuid x86cpuid.o + +echo "$oper-:$arch-:$syst-:$chip-:$kern-" | tr ' [A-Z]' '.[a-z]' diff --git a/iguana/databases/cdb-0.75/fmt.h b/iguana/databases/cdb-0.75/fmt.h new file mode 100644 index 000000000..6fd8fef72 --- /dev/null +++ b/iguana/databases/cdb-0.75/fmt.h @@ -0,0 +1,25 @@ +#ifndef FMT_H +#define FMT_H + +#define FMT_ULONG 40 /* enough space to hold 2^128 - 1 in decimal, plus \0 */ +#define FMT_LEN ((char *) 0) /* convenient abbreviation */ + +extern unsigned int fmt_uint(char *,unsigned int); +extern unsigned int fmt_uint0(char *,unsigned int,unsigned int); +extern unsigned int fmt_xint(char *,unsigned int); +extern unsigned int fmt_nbbint(char *,unsigned int,unsigned int,unsigned int,unsigned int); +extern unsigned int fmt_ushort(char *,unsigned short); +extern unsigned int fmt_xshort(char *,unsigned short); +extern unsigned int fmt_nbbshort(char *,unsigned int,unsigned int,unsigned int,unsigned short); +extern unsigned int fmt_ulong(char *,unsigned long); +extern unsigned int fmt_xlong(char *,unsigned long); +extern unsigned int fmt_nbblong(char *,unsigned int,unsigned int,unsigned int,unsigned long); + +extern unsigned int fmt_plusminus(char *,int); +extern unsigned int fmt_minus(char *,int); +extern unsigned int fmt_0x(char *,int); + +extern unsigned int fmt_str(char *,char *); +extern unsigned int fmt_strn(char *,char *,unsigned int); + +#endif diff --git a/iguana/databases/cdb-0.75/fmt_ulong.c b/iguana/databases/cdb-0.75/fmt_ulong.c new file mode 100644 index 000000000..db48bfde5 --- /dev/null +++ b/iguana/databases/cdb-0.75/fmt_ulong.c @@ -0,0 +1,13 @@ +#include "fmt.h" + +unsigned int fmt_ulong(register char *s,register unsigned long u) +{ + register unsigned int len; register unsigned long q; + len = 1; q = u; + while (q > 9) { ++len; q /= 10; } + if (s) { + s += len; + do { *--s = '0' + (u % 10); u /= 10; } while(u); /* handles u == 0 */ + } + return len; +} diff --git a/iguana/databases/cdb-0.75/hier.c b/iguana/databases/cdb-0.75/hier.c new file mode 100644 index 000000000..acb9ab210 --- /dev/null +++ b/iguana/databases/cdb-0.75/hier.c @@ -0,0 +1,98 @@ +#include +#include +#include "auto_home.h" +#include "strerr.h" +#include "error.h" +#include "open.h" +#include "readwrite.h" +#include "exit.h" +#include "buffer.h" +#define FATAL "install: fatal: " + +static void h(char *home,int uid,int gid,int mode) +{ + if (mkdir(home,0700) == -1) + if (errno != error_exist) + strerr_die4sys(111,FATAL,"unable to mkdir ",home,": "); + if (chown(home,uid,gid) == -1) + strerr_die4sys(111,FATAL,"unable to chown ",home,": "); + if (chmod(home,mode) == -1) + strerr_die4sys(111,FATAL,"unable to chmod ",home,": "); +} + +static void d(char *home,char *subdir,int uid,int gid,int mode) +{ + if (chdir(home) == -1) + strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); + if (mkdir(subdir,0700) == -1) + if (errno != error_exist) + strerr_die6sys(111,FATAL,"unable to mkdir ",home,"/",subdir,": "); + if (chown(subdir,uid,gid) == -1) + strerr_die6sys(111,FATAL,"unable to chown ",home,"/",subdir,": "); + if (chmod(subdir,mode) == -1) + strerr_die6sys(111,FATAL,"unable to chmod ",home,"/",subdir,": "); +} + +static char inbuf[BUFFER_INSIZE]; +static char outbuf[BUFFER_OUTSIZE]; +static buffer ssin; +static buffer ssout; +int fdsourcedir = -1; + +static void c(char *home,char *subdir,char *file,int uid,int gid,int mode) +{ + int fdin; + int fdout; + + if (fchdir(fdsourcedir) == -1) + strerr_die2sys(111,FATAL,"unable to switch back to source directory: "); + + fdin = open_read(file); + if (fdin == -1) + strerr_die4sys(111,FATAL,"unable to read ",file,": "); + buffer_init(&ssin,read,fdin,inbuf,sizeof inbuf); + + if (chdir(home) == -1) + strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); + if (chdir(subdir) == -1) + strerr_die6sys(111,FATAL,"unable to switch to ",home,"/",subdir,": "); + + fdout = open_trunc(file); + if (fdout == -1) + strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); + buffer_init(&ssout,write,fdout,outbuf,sizeof outbuf); + + switch(buffer_copy(&ssout,&ssin)) { + case -2: + strerr_die4sys(111,FATAL,"unable to read ",file,": "); + case -3: + strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); + } + + close(fdin); + if (buffer_flush(&ssout) == -1) + strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); + if (fsync(fdout) == -1) + strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); + if (close(fdout) == -1) /* NFS silliness */ + strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); + + if (chown(file,uid,gid) == -1) + strerr_die6sys(111,FATAL,"unable to chown .../",subdir,"/",file,": "); + if (chmod(file,mode) == -1) + strerr_die6sys(111,FATAL,"unable to chmod .../",subdir,"/",file,": "); +} + +void hier() +{ + h(auto_home,-1,-1,02755); + d(auto_home,"bin",-1,-1,02755); + + c(auto_home,"bin","cdbget",-1,-1,0755); + c(auto_home,"bin","cdbmake",-1,-1,0755); + c(auto_home,"bin","cdbdump",-1,-1,0755); + c(auto_home,"bin","cdbstats",-1,-1,0755); + c(auto_home,"bin","cdbtest",-1,-1,0755); + c(auto_home,"bin","cdbmake-12",-1,-1,0755); + c(auto_home,"bin","cdbmake-sv",-1,-1,0755); +} diff --git a/iguana/databases/cdb-0.75/install b/iguana/databases/cdb-0.75/install new file mode 100755 index 000000000..920b308c5 Binary files /dev/null and b/iguana/databases/cdb-0.75/install differ diff --git a/iguana/databases/cdb-0.75/install.c b/iguana/databases/cdb-0.75/install.c new file mode 100644 index 000000000..fe0cbd097 --- /dev/null +++ b/iguana/databases/cdb-0.75/install.c @@ -0,0 +1,65 @@ +#include +#include +#include "buffer.h" +#include "strerr.h" +#include "error.h" +#include "open.h" +#include "readwrite.h" +#include "exit.h" + +extern void hier(); + +#define FATAL "install: fatal: " + +extern int fdsourcedir; +static buffer ssout; +static char outbuf[BUFFER_OUTSIZE]; + +void z(home,subdir,file,len,uid,gid,mode) +char *home; +char *subdir; +char *file; +int len; +int uid; +int gid; +int mode; +{ + int fdout; + + if (chdir(home) == -1) + strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); + if (chdir(subdir) == -1) + strerr_die6sys(111,FATAL,"unable to switch to ",home,"/",subdir,": "); + + fdout = open_trunc(file); + if (fdout == -1) + strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); + buffer_init(&ssout,write,fdout,outbuf,sizeof outbuf); + + while (len-- > 0) + if (buffer_put(&ssout,"",1) == -1) + strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); + + if (buffer_flush(&ssout) == -1) + strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); + if (fsync(fdout) == -1) + strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); + if (close(fdout) == -1) /* NFS silliness */ + strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); + + if (chown(file,uid,gid) == -1) + strerr_die6sys(111,FATAL,"unable to chown .../",subdir,"/",file,": "); + if (chmod(file,mode) == -1) + strerr_die6sys(111,FATAL,"unable to chmod .../",subdir,"/",file,": "); +} + +int32_t main() +{ + fdsourcedir = open_read("."); + if (fdsourcedir == -1) + strerr_die2sys(111,FATAL,"unable to open current directory: "); + + umask(077); + hier(); + _exit(0); +} diff --git a/iguana/databases/cdb-0.75/instcheck b/iguana/databases/cdb-0.75/instcheck new file mode 100755 index 000000000..093984b77 Binary files /dev/null and b/iguana/databases/cdb-0.75/instcheck differ diff --git a/iguana/databases/cdb-0.75/instcheck.c b/iguana/databases/cdb-0.75/instcheck.c new file mode 100644 index 000000000..b77ed1012 --- /dev/null +++ b/iguana/databases/cdb-0.75/instcheck.c @@ -0,0 +1,109 @@ +#include +#include +#include +#include "strerr.h" +#include "error.h" +#include "readwrite.h" +#include "exit.h" + +extern void hier(); + +#define FATAL "instcheck: fatal: " +#define WARNING "instcheck: warning: " + +void perm(prefix1,prefix2,prefix3,file,type,uid,gid,mode) +char *prefix1; +char *prefix2; +char *prefix3; +char *file; +int type; +int uid; +int gid; +int mode; +{ + struct stat st; + + if (stat(file,&st) == -1) { + if (errno == error_noent) + strerr_warn6(WARNING,prefix1,prefix2,prefix3,file," does not exist",0); + else + strerr_warn4(WARNING,"unable to stat .../",file,": ",&strerr_sys); + return; + } + + if ((uid != -1) && (st.st_uid != uid)) + strerr_warn6(WARNING,prefix1,prefix2,prefix3,file," has wrong owner",0); + if ((gid != -1) && (st.st_gid != gid)) + strerr_warn6(WARNING,prefix1,prefix2,prefix3,file," has wrong group",0); + if ((st.st_mode & 07777) != mode) + strerr_warn6(WARNING,prefix1,prefix2,prefix3,file," has wrong permissions",0); + if ((st.st_mode & S_IFMT) != type) + strerr_warn6(WARNING,prefix1,prefix2,prefix3,file," has wrong type",0); +} + +void h(home,uid,gid,mode) +char *home; +int uid; +int gid; +int mode; +{ + perm("","","",home,S_IFDIR,uid,gid,mode); +} + +void d(home,subdir,uid,gid,mode) +char *home; +char *subdir; +int uid; +int gid; +int mode; +{ + if (chdir(home) == -1) + strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); + perm("",home,"/",subdir,S_IFDIR,uid,gid,mode); +} + +void p(home,fifo,uid,gid,mode) +char *home; +char *fifo; +int uid; +int gid; +int mode; +{ + if (chdir(home) == -1) + strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); + perm("",home,"/",fifo,S_IFIFO,uid,gid,mode); +} + +void c(home,subdir,file,uid,gid,mode) +char *home; +char *subdir; +char *file; +int uid; +int gid; +int mode; +{ + if (chdir(home) == -1) + strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); + if (chdir(subdir) == -1) + strerr_die6sys(111,FATAL,"unable to switch to ",home,"/",subdir,": "); + perm(".../",subdir,"/",file,S_IFREG,uid,gid,mode); +} + +void z(home,file,len,uid,gid,mode) +char *home; +char *file; +int len; +int uid; +int gid; +int mode; +{ + if (chdir(home) == -1) + strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); + perm("",home,"/",file,S_IFREG,uid,gid,mode); +} + +int32_t main() +{ + hier(); + _exit(0); +} diff --git a/iguana/databases/cdb-0.75/load b/iguana/databases/cdb-0.75/load new file mode 100755 index 000000000..0cbeba18d --- /dev/null +++ b/iguana/databases/cdb-0.75/load @@ -0,0 +1,4 @@ +#!/bin/sh +# WARNING: This file was auto-generated. Do not edit! +main="$1"; shift +exec gcc -o "$main" "$main".o ${1+"$@"} diff --git a/iguana/databases/cdb-0.75/makelib b/iguana/databases/cdb-0.75/makelib new file mode 100755 index 000000000..f94bcf3cc --- /dev/null +++ b/iguana/databases/cdb-0.75/makelib @@ -0,0 +1,6 @@ +#!/bin/sh +# WARNING: This file was auto-generated. Do not edit! +main="$1"; shift +rm -f "$main" +ar cr "$main" ${1+"$@"} +ranlib "$main" diff --git a/iguana/databases/cdb-0.75/open.h b/iguana/databases/cdb-0.75/open.h new file mode 100644 index 000000000..2963fa70c --- /dev/null +++ b/iguana/databases/cdb-0.75/open.h @@ -0,0 +1,10 @@ +#ifndef OPEN_H +#define OPEN_H + +extern int open_read(char *); +extern int open_excl(char *); +extern int open_append(char *); +extern int open_trunc(char *); +extern int open_write(char *); + +#endif diff --git a/iguana/databases/cdb-0.75/open_read.c b/iguana/databases/cdb-0.75/open_read.c new file mode 100644 index 000000000..7f5ec8b95 --- /dev/null +++ b/iguana/databases/cdb-0.75/open_read.c @@ -0,0 +1,6 @@ +#include +#include +#include "open.h" + +int open_read(char *fn) +{ return open(fn,O_RDONLY | O_NDELAY); } diff --git a/iguana/databases/cdb-0.75/open_trunc.c b/iguana/databases/cdb-0.75/open_trunc.c new file mode 100644 index 000000000..77b99ef1f --- /dev/null +++ b/iguana/databases/cdb-0.75/open_trunc.c @@ -0,0 +1,6 @@ +#include +#include +#include "open.h" + +int open_trunc(char *fn) +{ return open(fn,O_WRONLY | O_NDELAY | O_TRUNC | O_CREAT,0644); } diff --git a/iguana/databases/cdb-0.75/random.cdb b/iguana/databases/cdb-0.75/random.cdb new file mode 100644 index 000000000..81e3e111c Binary files /dev/null and b/iguana/databases/cdb-0.75/random.cdb differ diff --git a/iguana/databases/cdb-0.75/readwrite.h b/iguana/databases/cdb-0.75/readwrite.h new file mode 100644 index 000000000..52ac1c713 --- /dev/null +++ b/iguana/databases/cdb-0.75/readwrite.h @@ -0,0 +1,8 @@ +#ifndef READWRITE_H +#define READWRITE_H +#include + +ssize_t read(int, void *, size_t); +ssize_t write(int, const void *, size_t); + +#endif diff --git a/iguana/databases/cdb-0.75/rts b/iguana/databases/cdb-0.75/rts new file mode 100755 index 000000000..176f21ec7 --- /dev/null +++ b/iguana/databases/cdb-0.75/rts @@ -0,0 +1,3 @@ +#!/bin/sh +# WARNING: This file was auto-generated. Do not edit! +env - PATH="`pwd`:$PATH" sh rts.tests 2>&1 | cat -v diff --git a/iguana/databases/cdb-0.75/rts.exp b/iguana/databases/cdb-0.75/rts.exp new file mode 100644 index 000000000..835c0b919 --- /dev/null +++ b/iguana/databases/cdb-0.75/rts.exp @@ -0,0 +1,251 @@ +--- cdbmake handles simple example +0 +--- cdbmake-12 handles simple example +0 +--- cdbmake-sv handles simple example +0 +--- cdbdump handles simple examples ++3,5:one->Hello ++3,7:two->Goodbye + +0 ++3,5:one->Hello ++3,7:two->Goodbye + +0 ++6,4:@7/tcp->echo ++8,1:echo/tcp->7 ++6,4:@7/udp->echo ++8,1:echo/udp->7 ++6,7:@9/tcp->discard ++11,1:discard/tcp->9 ++8,1:sink/tcp->9 ++8,1:null/tcp->9 ++6,7:@9/udp->discard ++11,1:discard/udp->9 ++8,1:sink/udp->9 ++8,1:null/udp->9 ++7,6:@11/tcp->systat ++10,2:systat/tcp->11 ++9,2:users/tcp->11 ++7,6:@11/udp->systat ++10,2:systat/udp->11 ++9,2:users/udp->11 + +0 +--- cdbtest handles simple examples +found: 2 +different record: 0 +bad length: 0 +not found: 0 +untested: 0 +0 +found: 2 +different record: 0 +bad length: 0 +not found: 0 +untested: 0 +0 +found: 18 +different record: 0 +bad length: 0 +not found: 0 +untested: 0 +0 +--- cdbstats handles simple examples +records 2 +d0 2 +d1 0 +d2 0 +d3 0 +d4 0 +d5 0 +d6 0 +d7 0 +d8 0 +d9 0 +>9 0 +0 +records 2 +d0 2 +d1 0 +d2 0 +d3 0 +d4 0 +d5 0 +d6 0 +d7 0 +d8 0 +d9 0 +>9 0 +0 +records 18 +d0 18 +d1 0 +d2 0 +d3 0 +d4 0 +d5 0 +d6 0 +d7 0 +d8 0 +d9 0 +>9 0 +0 +--- cdbget retrieves data successfully +Hello +0 +Goodbye +0 +echo +0 +echo +0 +7 +0 +7 +0 +discard +0 +discard +0 +9 +0 +9 +0 +9 +0 +9 +0 +9 +0 +9 +0 +systat +0 +systat +0 +11 +0 +11 +0 +11 +0 +11 +0 +--- cdbget exits 100 on nonexistent data +100 +100 +--- cdbmake handles repeated keys +0 ++3,5:one->Hello ++3,7:one->Goodbye ++3,7:one->Another + +0 +--- cdbget handles repeated keys +Hello +0 +Hello +0 +Goodbye +0 +Another +0 + +100 + +100 +--- cdbmake handles long keys and data +0 +--- cdbdump handles long keys and data ++320,320:ba483b3442e75cace82def4b5df25bfca887b41687537c21dc4b82cb4c36315e2f6a0661d1af2e05e686c4c595c16561d8c1b3fbee8a6b99c54b3d10d61948445298e97e971f85a600c88164d6b0b09 +b5169a54910232db0a56938de61256721667bddc1c0a2b14f5d063ab586a87a957e87f704acb7246c5e8c25becef713a365efef79bb1f406fecee88f3261f68e239c5903e3145961eb0fbc538ff506a +->152e113d5deec3638ead782b93e1b9666d265feb5aebc840e79aa69e2cfc1a2ce4b3254b79fa73c338d22a75e67cfed4cd17b92c405e204a48f21c31cdcf7da46312dc80debfbdaf6dc39d74694a711 +6d170c5fde1a81806847cf71732c7f3217a38c6234235951af7b7c1d32e62d480d7c82a63a9d94291d92767ed97dd6a6809d1eb856ce23eda20268cb53fda31c016a19fc20e80aec3bd594a3eb82a5a + + +0 +--- cdbtest handles long keys and data +found: 1 +different record: 0 +bad length: 0 +not found: 0 +untested: 0 +0 +--- cdbstats handles long keys and data +records 1 +d0 1 +d1 0 +d2 0 +d3 0 +d4 0 +d5 0 +d6 0 +d7 0 +d8 0 +d9 0 +>9 0 +0 +--- cdbget handles long keys and data +152e113d5deec3638ead782b93e1b9666d265feb5aebc840e79aa69e2cfc1a2ce4b3254b79fa73c338d22a75e67cfed4cd17b92c405e204a48f21c31cdcf7da46312dc80debfbdaf6dc39d74694a711 +6d170c5fde1a81806847cf71732c7f3217a38c6234235951af7b7c1d32e62d480d7c82a63a9d94291d92767ed97dd6a6809d1eb856ce23eda20268cb53fda31c016a19fc20e80aec3bd594a3eb82a5a + +0 +--- cdbmake handles unwritable tmp +cdbmake: fatal: unable to create loop: symbolic link loop +111 +--- cdbmake handles unmovable cdb +cdbmake: fatal: unable to rename test.tmp to loop/test.cdb: symbolic link loop +111 +--- cdbmake handles nomem +cdbmake: fatal: unable to create test.tmp: out of memory +111 +--- cdbmake handles full disk +cdbmake: fatal: unable to create test.tmp: file too big +111 +--- cdbmake handles absurd klen +cdbmake: fatal: unable to create test.tmp: out of memory +111 +--- cdbget handles empty file +cdbget: fatal: unable to read input: protocol error +111 +--- cdbdump and cdbmake handle random.cdb +0 +--- cdbtest handles random.cdb +found: 100 +different record: 0 +bad length: 0 +not found: 0 +untested: 0 +0 +--- cdbstats handles random.cdb +records 100 +d0 96 +d1 4 +d2 0 +d3 0 +d4 0 +d5 0 +d6 0 +d7 0 +d8 0 +d9 0 +>9 0 +0 +--- testzero works +0 +found: 5 +different record: 0 +bad length: 0 +not found: 0 +untested: 0 +0 +--- testzero can build a database very close to 4GB +0 +--- testzero complains if hash table passes 4GB +testzero: fatal: unable to write: out of memory +111 +--- testzero complains if records pass 4GB +testzero: fatal: unable to write: out of memory +111 diff --git a/iguana/databases/cdb-0.75/rts.sh b/iguana/databases/cdb-0.75/rts.sh new file mode 100644 index 000000000..c71e839f0 --- /dev/null +++ b/iguana/databases/cdb-0.75/rts.sh @@ -0,0 +1 @@ +env - PATH="`pwd`:$PATH" sh rts.tests 2>&1 | cat -v diff --git a/iguana/databases/cdb-0.75/rts.tests b/iguana/databases/cdb-0.75/rts.tests new file mode 100644 index 000000000..dae4ff602 --- /dev/null +++ b/iguana/databases/cdb-0.75/rts.tests @@ -0,0 +1,210 @@ +# Requirements: +# You have softlimit in your path. +# XFSZ is signal 25. +# +# Some features not tested here: +# cdbmake traps 4GB overflows. + + +umask 022 + +rm -rf rts-tmp +mkdir rts-tmp +cd rts-tmp + + +echo '--- cdbmake handles simple example' +echo '+3,5:one->Hello ++3,7:two->Goodbye +' | cdbmake test.cdb test.tmp +echo $? + +echo '--- cdbmake-12 handles simple example' +echo ' + one Hello +# comment line + two Goodbye +' | cdbmake-12 12.cdb 12.tmp +echo $? + +echo '--- cdbmake-sv handles simple example' +echo ' +# Network services, Internet style +echo 7/tcp +echo 7/udp +discard 9/tcp sink null +discard 9/udp sink null +systat 11/tcp users #Active Users +systat 11/udp users #Active Users +' | cdbmake-sv sv.cdb sv.tmp +echo $? + +echo '--- cdbdump handles simple examples' +cdbdump < test.cdb +echo $? +cdbdump < 12.cdb +echo $? +cdbdump < sv.cdb +echo $? + +echo '--- cdbtest handles simple examples' +cdbtest < test.cdb +echo $? +cdbtest < 12.cdb +echo $? +cdbtest < sv.cdb +echo $? + +echo '--- cdbstats handles simple examples' +cdbstats < test.cdb +echo $? +cdbstats < 12.cdb +echo $? +cdbstats < sv.cdb +echo $? + +echo '--- cdbget retrieves data successfully' +cdbget one < test.cdb +echo ' +'$? +cdbget two < test.cdb +echo ' +'$? +for i in @7 echo @9 discard sink null @11 systat users +do + cdbget $i/tcp < sv.cdb + echo ' +'$? + cdbget $i/udp < sv.cdb + echo ' +'$? +done + +echo '--- cdbget exits 100 on nonexistent data' +cdbget three < test.cdb +echo $? +cdbget '#Active' < sv.cdb +echo $? + + +echo '--- cdbmake handles repeated keys' +echo '+3,5:one->Hello ++3,7:one->Goodbye ++3,7:one->Another +' | cdbmake rep.cdb rep.tmp +echo $? +cdbdump < rep.cdb +echo $? + +echo '--- cdbget handles repeated keys' +cdbget one < rep.cdb +echo ' +'$? +cdbget one 0 < rep.cdb +echo ' +'$? +cdbget one 1 < rep.cdb +echo ' +'$? +cdbget one 2 < rep.cdb +echo ' +'$? +cdbget one 3 < rep.cdb +echo ' +'$? +cdbget one 4 < rep.cdb +echo ' +'$? + +echo '--- cdbmake handles long keys and data' +echo '+320,320:ba483b3442e75cace82def4b5df25bfca887b41687537c21dc4b82cb4c36315e2f6a0661d1af2e05e686c4c595c16561d8c1b3fbee8a6b99c54b3d10d61948445298e97e971f85a600c88164d6b0b09 +b5169a54910232db0a56938de61256721667bddc1c0a2b14f5d063ab586a87a957e87f704acb7246c5e8c25becef713a365efef79bb1f406fecee88f3261f68e239c5903e3145961eb0fbc538ff506a +->152e113d5deec3638ead782b93e1b9666d265feb5aebc840e79aa69e2cfc1a2ce4b3254b79fa73c338d22a75e67cfed4cd17b92c405e204a48f21c31cdcf7da46312dc80debfbdaf6dc39d74694a711 +6d170c5fde1a81806847cf71732c7f3217a38c6234235951af7b7c1d32e62d480d7c82a63a9d94291d92767ed97dd6a6809d1eb856ce23eda20268cb53fda31c016a19fc20e80aec3bd594a3eb82a5a + +' | cdbmake test.cdb test.tmp +echo $? + +echo '--- cdbdump handles long keys and data' +cdbdump < test.cdb +echo $? + +echo '--- cdbtest handles long keys and data' +cdbtest < test.cdb +echo $? + +echo '--- cdbstats handles long keys and data' +cdbstats < test.cdb +echo $? + +echo '--- cdbget handles long keys and data' +cdbget 'ba483b3442e75cace82def4b5df25bfca887b41687537c21dc4b82cb4c36315e2f6a0661d1af2e05e686c4c595c16561d8c1b3fbee8a6b99c54b3d10d61948445298e97e971f85a600c88164d6b0b09 +b5169a54910232db0a56938de61256721667bddc1c0a2b14f5d063ab586a87a957e87f704acb7246c5e8c25becef713a365efef79bb1f406fecee88f3261f68e239c5903e3145961eb0fbc538ff506a +' < test.cdb +echo ' +'$? + +echo '--- cdbmake handles unwritable tmp' +ln -s loop loop +echo '' | cdbmake test.cdb loop +echo $? + +echo '--- cdbmake handles unmovable cdb' +echo '' | cdbmake loop/test.cdb test.tmp +echo $? + +echo '--- cdbmake handles nomem' +csh -cf 'repeat 5000 echo "+3,5:one->Hello"' \ +| softlimit -d 50000 cdbmake test.cdb test.tmp +echo $? + +echo '--- cdbmake handles full disk' +( + trap '' 25 + echo '' | softlimit -f 2047 cdbmake test.cdb test.tmp + echo $? +) + +echo '--- cdbmake handles absurd klen' +echo '+4294967210' | cdbmake test.cdb test.tmp +echo $? + +echo '--- cdbget handles empty file' +cdbget foo test.cdb +echo $? +cdbtest < test.cdb +echo $? + +echo '--- testzero can build a database very close to 4GB' +testzero 65507 > /dev/null +echo $? + +echo '--- testzero complains if hash table passes 4GB' +testzero 65508 > /dev/null +echo $? + +echo '--- testzero complains if records pass 4GB' +testzero 66000 > /dev/null +echo $? + + +exit 0 diff --git a/iguana/databases/cdb-0.75/scan.h b/iguana/databases/cdb-0.75/scan.h new file mode 100644 index 000000000..758138c61 --- /dev/null +++ b/iguana/databases/cdb-0.75/scan.h @@ -0,0 +1,28 @@ +#ifndef SCAN_H +#define SCAN_H + +extern unsigned int scan_uint(char *,unsigned int *); +extern unsigned int scan_xint(char *,unsigned int *); +extern unsigned int scan_nbbint(char *,unsigned int,unsigned int,unsigned int,unsigned int *); +extern unsigned int scan_ushort(char *,unsigned short *); +extern unsigned int scan_xshort(char *,unsigned short *); +extern unsigned int scan_nbbshort(char *,unsigned int,unsigned int,unsigned int,unsigned short *); +extern unsigned int scan_ulong(char *,unsigned long *); +extern unsigned int scan_xlong(char *,unsigned long *); +extern unsigned int scan_nbblong(char *,unsigned int,unsigned int,unsigned int,unsigned long *); + +extern unsigned int scan_plusminus(char *,int *); +extern unsigned int scan_0x(char *,unsigned int *); + +extern unsigned int scan_whitenskip(char *,unsigned int); +extern unsigned int scan_nonwhitenskip(char *,unsigned int); +extern unsigned int scan_charsetnskip(char *,char *,unsigned int); +extern unsigned int scan_noncharsetnskip(char *,char *,unsigned int); + +extern unsigned int scan_strncmp(char *,char *,unsigned int); +extern unsigned int scan_memcmp(char *,char *,unsigned int); + +extern unsigned int scan_long(char *,long *); +extern unsigned int scan_8long(char *,unsigned long *); + +#endif diff --git a/iguana/databases/cdb-0.75/scan_ulong.c b/iguana/databases/cdb-0.75/scan_ulong.c new file mode 100644 index 000000000..c4f03c0aa --- /dev/null +++ b/iguana/databases/cdb-0.75/scan_ulong.c @@ -0,0 +1,11 @@ +#include "scan.h" + +unsigned int scan_ulong(register char *s,register unsigned long *u) +{ + register unsigned int pos; register unsigned long result; + register unsigned long c; + pos = 0; result = 0; + while ((c = (unsigned long) (unsigned char) (s[pos] - '0')) < 10) + { result = result * 10 + c; ++pos; } + *u = result; return pos; +} diff --git a/iguana/databases/cdb-0.75/seek.h b/iguana/databases/cdb-0.75/seek.h new file mode 100644 index 000000000..3c80dcaf2 --- /dev/null +++ b/iguana/databases/cdb-0.75/seek.h @@ -0,0 +1,17 @@ +#ifndef SEEK_H +#define SEEK_H + +off_t lseek(int, off_t, int); + +typedef unsigned long seek_pos; + +extern seek_pos seek_cur(int); + +extern int seek_set(int,seek_pos); +extern int seek_end(int); + +extern int seek_trunc(int,seek_pos); + +#define seek_begin(fd) (seek_set((fd),(seek_pos) 0)) + +#endif diff --git a/iguana/databases/cdb-0.75/seek_cur.c b/iguana/databases/cdb-0.75/seek_cur.c new file mode 100644 index 000000000..c2950a1ae --- /dev/null +++ b/iguana/databases/cdb-0.75/seek_cur.c @@ -0,0 +1,7 @@ +#include +#include "seek.h" + +#define CUR 1 /* sigh */ + +seek_pos seek_cur(int fd) +{ return lseek(fd,(off_t) 0,CUR); } diff --git a/iguana/databases/cdb-0.75/seek_set.c b/iguana/databases/cdb-0.75/seek_set.c new file mode 100644 index 000000000..d08d4f38b --- /dev/null +++ b/iguana/databases/cdb-0.75/seek_set.c @@ -0,0 +1,7 @@ +#include +#include "seek.h" + +#define SET 0 /* sigh */ + +int seek_set(int fd,seek_pos pos) +{ if (lseek(fd,(off_t) pos,SET) == -1) return -1; return 0; } diff --git a/iguana/databases/cdb-0.75/str.h b/iguana/databases/cdb-0.75/str.h new file mode 100644 index 000000000..fa71514c1 --- /dev/null +++ b/iguana/databases/cdb-0.75/str.h @@ -0,0 +1,15 @@ +#ifndef STR_H +#define STR_H +#include + +extern unsigned int str_copy(char *,char *); +extern int str_diff(char *,char *); +extern int str_diffn(char *,char *,unsigned int); +extern unsigned int str_len(char *); +extern unsigned int str_chr(char *,int); +extern unsigned int str_rchr(char *,int); +extern int str_start(char *,char *); + +#define str_equal(s,t) (!str_diff((s),(t))) + +#endif diff --git a/iguana/databases/cdb-0.75/str_len.c b/iguana/databases/cdb-0.75/str_len.c new file mode 100644 index 000000000..df2453949 --- /dev/null +++ b/iguana/databases/cdb-0.75/str_len.c @@ -0,0 +1,14 @@ +#include "str.h" + +uint32_t str_len(char *s) +{ + register char *t; + + t = s; + for (;;) { + if (!*t) return (uint32_t)(t - s); ++t; + if (!*t) return (uint32_t)(t - s); ++t; + if (!*t) return (uint32_t)(t - s); ++t; + if (!*t) return (uint32_t)(t - s); ++t; + } +} diff --git a/iguana/databases/cdb-0.75/strerr.h b/iguana/databases/cdb-0.75/strerr.h new file mode 100644 index 000000000..702f58895 --- /dev/null +++ b/iguana/databases/cdb-0.75/strerr.h @@ -0,0 +1,78 @@ +#ifndef STRERR_H +#define STRERR_H + +struct strerr { + struct strerr *who; + char *x; + char *y; + char *z; +} ; + +extern struct strerr strerr_sys; +extern void strerr_sysinit(void); + +extern char *strerr(struct strerr *); +extern void strerr_warn(char *,char *,char *,char *,char *,char *,struct strerr *); +extern void strerr_die(int,char *,char *,char *,char *,char *,char *,struct strerr *); + +#define STRERR(r,se,a) \ +{ se.who = 0; se.x = a; se.y = 0; se.z = 0; return r; } + +#define STRERR_SYS(r,se,a) \ +{ se.who = &strerr_sys; se.x = a; se.y = 0; se.z = 0; return r; } +#define STRERR_SYS3(r,se,a,b,c) \ +{ se.who = &strerr_sys; se.x = a; se.y = b; se.z = c; return r; } + +#define strerr_warn6(x1,x2,x3,x4,x5,x6,se) \ +strerr_warn((x1),(x2),(x3),(x4),(x5),(x6),(se)) +#define strerr_warn5(x1,x2,x3,x4,x5,se) \ +strerr_warn((x1),(x2),(x3),(x4),(x5),0,(se)) +#define strerr_warn4(x1,x2,x3,x4,se) \ +strerr_warn((x1),(x2),(x3),(x4),0,0,(se)) +#define strerr_warn3(x1,x2,x3,se) \ +strerr_warn((x1),(x2),(x3),0,0,0,(se)) +#define strerr_warn2(x1,x2,se) \ +strerr_warn((x1),(x2),0,0,0,0,(se)) +#define strerr_warn1(x1,se) \ +strerr_warn((x1),0,0,0,0,0,(se)) + +#define strerr_die6(e,x1,x2,x3,x4,x5,x6,se) \ +strerr_die((e),(x1),(x2),(x3),(x4),(x5),(x6),(se)) +#define strerr_die5(e,x1,x2,x3,x4,x5,se) \ +strerr_die((e),(x1),(x2),(x3),(x4),(x5),0,(se)) +#define strerr_die4(e,x1,x2,x3,x4,se) \ +strerr_die((e),(x1),(x2),(x3),(x4),0,0,(se)) +#define strerr_die3(e,x1,x2,x3,se) \ +strerr_die((e),(x1),(x2),(x3),0,0,0,(se)) +#define strerr_die2(e,x1,x2,se) \ +strerr_die((e),(x1),(x2),0,0,0,0,(se)) +#define strerr_die1(e,x1,se) \ +strerr_die((e),(x1),0,0,0,0,0,(se)) + +#define strerr_die6sys(e,x1,x2,x3,x4,x5,x6) \ +strerr_die((e),(x1),(x2),(x3),(x4),(x5),(x6),&strerr_sys) +#define strerr_die5sys(e,x1,x2,x3,x4,x5) \ +strerr_die((e),(x1),(x2),(x3),(x4),(x5),0,&strerr_sys) +#define strerr_die4sys(e,x1,x2,x3,x4) \ +strerr_die((e),(x1),(x2),(x3),(x4),0,0,&strerr_sys) +#define strerr_die3sys(e,x1,x2,x3) \ +strerr_die((e),(x1),(x2),(x3),0,0,0,&strerr_sys) +#define strerr_die2sys(e,x1,x2) \ +strerr_die((e),(x1),(x2),0,0,0,0,&strerr_sys) +#define strerr_die1sys(e,x1) \ +strerr_die((e),(x1),0,0,0,0,0,&strerr_sys) + +#define strerr_die6x(e,x1,x2,x3,x4,x5,x6) \ +strerr_die((e),(x1),(x2),(x3),(x4),(x5),(x6),0) +#define strerr_die5x(e,x1,x2,x3,x4,x5) \ +strerr_die((e),(x1),(x2),(x3),(x4),(x5),0,0) +#define strerr_die4x(e,x1,x2,x3,x4) \ +strerr_die((e),(x1),(x2),(x3),(x4),0,0,0) +#define strerr_die3x(e,x1,x2,x3) \ +strerr_die((e),(x1),(x2),(x3),0,0,0,0) +#define strerr_die2x(e,x1,x2) \ +strerr_die((e),(x1),(x2),0,0,0,0,0) +#define strerr_die1x(e,x1) \ +strerr_die((e),(x1),0,0,0,0,0,0) + +#endif diff --git a/iguana/databases/cdb-0.75/strerr_die.c b/iguana/databases/cdb-0.75/strerr_die.c new file mode 100644 index 000000000..850028b37 --- /dev/null +++ b/iguana/databases/cdb-0.75/strerr_die.c @@ -0,0 +1,31 @@ +#include "buffer.h" +#include "exit.h" +#include "strerr.h" + +void strerr_warn(char *x1,char *x2,char *x3,char *x4,char *x5,char *x6,struct strerr *se) +{ + strerr_sysinit(); + + if (x1) buffer_puts(buffer_2,x1); + if (x2) buffer_puts(buffer_2,x2); + if (x3) buffer_puts(buffer_2,x3); + if (x4) buffer_puts(buffer_2,x4); + if (x5) buffer_puts(buffer_2,x5); + if (x6) buffer_puts(buffer_2,x6); + + while(se) { + if (se->x) buffer_puts(buffer_2,se->x); + if (se->y) buffer_puts(buffer_2,se->y); + if (se->z) buffer_puts(buffer_2,se->z); + se = se->who; + } + + buffer_puts(buffer_2,"\n"); + buffer_flush(buffer_2); +} + +void strerr_die(int e,char *x1,char *x2,char *x3,char *x4,char *x5,char *x6,struct strerr *se) +{ + strerr_warn(x1,x2,x3,x4,x5,x6,se); + _exit(e); +} diff --git a/iguana/databases/cdb-0.75/strerr_sys.c b/iguana/databases/cdb-0.75/strerr_sys.c new file mode 100644 index 000000000..b48419771 --- /dev/null +++ b/iguana/databases/cdb-0.75/strerr_sys.c @@ -0,0 +1,12 @@ +#include "error.h" +#include "strerr.h" + +struct strerr strerr_sys; + +void strerr_sysinit(void) +{ + strerr_sys.who = 0; + strerr_sys.x = error_str(errno); + strerr_sys.y = ""; + strerr_sys.z = ""; +} diff --git a/iguana/databases/cdb-0.75/systype b/iguana/databases/cdb-0.75/systype new file mode 100644 index 000000000..aa1d3cd7b --- /dev/null +++ b/iguana/databases/cdb-0.75/systype @@ -0,0 +1 @@ +darwin-13.2.0-darwin.kernel.version.13.2.0..thu.apr.17.23.03.13.pdt.2014;.root.xnu-2422.100.13~1.release_x86_64-:i386-:-:genuineintel-00040651-bfebfbff-:- diff --git a/iguana/databases/cdb-0.75/testzero b/iguana/databases/cdb-0.75/testzero new file mode 100755 index 000000000..7fe9dffad Binary files /dev/null and b/iguana/databases/cdb-0.75/testzero differ diff --git a/iguana/databases/cdb-0.75/testzero.c b/iguana/databases/cdb-0.75/testzero.c new file mode 100644 index 000000000..683877172 --- /dev/null +++ b/iguana/databases/cdb-0.75/testzero.c @@ -0,0 +1,36 @@ +#include +#include "uint32.h" +#include "scan.h" +#include "strerr.h" +#include "cdb_make.h" + +#define FATAL "testzero: fatal: " + +void die_write(void) +{ + strerr_die2sys(111,FATAL,"unable to write: "); +} + +static char key[4]; +static char data[65536]; +struct cdb_make c; + +int main(int argc,char **argv) +{ + int fd; + unsigned long loop; + + if (!*argv) _exit(0); + if (!*++argv) _exit(0); + scan_ulong(*argv,&loop); + + if (cdb_make_start(&c,1) == -1) die_write(); + + while (loop) { + uint32_pack(key,--loop); + if (cdb_make_add(&c,key,4,data,sizeof data) == -1) die_write(); + } + + if (cdb_make_finish(&c) == -1) die_write(); + _exit(0); +} diff --git a/iguana/databases/cdb-0.75/trycpp.c b/iguana/databases/cdb-0.75/trycpp.c new file mode 100644 index 000000000..3ab455bb4 --- /dev/null +++ b/iguana/databases/cdb-0.75/trycpp.c @@ -0,0 +1,7 @@ +main() +{ +#ifdef NeXT + printf("nextstep\n"); exit(0); +#endif + printf("unknown\n"); exit(0); +} diff --git a/iguana/databases/cdb-0.75/tryulong32.c b/iguana/databases/cdb-0.75/tryulong32.c new file mode 100644 index 000000000..a10807638 --- /dev/null +++ b/iguana/databases/cdb-0.75/tryulong32.c @@ -0,0 +1,11 @@ +void main() +{ + unsigned long u; + u = 1; + u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; + u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; + u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; + u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; + if (!u) _exit(0); + _exit(1); +} diff --git a/iguana/databases/cdb-0.75/uint32.h b/iguana/databases/cdb-0.75/uint32.h new file mode 100644 index 000000000..68d723136 --- /dev/null +++ b/iguana/databases/cdb-0.75/uint32.h @@ -0,0 +1,11 @@ +#ifndef UINT32_H +#define UINT32_H + +typedef unsigned int uint32; + +extern void uint32_pack(char *,uint32); +extern void uint32_pack_big(char *,uint32); +extern void uint32_unpack(char *,uint32 *); +extern void uint32_unpack_big(char *,uint32 *); + +#endif diff --git a/iguana/databases/cdb-0.75/uint32.h1 b/iguana/databases/cdb-0.75/uint32.h1 new file mode 100644 index 000000000..68d723136 --- /dev/null +++ b/iguana/databases/cdb-0.75/uint32.h1 @@ -0,0 +1,11 @@ +#ifndef UINT32_H +#define UINT32_H + +typedef unsigned int uint32; + +extern void uint32_pack(char *,uint32); +extern void uint32_pack_big(char *,uint32); +extern void uint32_unpack(char *,uint32 *); +extern void uint32_unpack_big(char *,uint32 *); + +#endif diff --git a/iguana/databases/cdb-0.75/uint32.h2 b/iguana/databases/cdb-0.75/uint32.h2 new file mode 100644 index 000000000..b5c7f40e1 --- /dev/null +++ b/iguana/databases/cdb-0.75/uint32.h2 @@ -0,0 +1,11 @@ +#ifndef UINT32_H +#define UINT32_H + +typedef unsigned long uint32; + +extern void uint32_pack(char *,uint32); +extern void uint32_pack_big(char *,uint32); +extern void uint32_unpack(char *,uint32 *); +extern void uint32_unpack_big(char *,uint32 *); + +#endif diff --git a/iguana/databases/cdb-0.75/uint32_pack.c b/iguana/databases/cdb-0.75/uint32_pack.c new file mode 100644 index 000000000..76bc67045 --- /dev/null +++ b/iguana/databases/cdb-0.75/uint32_pack.c @@ -0,0 +1,21 @@ +#include "uint32.h" + +void uint32_pack(char s[4],uint32 u) +{ + s[0] = u & 255; + u >>= 8; + s[1] = u & 255; + u >>= 8; + s[2] = u & 255; + s[3] = u >> 8; +} + +void uint32_pack_big(char s[4],uint32 u) +{ + s[3] = u & 255; + u >>= 8; + s[2] = u & 255; + u >>= 8; + s[1] = u & 255; + s[0] = u >> 8; +} diff --git a/iguana/databases/cdb-0.75/uint32_unpack.c b/iguana/databases/cdb-0.75/uint32_unpack.c new file mode 100644 index 000000000..f484644dc --- /dev/null +++ b/iguana/databases/cdb-0.75/uint32_unpack.c @@ -0,0 +1,31 @@ +#include "uint32.h" + +void uint32_unpack(char s[4],uint32 *u) +{ + uint32 result; + + result = (unsigned char) s[3]; + result <<= 8; + result += (unsigned char) s[2]; + result <<= 8; + result += (unsigned char) s[1]; + result <<= 8; + result += (unsigned char) s[0]; + + *u = result; +} + +void uint32_unpack_big(char s[4],uint32 *u) +{ + uint32 result; + + result = (unsigned char) s[0]; + result <<= 8; + result += (unsigned char) s[1]; + result <<= 8; + result += (unsigned char) s[2]; + result <<= 8; + result += (unsigned char) s[3]; + + *u = result; +} diff --git a/iguana/databases/cdb-0.75/warn-auto.sh b/iguana/databases/cdb-0.75/warn-auto.sh new file mode 100644 index 000000000..36d2313be --- /dev/null +++ b/iguana/databases/cdb-0.75/warn-auto.sh @@ -0,0 +1,2 @@ +#!/bin/sh +# WARNING: This file was auto-generated. Do not edit! diff --git a/iguana/databases/cdb-0.75/x86cpuid.c b/iguana/databases/cdb-0.75/x86cpuid.c new file mode 100644 index 000000000..98e37dbf2 --- /dev/null +++ b/iguana/databases/cdb-0.75/x86cpuid.c @@ -0,0 +1,38 @@ +#include + +void nope() +{ + exit(1); +} + +int main() +{ + unsigned long x[4]; + unsigned long y[4]; + int i; + int j; + char c; + + signal(SIGILL,nope); + + x[0] = 0; + x[1] = 0; + x[2] = 0; + x[3] = 0; + + asm volatile(".byte 15;.byte 162" : "=a"(x[0]),"=b"(x[1]),"=c"(x[3]),"=d"(x[2]) : "0"(0) ); + if (!x[0]) return 0; + asm volatile(".byte 15;.byte 162" : "=a"(y[0]),"=b"(y[1]),"=c"(y[2]),"=d"(y[3]) : "0"(1) ); + + for (i = 1;i < 4;++i) + for (j = 0;j < 4;++j) { + c = x[i] >> (8 * j); + if (c < 32) c = 32; + if (c > 126) c = 126; + putchar(c); + } + + printf("-%08x-%08x\n",y[0],y[3]); + + return 0; +} diff --git a/iguana/databases/iguana_DB.c b/iguana/databases/iguana_DB.c new file mode 100755 index 000000000..0421be2b6 --- /dev/null +++ b/iguana/databases/iguana_DB.c @@ -0,0 +1,97 @@ +/****************************************************************************** + * 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/cJSON.h" +#include "cdb-0.75/alloc.c" +#include "cdb-0.75/buffer.c" +#include "cdb-0.75/buffer_copy.c" +#include "cdb-0.75/buffer_put.c" +#include "cdb-0.75/buffer_get.c" +#include "cdb-0.75/byte_copy.c" +#include "cdb-0.75/byte_cr.c" +#include "cdb-0.75/byte_diff.c" +#include "cdb-0.75/cdb.c" +#include "cdb-0.75/cdb_hash.c" +#include "cdb-0.75/cdb_make.c" +#include "cdb-0.75/uint32_pack.c" +#include "cdb-0.75/uint32_unpack.c" +#include "cdb-0.75/str_len.c" +#include "cdb-0.75/seek_cur.c" +#include "cdb-0.75/seek_set.c" +#include "cdb-0.75/open_read.c" +#include "cdb-0.75/open_trunc.c" +#include "cdb-0.75/error.c" +#include "cdb-0.75/error_str.c" + +int32_t cdb_jsonmake(cJSON *array,char *dest,char *tmpname) +{ + uint32_t klen,dlen,i,n,h; char *field,*value; int32_t fd; cJSON *item; struct cdb_make cdb; + memset(&cdb,0,sizeof(cdb)); + if ( (fd= open_trunc(tmpname)) == -1 ) + return(-1); + if ( cdb_make_start(&cdb,fd) == -1 ) + { + close(fd); + return(-2); + } + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; i 0) + { + value = jprint(item,0); + if ( (dlen= str_len(value)) > 0 ) + { + if ( klen > 429496720 || dlen > 429496720 || cdb_make_addbegin(&cdb,klen,dlen) == -1 ) + { + close(fd); + free(value); + return(-3); + } + h = CDB_HASHSTART; + for (i=0; i-1 && string.indexOf("bind sock")>-1 ){ APPLICATION.port7778="successfully binded"; + + setTimeout(initialization_commands,3000); if_changed=1; }else if(string.indexOf("finished DidCreate iguana")>-1){ APPLICATION.pexe="Loaded"; if_changed=1; + setTimeout(initialization_commands,3000); }else if(string.indexOf("ERROR BINDING PORT.7778")>-1){ //APPLICATION.state="Loading.."; APPLICATION.port7778="Retrying"; @@ -324,3 +353,10 @@ var change_app_status=function(){ html=html+"Port 7778 state:"+APPLICATION.port7778+""; $("#appstatus").html(html); }; + +var initialization_commands=function(){ + addInitCoins(); + load_peers_to_pool(); + ListAllExchanges(); + +}; diff --git a/iguana/exchanges/bitcoin.c b/iguana/exchanges/bitcoin.c index 4bbba662c..36fa64470 100755 --- a/iguana/exchanges/bitcoin.c +++ b/iguana/exchanges/bitcoin.c @@ -15,21 +15,12 @@ #include "bitcoin.h" -static const char base58_chars[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; +cJSON *instantdex_statemachinejson(struct bitcoin_swapinfo *swap); -#define IGUANA_SCRIPT_NULL 0 -#define IGUANA_SCRIPT_76AC 1 -#define IGUANA_SCRIPT_76A988AC 2 -#define IGUANA_SCRIPT_P2SH 3 -#define IGUANA_SCRIPT_OPRETURN 4 -#define IGUANA_SCRIPT_3of3 5 -#define IGUANA_SCRIPT_2of3 6 -#define IGUANA_SCRIPT_1of3 7 -#define IGUANA_SCRIPT_2of2 8 -#define IGUANA_SCRIPT_1of2 9 -#define IGUANA_SCRIPT_MSIG 10 -#define IGUANA_SCRIPT_DATA 11 -#define IGUANA_SCRIPT_STRANGE 15 +char *bitcoind_passthru(char *coinstr,char *serverport,char *userpass,char *method,char *params) +{ + return(bitcoind_RPC(0,coinstr,serverport,userpass,method,params)); +} int32_t bitcoin_pubkeylen(const uint8_t *pubkey) { @@ -40,120 +31,6 @@ int32_t bitcoin_pubkeylen(const uint8_t *pubkey) else return(-1); } -void bn_mpi2bn(BIGNUM *vo,uint8_t *data,int32_t datalen) -{ - uint8_t vch2[64 + 4]; uint32_t i,vch2_len = (int32_t)datalen + 4; - if ( datalen < sizeof(vch2) ) - { - vch2[0] = (datalen >> 24) & 0xff; - vch2[1] = (datalen >> 16) & 0xff; - vch2[2] = (datalen >> 8) & 0xff; - vch2[3] = (datalen >> 0) & 0xff; - for (i=0; i= 4 && sz < sizeof(s_be) ) // get MPI format size - { - BN_bn2mpi(v,s_be); - // copy-swap MPI to little endian, sans 32-bit size prefix - sz -= 4; - for (i=0; i> 1) ) - { - ctx = BN_CTX_new(); - BN_init(&bn58), BN_init(&bn0), BN_init(&bn), BN_init(&dv), BN_init(&rem); - BN_set_word(&bn58,58); - BN_set_word(&bn0,0); - for (i=0; i 0 ) - { - if ( BN_div(&dv,&rem,&bn,&bn58,ctx) == 0 ) - { - flag = -1; - break; - } - BN_copy(&bn,&dv); - rs[n++] = base58_chars[BN_get_word(&rem)]; - } - if ( flag == 0 ) - { - for (i=0; i= 2 && revdata[len - 1] == 0 && revdata[len - 2] >= 0x80 ) - len--; - zeroes = 0; - for (p=coinaddr; *p==base58_chars[0]; p++) - zeroes++; - be_sz = (uint32_t)len + (uint32_t)zeroes; - memset(data,0,be_sz); - for (i=0; ichain->pubtype && addrtype != coin->chain->p2shtype ) return(-1); - else if ( bitcoin_address(coinaddr,addrtype,rmd160,sizeof(rmd160)) != coinaddr ) + else if ( bitcoin_address(checkaddr,addrtype,rmd160,sizeof(rmd160)) != checkaddr || strcmp(checkaddr,coinaddr) != 0 ) return(-1); return(0); } -EC_KEY *bitcoin_privkeyset(uint8_t *oddevenp,bits256 *pubkeyp,bits256 privkey) -{ - BIGNUM *bn; BN_CTX *ctx = NULL; uint8_t *ptr,tmp[33]; EC_POINT *pub_key = NULL; const EC_GROUP *group; - EC_KEY *KEY = EC_KEY_new_by_curve_name(NID_secp256k1); - *oddevenp = 0; - EC_KEY_set_conv_form(KEY,POINT_CONVERSION_COMPRESSED); - { - if ( (group= EC_KEY_get0_group(KEY)) != 0 && (ctx= BN_CTX_new()) != 0 ) - { - if ( (pub_key= EC_POINT_new(group)) != 0 ) - { - if ( (bn= BN_bin2bn(privkey.bytes,sizeof(privkey),BN_new())) != 0 ) - { - if ( EC_POINT_mul(group,pub_key,bn,NULL,NULL,ctx) > 0 ) - { - EC_KEY_set_private_key(KEY,bn); - EC_KEY_set_public_key(KEY,pub_key); - ptr = tmp; - i2o_ECPublicKey(KEY,&ptr); - *oddevenp = tmp[0]; - memcpy(pubkeyp->bytes,&tmp[1],sizeof(*pubkeyp)); - } - BN_clear_free(bn); - } - EC_POINT_free(pub_key); - } - BN_CTX_free(ctx); - } - } - return(KEY); -} - -bits256 bitcoin_pubkey33(uint8_t *data,bits256 privkey) -{ - uint8_t oddeven; bits256 pubkey; - EC_KEY *KEY; - if ( (KEY= bitcoin_privkeyset(&oddeven,&pubkey,privkey)) != 0 ) - { - data[0] = oddeven; - memcpy(data+1,pubkey.bytes,sizeof(pubkey)); - EC_KEY_free(KEY); - } - return(pubkey); -} - -/*int32_t bitcoin_priv2wif(char *wifstr,uint8_t privkey[32],uint8_t addrtype) -{ - uint8_t tmp[128]; char hexstr[67]; cstring *btc_addr; - memcpy(tmp,privkey,32); - tmp[32] = 1; - init_hexbytes_noT(hexstr,tmp,32); - if ( (btc_addr= base58_encode_check(addrtype,true,tmp,33)) != 0 ) - { - strcpy(wifstr,btc_addr->str); - cstr_free(btc_addr,true); - } - printf("-> (%s) -> wif.(%s) addrtype.%02x\n",hexstr,wifstr,addrtype); - return(0); -} - -int32_t bitcoin_wif2priv(uint8_t *addrtypep,uint8_t privkey[32],char *wifstr) -{ - cstring *cstr; int32_t len = -1; - if ( (cstr= base58_decode_check(addrtypep,(const char *)wifstr)) != 0 ) - { - init_hexbytes_noT((void *)privkey,(void *)cstr->str,cstr->len); - if ( cstr->str[cstr->len-1] == 0x01 ) - cstr->len--; - memcpy(privkey,cstr->str,cstr->len); - len = (int32_t)cstr->len; - char tmp[138]; - btc_priv2wif(tmp,privkey,*addrtypep); - printf("addrtype.%02x wifstr.(%llx) len.%d\n",*addrtypep,*(long long *)privkey,len); - cstr_free(cstr,true); - } - return(len); -}*/ - -int32_t bitcoin_sign(uint8_t *sig,int32_t maxlen,uint8_t *data,int32_t datalen,bits256 privkey) -{ - uint32_t siglen; EC_KEY *KEY; uint8_t oddeven; bits256 pubkey; int32_t retval = -1; - if ( (KEY= bitcoin_privkeyset(&oddeven,&pubkey,privkey)) != 0 ) - { - if ( ECDSA_sign(0,data,datalen,sig,&siglen,KEY) > 0 && siglen <= maxlen ) - retval = siglen; - EC_KEY_free(KEY); - } - return(retval); -} - -int32_t bitcoin_verify(uint8_t *sig,int32_t siglen,uint8_t *data,int32_t datalen,EC_KEY *KEY,uint8_t *pubkey,int32_t len) -{ - ECDSA_SIG *esig; int32_t retval = -1; uint8_t tmp[33],*ptr,*sigptr = sig; EC_KEY *origkey = KEY; - if ( (esig= ECDSA_SIG_new()) != 0 ) - { - if ( d2i_ECDSA_SIG(&esig,(const uint8_t **)&sigptr,siglen) != 0 ) - { - if ( KEY != 0 || (KEY= EC_KEY_new_by_curve_name(NID_secp256k1)) != 0 ) - { - EC_KEY_set_conv_form(KEY,POINT_CONVERSION_COMPRESSED); - if ( len == 32 ) - { - memcpy(tmp+1,pubkey,len); - for (tmp[0]=2; tmp[0]<=3; tmp[0]++) - { - ptr = tmp; - o2i_ECPublicKey(&KEY,(const uint8_t **)&ptr,33); - if ( ECDSA_do_verify(data,datalen,esig,KEY) > 0 ) - { - retval = 0; - break; - } - } - } - else - { - ptr = pubkey; - o2i_ECPublicKey(&KEY,(const uint8_t **)&ptr,len); - if ( ECDSA_do_verify(data,datalen,esig,KEY) > 0 ) - retval = 0; - } - if ( origkey == 0 ) - EC_KEY_free(KEY); - } - } - ECDSA_SIG_free(esig); - } - return(retval); -} - -int32_t bitcoin_pubkeyspend(uint8_t *script,int32_t n,uint8_t pubkey[66]) +int32_t base58encode_checkbuf(uint8_t addrtype,uint8_t *data,int32_t data_len) { - int32_t scriptlen = bitcoin_pubkeylen(pubkey); - script[n++] = scriptlen; - memcpy(&script[n],pubkey,scriptlen); - n += scriptlen; - script[n++] = SCRIPT_OP_CHECKSIG; - return(n); -} - -int32_t bitcoin_p2shspend(uint8_t *script,int32_t n,uint8_t rmd160[20]) -{ - script[n++] = SCRIPT_OP_HASH160; - script[n++] = 0x14; memcpy(&script[n],rmd160,0x14); n += 0x14; - script[n++] = SCRIPT_OP_EQUAL; - return(n); -} - -int32_t bitcoin_revealsecret160(uint8_t *script,int32_t n,uint8_t secret160[20]) -{ - script[n++] = SCRIPT_OP_HASH160; - script[n++] = 0x14; memcpy(&script[n],secret160,0x14); n += 0x14; - script[n++] = SCRIPT_OP_EQUALVERIFY; - return(n); -} - -int32_t bitcoin_standardspend(uint8_t *script,int32_t n,uint8_t rmd160[20]) -{ - script[n++] = SCRIPT_OP_DUP; - script[n++] = SCRIPT_OP_HASH160; - script[n++] = 0x14; memcpy(&script[n],rmd160,0x14); n += 0x14; - script[n++] = SCRIPT_OP_EQUALVERIFY; - script[n++] = SCRIPT_OP_CHECKSIG; - return(n); -} - -int32_t bitcoin_checklocktimeverify(uint8_t *script,int32_t n,uint32_t locktime) -{ - script[n++] = (locktime >> 24), script[n++] = (locktime >> 16), script[n++] = (locktime >> 8), script[n++] = locktime; - script[n++] = OP_CHECKLOCKTIMEVERIFY; - script[n++] = OP_DROP; - return(n); -} - -int32_t bitcoin_MofNspendscript(uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,const struct vin_info *vp) -{ - uint8_t sha256[32]; int32_t i,plen; - script[n++] = 0x50 + vp->M; - for (i=0; iN; i++) - { - if ( (plen= bitcoin_pubkeylen(vp->signers[i].pubkey)) < 0 ) - return(-1); - script[n++] = plen; - memcpy(&script[n],vp->signers[i].pubkey,plen); - n += plen; - } - script[n++] = 0x50 + vp->N; - script[n++] = SCRIPT_OP_CHECKMULTISIG; - vcalc_sha256(0,sha256,script,n); - calc_rmd160(0,p2sh_rmd160,sha256,sizeof(sha256)); - return(n); -} - -int32_t bitcoin_p2shscript(uint8_t *script,int32_t n,const uint8_t *p2shscript,const int32_t p2shlen) -{ - if ( p2shlen >= 0xfd ) - { - script[n++] = 0x4d; - script[n++] = (p2shlen & 0xff); - script[n++] = ((p2shlen >> 8) & 0xff); - } - else - { - script[n++] = 0x4c; - script[n++] = p2shlen; - } - memcpy(&script[n],p2shscript,p2shlen), n += p2shlen; - return(n); + uint8_t i; bits256 hash; + data[0] = addrtype; + //for (i=0; i "); + hash = bits256_doublesha256(0,data,(int32_t)data_len+1); + //for (i=0; i<32; i++) + // printf("%02x",hash.bytes[i]); + //printf(" checkhash\n"); + for (i=0; i<4; i++) + data[data_len+i+1] = hash.bytes[31-i]; + return(data_len + 5); } -int32_t bitcoin_changescript(struct iguana_info *coin,uint8_t *changescript,int32_t n,uint64_t *changep,char *changeaddr,uint64_t inputsatoshis,uint64_t satoshis,uint64_t txfee) +int32_t bitcoin_wif2priv(uint8_t *addrtypep,bits256 *privkeyp,char *wifstr) { - uint8_t addrtype,rmd160[20]; int32_t len; - *changep = 0; - if ( inputsatoshis >= (satoshis + txfee) ) + int32_t len = -1; bits256 hash; uint8_t buf[64]; + if ( (len= bitcoin_base58decode(buf,wifstr)) >= 4 ) { - *changep = inputsatoshis - (satoshis + txfee); - if ( changeaddr != 0 && changeaddr[0] != 0 ) + // validate with trailing hash, then remove hash + hash = bits256_doublesha256(0,buf,len - 4); + *addrtypep = *buf; + memcpy(privkeyp,buf+1,32); + if ( (buf[len - 4]&0xff) == hash.bytes[31] && (buf[len - 3]&0xff) == hash.bytes[30] &&(buf[len - 2]&0xff) == hash.bytes[29] &&(buf[len - 1]&0xff) == hash.bytes[28] ) { - bitcoin_addr2rmd160(&addrtype,rmd160,changeaddr); - if ( addrtype == coin->chain->pubtype ) - len = bitcoin_standardspend(changescript,0,rmd160); - else if ( addrtype == coin->chain->p2shtype ) - len = bitcoin_standardspend(changescript,0,rmd160); - else - { - printf("error with mismatched addrtype.%02x vs (%02x %02x)\n",addrtype,coin->chain->pubtype,coin->chain->p2shtype); - return(-1); - } - return(len); + //printf("coinaddr.(%s) valid checksum\n",coinaddr); + return(32); } - else printf("error no change address when there is change\n"); } return(-1); } -int32_t bitcoin_scriptsig(uint8_t *script,int32_t n,const struct vin_info *vp) +int32_t bitcoin_priv2wif(char *wifstr,bits256 privkey,uint8_t addrtype) { - int32_t i,siglen; - if ( vp->N > 1 ) - script[n++] = SCRIPT_OP_NOP; - for (i=0; iN; i++) + uint8_t data[128]; int32_t len; + memcpy(data+1,privkey.bytes,sizeof(privkey)); + data[33] = 1; + len = base58encode_checkbuf(addrtype,data,33); + + if ( bitcoin_base58encode(wifstr,data,len) == 0 ) + return(-1); + if ( 1 ) { - if ( (siglen= vp->signers[i].siglen) != 0 ) + uint8_t checktype; bits256 checkpriv; char str[65],str2[65]; + if ( bitcoin_wif2priv(&checktype,&checkpriv,wifstr) == sizeof(bits256) ) { - script[n++] = siglen; - memcpy(&script[n],vp->signers[i].sig,siglen), n += siglen; + if ( checktype != addrtype || bits256_cmp(checkpriv,privkey) != 0 ) + printf("(%s) -> wif.(%s) addrtype.%02x -> %02x (%s)\n",bits256_str(str,privkey),wifstr,addrtype,checktype,bits256_str(str2,checkpriv)); } } - if ( vp->type == IGUANA_SCRIPT_P2SH ) - n = bitcoin_p2shscript(script,n,vp->p2shscript,vp->p2shlen); - return(n); + return((int32_t)strlen(wifstr)); } -int32_t bitcoin_cltvscript(uint8_t p2shtype,char *ps2h_coinaddr,uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,char *senderaddr,char *otheraddr,uint8_t secret160[20],uint32_t locktime) +int32_t iguana_validatesigs(struct iguana_info *coin,struct iguana_msgvin *vin) { - // OP_IF - // OP_CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG - // OP_ELSE - // OP_HASH160 secret160 OP_EQUALVERIFY OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG // standard spend - // OP_ENDIF - uint8_t sha256[32],rmd160A[20],rmd160B[20],addrtypeA,addrtypeB; - bitcoin_addr2rmd160(&addrtypeA,rmd160A,senderaddr); - bitcoin_addr2rmd160(&addrtypeB,rmd160B,otheraddr); - script[n++] = SCRIPT_OP_IF; - n = bitcoin_checklocktimeverify(script,n,locktime); - n = bitcoin_standardspend(script,n,rmd160A); - script[n++] = SCRIPT_OP_ELSE; - n = bitcoin_revealsecret160(script,n,secret160); - n = bitcoin_standardspend(script,n,rmd160B); - script[n++] = SCRIPT_OP_ENDIF; - vcalc_sha256(0,sha256,script,n); - calc_rmd160(0,p2sh_rmd160,sha256,sizeof(sha256)); - bitcoin_address(ps2h_coinaddr,p2shtype,p2sh_rmd160,20); - return(n); + // multiple coins + // ro -> vouts collision, purgeable + // + return(0); } -int32_t iguana_scriptgen(struct iguana_info *coin,int32_t *Mp,int32_t *nump,char *coinaddr,uint8_t *script,char *asmstr,uint8_t rmd160[20],uint8_t type,const struct vin_info *vp,int32_t txi) +uint64_t bitcoin_parseunspent(struct iguana_info *coin,struct bitcoin_unspent *unspent,double minconfirms,char *account,cJSON *item) { - uint8_t addrtype; char rmd160str[41],pubkeystr[256]; int32_t i,m,n,flag = 0,scriptlen = 0; - m = n = 1; - if ( type == IGUANA_SCRIPT_76A988AC || type == IGUANA_SCRIPT_76AC || type == IGUANA_SCRIPT_P2SH ) - { - if ( type == IGUANA_SCRIPT_P2SH ) - addrtype = coin->chain->p2shtype; - else addrtype = coin->chain->pubtype; - init_hexbytes_noT(rmd160str,rmd160,20); - btc_convrmd160(coinaddr,addrtype,rmd160); - } - switch ( type ) + uint8_t addrtype; char *hexstr,*wifstr,coinaddr[64],args[128]; + memset(unspent,0,sizeof(*unspent)); + if ( jstr(item,"address") != 0 ) { - case IGUANA_SCRIPT_NULL: - strcpy(asmstr,txi == 0 ? "coinbase " : "PoSbase "); - flag++; - coinaddr[0] = 0; - break; - case IGUANA_SCRIPT_76AC: - init_hexbytes_noT(pubkeystr,(uint8_t *)vp->signers[0].pubkey,bitcoin_pubkeylen(vp->signers[0].pubkey)); - sprintf(asmstr,"OP_DUP %s OP_CHECKSIG // %s",pubkeystr,coinaddr); - scriptlen = bitcoin_pubkeyspend(script,0,(uint8_t *)vp->signers[0].pubkey); - //printf("[%02x] scriptlen.%d (%s)\n",vp->signers[0].pubkey[0],scriptlen,asmstr); - break; - case IGUANA_SCRIPT_76A988AC: - sprintf(asmstr,"OP_DUP OP_HASH160 %s OP_EQUALVERIFY OP_CHECKSIG // %s",rmd160str,coinaddr); - scriptlen = bitcoin_standardspend(script,0,rmd160); - break; - case IGUANA_SCRIPT_P2SH: - sprintf(asmstr,"OP_HASH160 %s OP_EQUAL // %s",rmd160str,coinaddr); - scriptlen = bitcoin_p2shspend(script,0,rmd160); - break; - case IGUANA_SCRIPT_OPRETURN: - strcpy(asmstr,"OP_RETURN "); - flag++; - break; - case IGUANA_SCRIPT_3of3: m = 3, n = 3; break; - case IGUANA_SCRIPT_2of3: m = 2, n = 3; break; - case IGUANA_SCRIPT_1of3: m = 1, n = 3; break; - case IGUANA_SCRIPT_2of2: m = 2, n = 2; break; - case IGUANA_SCRIPT_1of2: m = 1, n = 2; break; - case IGUANA_SCRIPT_MSIG: m = vp->M, n = vp->N; break; - case IGUANA_SCRIPT_DATA: - strcpy(asmstr,"DATA ONLY"); - flag++; - break; - case IGUANA_SCRIPT_STRANGE: - strcpy(asmstr,"STRANGE SCRIPT "); - flag++; - break; - default: printf("unexpected script type\n"); break; + safecopy(coinaddr,jstr(item,"address"),sizeof(coinaddr)); + bitcoin_addr2rmd160(&unspent->addrtype,unspent->rmd160,coinaddr); + sprintf(args,"[\"%s\"]",coinaddr); + wifstr = bitcoind_RPC(0,coin->symbol,coin->chain->serverport,coin->chain->userpass,"dumpprivkey",args); + if ( wifstr != 0 ) + { + bitcoin_wif2priv(&addrtype,&unspent->privkeys[0],wifstr); + //printf("wifstr.(%s) -> %s\n",wifstr,bits256_str(str,unspent->privkeys[0])); + free(wifstr); + } else fprintf(stderr,"error (%s) cant find privkey\n",coinaddr); } - if ( n > 1 ) + if ( (account == 0 || jstr(item,"account") == 0 || strcmp(account,jstr(item,"account")) == 0) && (minconfirms <= 0 || juint(item,"confirmations") >= minconfirms-SMALLVAL) ) { - scriptlen = bitcoin_MofNspendscript(rmd160,script,0,vp); - sprintf(asmstr,"%d ",m); - for (i=0; isigners[i].pubkey,bitcoin_pubkeylen(vp->signers[i].pubkey)); - strcat(asmstr," "); + unspent->spendlen = (int32_t)strlen(hexstr) >> 1; + if ( unspent->spendlen < sizeof(unspent->spendscript) ) + decode_hex(unspent->spendscript,unspent->spendlen,hexstr); } - sprintf(asmstr + strlen(asmstr),"%d // M.%d of N.%d [",n,m,n); - for (i=0; isigners[i].coinaddr,ispendlen > 0 ) - init_hexbytes_noT(asmstr + strlen(asmstr),(uint8_t *)vp->spendscript,vp->spendlen); - *Mp = m, *nump = n; - return(scriptlen); + unspent->txid = jbits256(item,"txid"); + unspent->value = SATOSHIDEN * jdouble(item,"amount"); + unspent->vout = jint(item,"vout"); + //char str[65]; printf("(%s) -> %s %.8f scriptlen.%d\n",jprint(item,0),bits256_str(str,unspent->txid),dstr(unspent->value),unspent->scriptlen); + } else printf("skip.(%s) minconfirms.%f\n",jprint(item,0),minconfirms); + return(unspent->value); } -int32_t _iguana_calcrmd160(struct iguana_info *coin,struct vin_info *vp) +struct bitcoin_unspent *iguana_unspentsget(struct supernet_info *myinfo,struct iguana_info *coin,char **retstrp,double *balancep,int32_t *numunspentsp,double minconfirms,char *account) { - static uint8_t zero_rmd160[20]; - char hexstr[8192]; uint8_t sha256[32],*script,type; int32_t i,n,m,plen; - vp->N = 1; - vp->M = 1; - type = IGUANA_SCRIPT_STRANGE; - if ( vp->spendlen == 0 ) + char params[128],*retstr; uint64_t value,total = 0; struct bitcoin_unspent *unspents=0; cJSON *utxo; int32_t i,n; + if ( account != 0 && account[0] == 0 ) + account = 0; + *numunspentsp = 0; + if ( retstrp != 0 ) + *retstrp = 0; + sprintf(params,"%.0f, 99999999",minconfirms); + if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"listunspent",params)) != 0 ) { - if ( zero_rmd160[0] == 0 ) + //printf("sss unspents.(%s)\n",retstr); + if ( (utxo= cJSON_Parse(retstr)) != 0 ) { - vcalc_sha256(0,sha256,vp->spendscript,vp->spendlen); // e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 - calc_rmd160(0,zero_rmd160,sha256,sizeof(sha256)); // b472a266d0bd89c13706a4132ccfb16f7c3b9fcb - init_hexbytes_noT(hexstr,zero_rmd160,20); - char str[65]; printf("iguana_calcrmd160 zero len %s -> %s\n",bits256_str(str,*(bits256 *)sha256),hexstr); - } - memcpy(vp->rmd160,zero_rmd160,sizeof(zero_rmd160)); - return(IGUANA_SCRIPT_NULL); - } - else if ( vp->spendscript[0] == SCRIPT_OP_RETURN ) - type = IGUANA_SCRIPT_OPRETURN; - else if ( vp->spendscript[0] == SCRIPT_OP_DUP && vp->spendscript[1] == SCRIPT_OP_HASH160 && vp->spendscript[2] == 20 && vp->spendscript[vp->spendscript[2]+3] == SCRIPT_OP_EQUALVERIFY && vp->spendscript[vp->spendscript[2]+4] == SCRIPT_OP_CHECKSIG ) - { - //printf("IGUANA_SCRIPT_76A988AC plen.%d vs %d vp->spendlen\n",vp->spendscript[2]+4,vp->spendlen); - // 76a9145f69cb73016264270dae9f65c51f60d0e4d6fd4488ac - //vcalc_sha256(0,sha256,&vp->spendscript[3],vp->spendscript[2]); - //calc_rmd160(0,vp->rmd160,sha256,sizeof(sha256)); - memcpy(vp->rmd160,&vp->spendscript[3],20); - if ( (plen= vp->spendscript[2]+5) < vp->spendlen ) - { - while ( plen < vp->spendlen ) - if ( vp->spendscript[plen++] != 0x61 ) // nop - return(IGUANA_SCRIPT_STRANGE); - } - return(IGUANA_SCRIPT_76A988AC); - } - // 21035f1321ed17d387e4433b2fa229c53616057964af065f98bfcae2233c5108055eac - else if ( vp->spendscript[0] > 0 && vp->spendscript[0] < 76 && vp->spendscript[vp->spendlen-1] == SCRIPT_OP_CHECKSIG && vp->spendscript[0] == vp->spendlen-2 ) - { - memcpy(vp->signers[0].pubkey,&vp->spendscript[1],vp->spendscript[0]); - vcalc_sha256(0,sha256,vp->signers[0].pubkey,vp->spendscript[0]); - calc_rmd160(0,vp->rmd160,sha256,sizeof(sha256)); - return(IGUANA_SCRIPT_76AC); - } - else if ( vp->spendscript[0] == SCRIPT_OP_HASH160 && vp->spendscript[1] == 0x14 && vp->spendlen == 23 && vp->spendscript[22] == SCRIPT_OP_EQUAL ) - { - memcpy(vp->rmd160,vp->spendscript+2,20); - return(IGUANA_SCRIPT_P2SH); - } - else if ( vp->spendlen > 34 && vp->spendscript[vp->spendlen-1] == SCRIPT_OP_CHECKMULTISIG && (n= vp->spendscript[vp->spendlen-2]) >= 0x51 && n <= 0x60 && (m= vp->spendscript[0]) >= 0x51 && m <= n ) // m of n multisig - { - m -= 0x50, n -= 0x50; - script = vp->spendscript+1; - for (i=0; i 0 ) { - printf("multisig.%d of %d: invalid pubkey[%02x] len %d\n",i,n,script[0],bitcoin_pubkeylen(script)); - return(-1); + unspents = calloc(*numunspentsp,sizeof(*unspents)); + for (i=0; i<*numunspentsp; i++) + { + value = bitcoin_parseunspent(coin,&unspents[n],minconfirms,account,jitem(utxo,i)); + //printf("i.%d n.%d value %.8f\n",i,n,dstr(value)); + if ( value != 0 ) + { + total += value; + n++; + } + } } - memcpy(vp->signers[i].pubkey,script,plen); - vcalc_sha256(0,sha256,vp->signers[i].pubkey,plen); - calc_rmd160(0,vp->signers[i].rmd160,sha256,sizeof(sha256)); - bitcoin_address(vp->signers[i].coinaddr,coin->chain->pubtype,vp->signers[i].pubkey,plen); - } - if ( (int32_t)((long)script - (long)vp->spendscript) == vp->spendlen-2 ) - { - vp->N = n; - vp->M = m; - //printf("M.%d N.%d\n",m,n); - } - vcalc_sha256(0,sha256,vp->spendscript,vp->spendlen); - calc_rmd160(0,vp->rmd160,sha256,sizeof(sha256)); - if ( n == 3 ) - { - if ( m == 3 ) - return(IGUANA_SCRIPT_3of3); - else if ( m == 2 ) - return(IGUANA_SCRIPT_2of3); - else if ( m == 1 ) - return(IGUANA_SCRIPT_1of3); - } - else if ( n == 2 ) - { - if ( m == 2 ) - return(IGUANA_SCRIPT_2of2); - else if ( m == 1 ) - return(IGUANA_SCRIPT_1of2); - } - printf("strange msig M.%d of N.%d\n",m,n); - return(IGUANA_SCRIPT_MSIG); + //printf("numunspents.%d -> %d total %.8f\n",*numunspentsp,n,dstr(total)); + *numunspentsp = n; + free_json(utxo); + } else printf("error parsing.(%s)\n",retstr); + if ( retstrp != 0 ) + *retstrp = retstr; + else free(retstr); } - else if ( vp->spendlen == vp->spendscript[0]+1 ) - { - //printf("just data.%d\n",vp->spendlen); - memcpy(vp->rmd160,zero_rmd160,sizeof(zero_rmd160)); - return(IGUANA_SCRIPT_DATA); - } - if ( type != IGUANA_SCRIPT_OPRETURN ) - { - if ( vp->spendlen < sizeof(hexstr)/2-1) - { - static FILE *fp; - init_hexbytes_noT(hexstr,vp->spendscript,vp->spendlen); - char str[65]; printf("unparsed script.(%s).%d in %s len.%d\n",hexstr,vp->spendlen,bits256_str(str,vp->vin.prev_hash),vp->spendlen); - if ( 1 && fp == 0 ) - fp = fopen("unparsed.txt","w"); - if ( fp != 0 ) - fprintf(fp,"%s\n",hexstr), fflush(fp); - } else sprintf(hexstr,"pkscript overflowed %ld\n",(long)sizeof(hexstr)); - } - vcalc_sha256(0,sha256,vp->spendscript,vp->spendlen); - calc_rmd160(0,vp->rmd160,sha256,sizeof(sha256)); - return(type); + *balancep = dstr(total); + return(unspents); } -int32_t iguana_calcrmd160(struct iguana_info *coin,struct vin_info *vp,uint8_t *pk_script,int32_t pk_scriptlen,bits256 debugtxid,int32_t vout,uint32_t sequence) +struct bitcoin_unspent *iguana_bestfit(struct iguana_info *coin,struct bitcoin_unspent *unspents,int32_t numunspents,uint64_t value,int32_t mode) { - int32_t scriptlen; uint8_t script[IGUANA_MAXSCRIPTSIZE]; char asmstr[IGUANA_MAXSCRIPTSIZE*3]; - memset(vp,0,sizeof(*vp)); - vp->vin.prev_hash = debugtxid, vp->vin.prev_vout = vout; - vp->spendlen = pk_scriptlen; - vp->vin.sequence = sequence; - memcpy(vp->spendscript,pk_script,pk_scriptlen); - if ( (vp->type= _iguana_calcrmd160(coin,vp)) >= 0 ) + int32_t i; uint64_t above,below,gap,atx_value; struct bitcoin_unspent *vin,*abovevin,*belowvin; + abovevin = belowvin = 0; + for (above=below=i=0; iM,&vp->N,vp->coinaddr,script,asmstr,vp->rmd160,vp->type,(const struct vin_info *)vp,vout); - if ( scriptlen != pk_scriptlen || memcmp(script,pk_script,scriptlen) != 0 ) + vin = &unspents[i]; + atx_value = vin->value; + //printf("(%.8f vs %.8f)\n",dstr(atx_value),dstr(value)); + if ( atx_value == value ) + return(vin); + else if ( atx_value > value ) { - if ( vp->type != IGUANA_SCRIPT_OPRETURN ) + gap = (atx_value - value); + if ( above == 0 || gap < above ) { - int32_t i; - printf("\n--------------------\n"); - for (i=0; itype,scriptlen,pk_scriptlen); + above = gap; + abovevin = vin; } } - } - return(vp->type); -} - -int32_t iguana_parsevoutobj(struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_msgvout *vout,cJSON *voutobj) -{ - int32_t len = 0; cJSON *skey; char *hexstr; - memset(vout,0,sizeof(*vout)); - vout->value = jdouble(voutobj,"value") * SATOSHIDEN; - if ( (skey= jobj(voutobj,"scriptPubKey")) != 0 ) - { - if ( (hexstr= jstr(skey,"hex")) != 0 ) + else if ( mode == 0 ) { - len = (int32_t)strlen(hexstr) >> 1; - decode_hex(serialized,len,hexstr); - vout->pk_script = serialized; - vout->pk_scriptlen = len; - } - } - return(len); -} - -int32_t iguana_parsevinobj(struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_msgvin *vin,cJSON *vinobj) -{ - int32_t len = 0; char *hexstr; cJSON *sigjson; - memset(vin,0,sizeof(*vin)); - vin->prev_vout = -1; - vin->sequence = juint(vinobj,"sequence"); - if ( (hexstr= jstr(vinobj,"coinbase")) == 0 ) - { - vin->prev_hash = jbits256(vinobj,"txid"); - vin->prev_vout = jint(vinobj,"vout"); - if ( (sigjson= jobj(vinobj,"scriptSig")) != 0 ) - hexstr = jstr(sigjson,"hex"); - } - if ( hexstr != 0 ) - { - len = (int32_t)strlen(hexstr) >> 1; - decode_hex(serialized,len,hexstr); - vin->script = serialized; - vin->scriptlen = len; - } - else - { - printf("iguana_parsevinobj: hex script missing (%s)\n",jprint(vinobj,0)); - return(0); - } - return(len); -} - -cJSON *iguana_voutjson(struct iguana_info *coin,struct iguana_msgvout *vout,int32_t txi,bits256 txid) -{ - // 035f1321ed17d387e4433b2fa229c53616057964af065f98bfcae2233c5108055e OP_CHECKSIG - char scriptstr[8192+1],asmstr[16384]; int32_t i,m,n,scriptlen,asmtype; struct vin_info *vp; - uint8_t space[8192]; cJSON *addrs,*skey,*json = cJSON_CreateObject(); - vp = calloc(1,sizeof(*vp)); - jaddnum(json,"value",dstr(vout->value)); - jaddnum(json,"n",txi); - //"scriptPubKey":{"asm":"OP_DUP OP_HASH160 5f69cb73016264270dae9f65c51f60d0e4d6fd44 OP_EQUALVERIFY OP_CHECKSIG","reqSigs":1,"type":"pubkeyhash","addresses":["RHyh1V9syARTf2pyxibz7v27D5paBeWza5"]} - if ( vout->pk_script != 0 && vout->pk_scriptlen*2+1 < sizeof(scriptstr) ) - { - memset(vp,0,sizeof(*vp)); - if ( (asmtype= iguana_calcrmd160(coin,vp,vout->pk_script,vout->pk_scriptlen,txid,txi,0xffffffff)) >= 0 ) - { - skey = cJSON_CreateObject(); - scriptlen = iguana_scriptgen(coin,&m,&n,vp->coinaddr,space,asmstr,vp->rmd160,asmtype,vp,txi); - if ( asmstr[0] != 0 ) - jaddstr(skey,"asm",asmstr); - addrs = cJSON_CreateArray(); - if ( vp->N == 1 ) + gap = (value - atx_value); + if ( below == 0 || gap < below ) { - if ( asmtype == 2 ) - { - jaddnum(skey,"reqSigs",1); - jaddstr(skey,"type","pubkeyhash"); - } - if ( vp->coinaddr[0] != 0 ) - jaddistr(addrs,vp->coinaddr); - } - else - { - jaddnum(skey,"reqSigs",vp->M); - for (i=0; iN; i++) - { - //btc_convrmd160(coinaddr,coin->chain->pubtype,V.signers[i].pubkey); - jaddistr(addrs,vp->signers[i].coinaddr); - } + below = gap; + belowvin = vin; } - jadd(skey,"addresses",addrs); - init_hexbytes_noT(scriptstr,vout->pk_script,vout->pk_scriptlen); - if ( scriptstr[0] != 0 ) - jaddstr(skey,"hex",scriptstr); - jadd(json,"scriptPubKey",skey); - } - } - return(json); -} - -cJSON *iguana_vinjson(struct iguana_info *coin,struct iguana_msgvin *vin) -{ - char scriptstr[8192+1],str[65]; int32_t vout; cJSON *sigjson,*json = cJSON_CreateObject(); - vout = vin->prev_vout; - jaddnum(json,"sequence",vin->sequence); - if ( vin->script != 0 && vin->scriptlen*2+1 < sizeof(scriptstr) ) - init_hexbytes_noT(scriptstr,vin->script,vin->scriptlen); - if ( vout < 0 && bits256_nonz(vin->prev_hash) == 0 ) - jaddstr(json,"coinbase",scriptstr); - else - { - jaddstr(json,"txid",bits256_str(str,vin->prev_hash)); - jaddnum(json,"vout",vout); - sigjson = cJSON_CreateObject(); - jaddstr(sigjson,"hex",scriptstr); - jadd(json,"scriptSig",sigjson); - } - return(json); -} - -int32_t iguana_vinparse(struct iguana_info *coin,int32_t rwflag,uint8_t *serialized,struct iguana_msgvin *msg) -{ - int32_t len = 0; - len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->prev_hash),msg->prev_hash.bytes); - len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->prev_vout),&msg->prev_vout); - len += iguana_rwvarint32(rwflag,&serialized[len],&msg->scriptlen); - if ( rwflag == 0 ) - msg->script = &serialized[len]; - else memcpy(&serialized[len],msg->script,msg->scriptlen); - len += msg->scriptlen; - len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->sequence),&msg->sequence); - if ( 0 ) - { - int32_t i; char str[65]; - for (i=0; iscriptlen; i++) - printf("%02x",msg->script[i]); - printf(" prev_hash.(%s) vout.%d [%p] scriptlen.%d rwflag.%d\n",bits256_str(str,msg->prev_hash),msg->prev_vout,msg->script,msg->scriptlen,rwflag); - } - return(len); -} - -int32_t iguana_voutparse(int32_t rwflag,uint8_t *serialized,struct iguana_msgvout *msg) -{ - int32_t len = 0; - len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->value),&msg->value); - len += iguana_rwvarint32(rwflag,&serialized[len],&msg->pk_scriptlen); - if ( rwflag == 0 ) - msg->pk_script = &serialized[len]; - else memcpy(&serialized[len],msg->pk_script,msg->pk_scriptlen); - if ( 0 ) - { - int32_t i; - for (i=0; ipk_scriptlen; i++) - printf("%02x",msg->pk_script[i]); - printf(" [%p] scriptlen.%d rwflag.%d %.8f\n",msg->pk_script,msg->pk_scriptlen,rwflag,dstr(msg->value)); - } - len += msg->pk_scriptlen; - return(len); -} - -// {"result":{"txid":"867ab5071349ef8d0dcd03a43017b6b440c9533cb26a8a6870127e7884ff96f6","version":1,"time":1404960685,"locktime":0,"vin":[{"coinbase":"510103","sequence":4294967295}],"vout":[{"value":80.00000000,"n":0,"scriptPubKey":{"asm":"OP_DUP OP_HASH160 5f69cb73016264270dae9f65c51f60d0e4d6fd44 OP_EQUALVERIFY OP_CHECKSIG","reqSigs":1,"type":"pubkeyhash","addresses":["RHyh1V9syARTf2pyxibz7v27D5paBeWza5"]}}],"blockhash":"000000000c4682089c916de89eb080a877566494d4009c0089baf35fe94de22f","confirmations":930039} -//{"version":1,"timestamp":1404960685,"vins":[{"sequence":4294967295,"coinbase":"510103"}],"numvins":1,"vouts":[{"value":80,"n":0,"scriptPubKey":{"asm":"OP_DUP OP_HASH160 5f69cb73016264270dae9f65c51f60d0e4d6fd44 OP_EQUALVERIFY OP_CHECKSIG","reqSigs":1,"type":"pubkeyhash","addrs":["RHyh1V9syARTf2pyxibz7v27D5paBeWza5"],"hex":"76a9145f69cb73016264270dae9f65c51f60d0e4d6fd4488ac"}}],"numvouts":1,"locktime":0,"size":92,"txid":"867ab5071349ef8d0dcd03a43017b6b440c9533cb26a8a6870127e7884ff96f6","tag":"3968374231439324584"} - -int32_t iguana_rwmsgtx(struct iguana_info *coin,int32_t rwflag,cJSON *json,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,bits256 *txidp,char *vpnstr) -{ - int32_t i,len = 0; uint8_t *txstart = serialized; char txidstr[65]; cJSON *array=0; - len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->version),&msg->version); - if ( json != 0 ) - { - jaddnum(json,"version",msg->version); - array = cJSON_CreateArray(); - } - if ( coin->chain->hastimestamp != 0 ) - { - len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->timestamp),&msg->timestamp); - //printf("timestamp.%08x %u %s\n",msg->timestamp,msg->timestamp,utc_str(str,msg->timestamp)); - if ( json != 0 ) - jaddnum(json,"timestamp",msg->timestamp); - } - len += iguana_rwvarint32(rwflag,&serialized[len],&msg->tx_in); - if ( rwflag == 0 ) - { - if ( len + sizeof(struct iguana_msgvin)*msg->tx_in > maxsize ) - return(-1); - maxsize -= (sizeof(struct iguana_msgvin) * msg->tx_in); - msg->vins = (struct iguana_msgvin *)&serialized[maxsize]; - } - //printf("tx_in.%08x\n",msg->tx_in); - if ( msg->tx_in > 0 && msg->tx_in*sizeof(struct iguana_msgvin) < maxsize ) - { - for (i=0; itx_in; i++) - { - len += iguana_vinparse(coin,rwflag,&serialized[len],&msg->vins[i]); - if ( array != 0 ) - jaddi(array,iguana_vinjson(coin,&msg->vins[i])); - } - } - else - { - printf("invalid tx_in.%d\n",msg->tx_in); - return(-1); - } - if ( array != 0 ) - { - jadd(json,"vin",array); - jaddnum(json,"numvins",msg->tx_in); - array = cJSON_CreateArray(); - } - len += iguana_rwvarint32(rwflag,&serialized[len],&msg->tx_out); - if ( rwflag == 0 ) - { - if ( len + sizeof(struct iguana_msgvout)*msg->tx_out > maxsize ) - return(-1); - maxsize -= (sizeof(struct iguana_msgvout) * msg->tx_out); - msg->vouts = (struct iguana_msgvout *)&serialized[maxsize]; - } - if ( msg->tx_out > 0 && msg->tx_out*sizeof(struct iguana_msgvout) < maxsize ) - { - for (i=0; itx_out; i++) - { - len += iguana_voutparse(rwflag,&serialized[len],&msg->vouts[i]); - if ( array != 0 ) - jaddi(array,iguana_voutjson(coin,&msg->vouts[i],i,*txidp)); - } - } - else - { - printf("invalid tx_out.%d\n",msg->tx_out); - return(-1); - } - if ( array != 0 ) - { - jadd(json,"vout",array); - jaddnum(json,"numvouts",msg->tx_out); - } - len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->lock_time),&msg->lock_time); - //printf("lock_time.%08x\n",msg->lock_time); - if ( strcmp(coin->symbol,"VPN") == 0 ) - { - uint16_t ddosflag = 0; - len += iguana_rwnum(rwflag,&serialized[len],sizeof(ddosflag),&ddosflag); - for (i=0; serialized[len]!=0&&lenlock_time); - jaddnum(json,"size",len); - jaddbits256(json,"txid",*txidp); - //printf("TX.(%s) %p\n",jprint(json,0),json); - } - msg->allocsize = len; - return(len); -} - -bits256 iguana_parsetxobj(struct iguana_info *coin,int32_t *txstartp,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,cJSON *txobj) // json -> serialized + (msg,V) -{ - int32_t i,numvins,numvouts,len = 0; cJSON *array=0; bits256 txid; char vpnstr[64]; - memset(msg,0,sizeof(*msg)); - vpnstr[0] = 0; - msg->version = juint(txobj,"version"); - if ( coin->chain->hastimestamp != 0 ) - msg->timestamp = juint(txobj,"timestamp"); - if ( (array= jarray(&numvins,txobj,"vin")) != 0 ) - { - msg->tx_in = numvins; - if ( len + sizeof(struct iguana_msgvin)*msg->tx_in > maxsize ) - return(msg->txid); - maxsize -= (sizeof(struct iguana_msgvin) * msg->tx_in); - msg->vins = (struct iguana_msgvin *)&serialized[maxsize]; - if ( msg->tx_in > 0 && msg->tx_in*sizeof(struct iguana_msgvin) < maxsize ) - { - for (i=0; itx_in; i++) - len += iguana_parsevinobj(coin,&serialized[len],maxsize,&msg->vins[i],jitem(array,i)); } } - if ( (array= jarray(&numvouts,txobj,"vout")) != 0 ) - { - msg->tx_out = numvouts; - if ( len + sizeof(struct iguana_msgvout)*msg->tx_out > maxsize ) - return(msg->txid); - maxsize -= (sizeof(struct iguana_msgvout) * msg->tx_out); - msg->vouts = (struct iguana_msgvout *)&serialized[maxsize]; - if ( msg->tx_out > 0 && msg->tx_out*sizeof(struct iguana_msgvout) < maxsize ) - { - for (i=0; itx_out; i++) - len += iguana_parsevoutobj(coin,&serialized[len],maxsize,&msg->vouts[i],jitem(array,i)); - } - } - msg->lock_time = juint(txobj,"locktime"); - msg->txid = jbits256(txobj,"txid"); - *txstartp = len; - msg->allocsize = iguana_rwmsgtx(coin,1,0,&serialized[len],maxsize-len,msg,&txid,vpnstr); - //char str[65]; printf("json -> %s\n",bits256_str(str,txid)); - return(txid); -} - -char *iguana_rawtxbytes(struct iguana_info *coin,cJSON *json,struct iguana_msgtx *msgtx) -{ - int32_t n; char *txbytes = 0,vpnstr[64]; uint8_t *serialized; - serialized = malloc(IGUANA_MAXPACKETSIZE); - vpnstr[0] = 0; - //char str[65]; printf("%d of %d: %s\n",i,msg.txn_count,bits256_str(str,tx.txid)); - if ( (n= iguana_rwmsgtx(coin,1,json,serialized,IGUANA_MAXPACKETSIZE,msgtx,&msgtx->txid,vpnstr)) > 0 ) - { - txbytes = malloc(n*2+1); - init_hexbytes_noT(txbytes,serialized,n); - } - free(serialized); - return(txbytes); -} - -/* - struct vin_signer { bits256 privkey; uint8_t siglen,sig[80],rmd160[20],pubkey[66]; }; - - struct vin_info - { - struct iguana_msgvin vin; - int32_t M,N,validmask,spendlen,p2shflag; - struct vin_signer signers[16]; - uint8_t rmd160[20],spendscript[IGUANA_MAXSCRIPTSIZE]; - }; - */ - -int32_t bitcoin_scriptget(struct iguana_info *coin,int32_t *hashtypep,struct vin_info *vp,uint8_t *scriptsig,int32_t len,int32_t type) -{ - char asmstr[IGUANA_MAXSCRIPTSIZE*3]; int32_t j,n,siglen,plen; uint8_t sha256[32]; - j = n = 0; - *hashtypep = SIGHASH_ALL; - while ( (siglen= scriptsig[n]) >= 70 && siglen <= 73 && n+siglen+1 < len && j < 16 ) - { - vp->signers[j].siglen = siglen; - memcpy(vp->signers[j].sig,&scriptsig[n+1],siglen); - if ( j == 0 ) - *hashtypep = vp->signers[j].sig[siglen-1]; - n += (siglen + 1); - j++; - if ( type == 0 && j > 1 ) - type = IGUANA_SCRIPT_MSIG; - } - vp->type = type; - j = 0; - while ( ((plen= scriptsig[n]) == 33 || plen == 65 ) && j < 16 ) - { - memcpy(vp->signers[j].pubkey,&scriptsig[n+1],plen); - vcalc_sha256(0,sha256,vp->signers[j].pubkey,plen); - calc_rmd160(0,vp->signers[j].rmd160,sha256,sizeof(sha256)); - if ( j == 0 ) - memcpy(vp->rmd160,vp->signers[j].rmd160,20); - n += (plen + 1); - j++; - } - if ( n < len && (scriptsig[n] == 0x4c || scriptsig[n] == 0x4d) ) - { - if ( scriptsig[n] == 0x4c ) - vp->p2shlen = scriptsig[n+1], n += 2; - else vp->p2shlen = ((uint32_t)scriptsig[n+1] + ((uint32_t)scriptsig[n+2] << 8)), n += 3; - memcpy(vp->p2shscript,&scriptsig[n],vp->p2shlen); - vp->type = IGUANA_SCRIPT_P2SH; - } - /*if ( len == 0 ) - { - // txid.(eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2).v1 - decode_hex(vp->rmd160,20,"010966776006953d5567439e5e39f86a0d273bee");//3564a74f9ddb4372301c49154605573d7d1a88fe"); - vp->type = IGUANA_SCRIPT_76A988AC; - }*/ - vp->spendlen = iguana_scriptgen(coin,&vp->M,&vp->N,vp->coinaddr,vp->spendscript,asmstr,vp->rmd160,vp->type,(const struct vin_info *)vp,vp->vin.prev_vout); - //printf("type.%d asmstr.(%s) spendlen.%d\n",vp->type,asmstr,vp->spendlen); - return(vp->spendlen); + if ( (vin= (abovevin != 0) ? abovevin : belowvin) == 0 && mode == 1 ) + vin = unspents; + return(vin); } -int32_t bitcoin_verifyvins(struct iguana_info *coin,bits256 *signedtxidp,char **signedtx,int32_t *scriptlens,struct iguana_msgtx *msgtx,uint8_t *serialized,int32_t maxsize,struct vin_info *V) +struct bitcoin_spend *iguana_spendset(struct supernet_info *myinfo,struct iguana_info *coin,int64_t amount,int64_t txfee,char *account) { - bits256 txid,sigtxid,revsigtxid; char txidstr[128],bigstr[2560],coinaddr[64],vpnstr[64],str[65]; - uint8_t *sig,*pubkey,*saveinput; struct vin_info *vp; - int32_t n2,i,j,k,plen,vini=0,flag,numvins,hashtype,retval,siglen,asmtype; - vpnstr[0] = 0; - *signedtx = 0; - memset(signedtxidp,0,sizeof(*signedtxidp)); - numvins = msgtx->tx_in; - retval = -numvins; - for (vini=0; vinivins[vini].script; - vp = &V[vini]; - for (i=0; ivins[i].scriptlen = 0; - sig = &msgtx->vins[vini].script[1]; - siglen = msgtx->vins[vini].script[0] - 1; - vp->vin = msgtx->vins[vini]; - flag = 0; - for (k=0; k<2; k++) + int32_t i,mode,numunspents,maxinputs = 1024; struct bitcoin_unspent *ptr,*up; + struct bitcoin_unspent *ups; struct bitcoin_spend *spend; double balance; int64_t remains,smallest = 0; + if ( (ups= iguana_unspentsget(myinfo,coin,0,&balance,&numunspents,coin->chain->minconfirms,account)) == 0 ) + return(0); + spend = calloc(1,sizeof(*spend) + sizeof(*spend->inputs) * maxinputs); + spend->txfee = txfee; + remains = txfee + amount; + spend->satoshis = remains; + ptr = spend->inputs; + for (i=0; i=0; mode--) + if ( (up= iguana_bestfit(coin,ups,numunspents,remains,mode)) != 0 ) + break; + if ( up != 0 ) { - asmtype = (k == 0) ? IGUANA_SCRIPT_76A988AC : IGUANA_SCRIPT_76AC; - if ( bitcoin_scriptget(coin,&hashtype,vp,saveinput,scriptlens[vini],asmtype) < 0 ) + if ( smallest == 0 || up->value < smallest ) { - printf("cant get script for (%s).v%d\n",bits256_str(str,vp->vin.prev_hash),vp->vin.prev_vout); - continue; + smallest = up->value; + memcpy(spend->change160,up->rmd160,sizeof(spend->change160)); } - msgtx->vins[vini].script = vp->spendscript; - msgtx->vins[vini].scriptlen = vp->spendlen; - for (j=0; jN; j++) + spend->input_satoshis += up->value; + spend->inputs[spend->numinputs++] = *up; + if ( spend->input_satoshis >= spend->satoshis ) { - pubkey = vp->signers[j].pubkey; - if ( (plen= bitcoin_pubkeylen(pubkey)) < 0 ) - { - printf("illegal plen.%d [%02x]\n",plen,pubkey[0]); - break; - } - bitcoin_address(coinaddr,coin->chain->pubtype,pubkey,plen); - n2 = iguana_rwmsgtx(coin,1,0,serialized,maxsize,msgtx,&txid,vpnstr); - msgtx->vins[vini].script = saveinput; - if ( n2 > 0 ) - { - n2 += iguana_rwnum(1,&serialized[n2],sizeof(hashtype),&hashtype); - revsigtxid = bits256_doublesha256(txidstr,serialized,n2); - for (i=0; isigners[j].privkey) != 0 ) - { - vp->signers[j].siglen = bitcoin_sign(vp->signers[j].sig,sizeof(vp->signers[j].sig),sigtxid.bytes,sizeof(sigtxid),vp->signers[j].privkey); - sig = vp->signers[j].sig; - siglen = vp->signers[j].siglen; - msgtx->vins[vini].scriptlen = bitcoin_scriptsig(msgtx->vins[vini].script,0,(const struct vin_info *)vp); - printf("SIGNEDTX plen.%d siglen.%d\n",plen,siglen); - } - if ( bitcoin_verify(sig,siglen,sigtxid.bytes,sizeof(sigtxid),0,vp->signers[j].pubkey,bitcoin_pubkeylen(vp->signers[j].pubkey)) < 0 ) - { - init_hexbytes_noT(bigstr,serialized,n2); - printf("(%s) doesnt verify hash2.%s\n",bigstr,bits256_str(str,sigtxid)); - } - else - { - printf("SIG.%d VERIFIED\n",vini); - *signedtx = iguana_rawtxbytes(coin,0,msgtx); - *signedtxidp = msgtx->txid; - flag = 1; - break; - } - } else printf("bitcoin_verifyvins: vini.%d n2.%d\n",vini,n2); - } - if ( flag > 0 ) - { - retval++; + // numinputs 1 -> (1.00074485 - spend 0.41030880) = net 0.59043605 vs amount 0.40030880 change 0.40030880 -> txfee 0.01000000 vs chainfee 0.01000000 + spend->change = (spend->input_satoshis - spend->satoshis) - txfee; + printf("numinputs %d -> (%.8f - spend %.8f) = change %.8f -> txfee %.8f vs chainfee %.8f\n",spend->numinputs,dstr(spend->input_satoshis),dstr(spend->satoshis),dstr(spend->change),dstr(spend->input_satoshis - spend->change - spend->satoshis),dstr(txfee)); break; } - if ( vp->type != IGUANA_SCRIPT_76A988AC && vp->type != IGUANA_SCRIPT_76AC ) - break; - } + remains -= up->value; + } else break; } - return(retval); -} - -//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"; - -int32_t bitcoin_verifytx(struct iguana_info *coin,bits256 *signedtxidp,char **signedtx,char *rawtxstr,struct vin_info *V) -{ - int32_t i,len,maxsize,*scriptlens,numvins,retval = -1; uint8_t *serialized,*serialized2; - struct iguana_msgtx msgtx; bits256 txid; char vpnstr[64]; - len = (int32_t)strlen(rawtxstr); - maxsize = len + 32768; - serialized = calloc(1,maxsize); - serialized2 = calloc(1,maxsize); - len >>= 1; - vpnstr[0] = 0; - decode_hex(serialized,len,rawtxstr); - memset(&msgtx,0,sizeof(msgtx)); - if ( iguana_rwmsgtx(coin,0,0,serialized,maxsize,&msgtx,&txid,vpnstr) > 0 ) - { - numvins = msgtx.tx_in; - scriptlens = calloc(numvins,sizeof(*scriptlens)); - for (i=0; iinput_satoshis >= spend->satoshis ) { - txbytes = malloc(msgtx.allocsize*2 + 1); - init_hexbytes_noT(txbytes,&serialized[txstart],msgtx.allocsize); - } else printf("bitcoin_txtest: zero msgtx allocsize\n"); - free(serialized); - return(txbytes); -} - -cJSON *bitcoin_createtx(struct iguana_info *coin,int32_t locktime) -{ - cJSON *json = cJSON_CreateObject(); - if ( locktime == 0 ) - { - jaddnum(json,"version",1); - jaddnum(json,"locktime",0); + spend = realloc(spend,sizeof(*spend) + sizeof(*spend->inputs) * spend->numinputs); + return(spend); } else { - jaddnum(json,"version",4); - jaddnum(json,"locktime",locktime); - } - if ( coin->chain->hastimestamp != 0 ) - jaddnum(json,"timestamp",time(NULL)); - jadd(json,"vin",cJSON_CreateArray()); - jadd(json,"vout",cJSON_CreateArray()); - return(json); -} - -cJSON *bitcoin_addoutput(struct iguana_info *coin,cJSON *txobj,uint8_t *paymentscript,int32_t len,uint64_t satoshis) -{ - char *hexstr; cJSON *item,*skey,*vouts = jduplicate(jobj(txobj,"vout")); - item = cJSON_CreateObject(); - jaddnum(item,"value",dstr(satoshis)); - skey = cJSON_CreateObject(); - hexstr = malloc(len*2 + 1); - init_hexbytes_noT(hexstr,paymentscript,len); - jaddstr(skey,"hex",hexstr); - free(hexstr); - jadd(item,"scriptPubkey",skey); - jdelete(vouts,"vout"); - jadd(vouts,"vout",item); - return(txobj); -} - -cJSON *bitcoin_addinput(struct iguana_info *coin,cJSON *txobj,bits256 txid,int32_t vout,uint32_t sequence) -{ - cJSON *item,*vins = jduplicate(jobj(txobj,"vin")); - item = cJSON_CreateObject(); - jaddbits256(item,"txid",txid); - jaddnum(item,"vout",vout); - jaddnum(item,"sequence",sequence); - jdelete(vins,"vin"); - jadd(vins,"vin",item); - return(txobj); -} - -char *bitcoin_cltvtx(struct iguana_info *coin,char *changeaddr,char *senderaddr,char *senders_otheraddr,char *otheraddr,uint32_t locktime,uint64_t satoshis,bits256 txid,int32_t vout,uint64_t inputsatoshis,bits256 privkey) -{ - uint64_t change; char *rawtxstr,*signedtx; struct vin_info V; bits256 cltxid,signedtxid; - int32_t cltvlen,len; uint32_t timestamp; char ps2h_coinaddr[65]; cJSON *txobj; - uint8_t p2sh_rmd160[20],cltvscript[1024],paymentscript[64],rmd160[20],secret160[20],addrtype; - timestamp = (uint32_t)time(NULL); - bitcoin_addr2rmd160(&addrtype,secret160,senders_otheraddr); - cltvlen = bitcoin_cltvscript(coin->chain->p2shtype,ps2h_coinaddr,p2sh_rmd160,cltvscript,0,senderaddr,otheraddr,secret160,locktime); - txobj = bitcoin_createtx(coin,locktime); - len = bitcoin_p2shspend(paymentscript,0,p2sh_rmd160); - bitcoin_addoutput(coin,txobj,paymentscript,len,satoshis); - bitcoin_addinput(coin,txobj,txid,vout,locktime); - if ( inputsatoshis > (satoshis + 10000) ) - { - change = inputsatoshis - (satoshis + 10000); - if ( changeaddr != 0 && changeaddr[0] != 0 ) - { - bitcoin_addr2rmd160(&addrtype,rmd160,changeaddr); - if ( addrtype == coin->chain->pubtype ) - len = bitcoin_standardspend(paymentscript,0,rmd160); - else if ( addrtype == coin->chain->p2shtype ) - len = bitcoin_standardspend(paymentscript,0,rmd160); - else - { - printf("error with mismatched addrtype.%02x vs (%02x %02x)\n",addrtype,coin->chain->pubtype,coin->chain->p2shtype); - return(0); - } - bitcoin_addoutput(coin,txobj,paymentscript,len,change); - } - else - { - printf("error no change address when there is change\n"); - return(0); - } - } - rawtxstr = bitcoin_json2hex(coin,&cltxid,txobj); - char str[65]; printf("CLTV.%s (%s)\n",bits256_str(str,cltxid),rawtxstr); - memset(&V,0,sizeof(V)); - V.signers[0].privkey = privkey; - bitcoin_verifytx(coin,&signedtxid,&signedtx,rawtxstr,&V); - free(rawtxstr); - if ( signedtx != 0 ) - printf("signed CLTV.%s (%s)\n",bits256_str(str,signedtxid),signedtx); - else printf("error generating signedtx\n"); - free_json(txobj); - return(signedtx); -} - -cJSON *bitcoin_txtest(struct iguana_info *coin,char *rawtxstr,bits256 txid) -{ - struct iguana_msgtx msgtx; char str[65],str2[65]; bits256 checktxid,blockhash,signedtxid; - cJSON *retjson,*txjson; uint8_t *serialized,*serialized2; struct iguana_txid T,*tp; - struct vin_info *V; char vpnstr[64],*txbytes,*signedtx; int32_t n,txstart,height,n2,maxsize,len; - len = (int32_t)strlen(rawtxstr); -rawtxstr = refstr; - maxsize = len + 32768; - serialized = calloc(1,maxsize); - serialized2 = calloc(1,maxsize); - len >>= 1; - V = 0; - vpnstr[0] = 0; - memset(&msgtx,0,sizeof(msgtx)); - - if ( len < maxsize ) - { - decode_hex(serialized,len,rawtxstr); - txjson = cJSON_CreateObject(); - retjson = cJSON_CreateObject(); - if ( (n= iguana_rwmsgtx(coin,0,txjson,serialized,maxsize,&msgtx,&txid,vpnstr)) < 0 ) - { - printf("bitcoin_txtest len.%d: n.%d from (%s)\n",len,n,rawtxstr); - free(serialized), free(serialized2); - return(cJSON_Parse("{\"error\":\"cant parse txbytes\"}")); - } - V = calloc(msgtx.tx_in,sizeof(*V)); - { - //char *pstr; int32_t plen; - decode_hex(V[0].signers[0].privkey.bytes,sizeof(V[0].signers[0].privkey),"18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725"); - //pstr = "0450863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b23522cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6"; - //plen = (int32_t)strlen(pstr); - //decode_hex(V[0].signers[0].pubkey,plen,pstr); - } - if ( bitcoin_verifytx(coin,&signedtxid,&signedtx,rawtxstr,V) != 0 ) - printf("bitcoin_verifytx error\n"); - jadd(retjson,"result",txjson); - if ( (tp= iguana_txidfind(coin,&height,&T,txid)) != 0 ) - { - if ( height >= 0 ) - { - blockhash = iguana_blockhash(coin,height); - jaddnum(retjson,"height",height); - jaddnum(retjson,"confirmations",coin->longestchain - height); - jaddbits256(retjson,"blockhash",blockhash); - } - } - //printf("retjson.(%s) %p\n",jprint(retjson,0),retjson); - memset(checktxid.bytes,0,sizeof(checktxid)); - if ( (n2= iguana_rwmsgtx(coin,1,0,serialized2,maxsize,&msgtx,&checktxid,vpnstr)) < 0 || n != n2 ) - { - printf("bitcoin_txtest: n.%d vs n2.%d\n",n,n2); - free(serialized), free(serialized2), free(V); - return(retjson); - } - if ( bits256_cmp(checktxid,txid) != 0 ) - { - printf("bitcoin_txtest: txid.%s vs check.%s\n",bits256_str(str,txid),bits256_str(str2,checktxid)); - } - checktxid = iguana_parsetxobj(coin,&txstart,serialized,maxsize,&msgtx,jobj(retjson,"result")); - if ( bits256_cmp(checktxid,txid) != 0 ) - { - printf("bitcoin_txtest: txid.%s vs check2.%s\n",bits256_str(str,txid),bits256_str(str2,checktxid)); - } - if ( msgtx.allocsize != 0 ) - { - txbytes = malloc(msgtx.allocsize*2 + 1); - init_hexbytes_noT(txbytes,&serialized[txstart],msgtx.allocsize); - if ( strcmp(txbytes,rawtxstr) != 0 ) - printf("bitcoin_txtest: reconstruction error: %s != %s\n",rawtxstr,txbytes); - else printf("reconstruction PASSED\n"); - free(txbytes); - } else printf("bitcoin_txtest: zero msgtx allocsize\n"); - free(serialized), free(serialized2), free(V); - return(retjson); + free(spend); + return(0); } - free(serialized), free(serialized2); - return(cJSON_Parse("{\"error\":\"testing bitcoin txbytes\"}")); } #define EXCHANGE_NAME "bitcoin" @@ -1440,7 +342,8 @@ double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchang cJSON *retjson,*bids,*asks; double hbla; bids = cJSON_CreateArray(); asks = cJSON_CreateArray(); - instantdex_acceptablefind(exchange,bids,asks,0,base,rel); + instantdex_offerfind(SuperNET_MYINFO(0),exchange,bids,asks,0,base,rel,1); + //printf("bids.(%s) asks.(%s)\n",jprint(bids,0),jprint(asks,0)); retjson = cJSON_CreateObject(); cJSON_AddItemToObject(retjson,"bids",bids); cJSON_AddItemToObject(retjson,"asks",asks); @@ -1451,12 +354,49 @@ double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchang char *PARSEBALANCE(struct exchange_info *exchange,double *balancep,char *coinstr,cJSON *argjson) { - return(clonestr("{\"error\":\"bitcoin is not yet\"}")); + cJSON *item; + *balancep = 0; + if ( (item= jobj(argjson,coinstr)) != 0 ) + { + *balancep = jdouble(item,"balance"); + return(jprint(item,0)); + } + return(clonestr("{\"error\":\"no item for specified coin\"}")); } cJSON *BALANCES(struct exchange_info *exchange,cJSON *argjson) { - return(cJSON_Parse("{\"error\":\"bitcoin is not yet\"}")); + double balance; char *retstr; int32_t i,numunspents,minconfirms; struct iguana_info *coin; + struct supernet_info *myinfo; struct bitcoin_unspent *unspents; cJSON *item,*retjson,*utxo; + retjson = cJSON_CreateArray(); + myinfo = SuperNET_accountfind(argjson); + for (i=0; ichain->serverport[0] != 0 ) + { + balance = 0.; + minconfirms = juint(argjson,"minconfirms"); + if ( minconfirms < coin->minconfirms ) + minconfirms = coin->minconfirms; + if ( (unspents= iguana_unspentsget(myinfo,coin,&retstr,&balance,&numunspents,minconfirms,0)) != 0 ) + { + item = cJSON_CreateObject(); + jaddnum(retjson,"balance",balance); + if ( retstr != 0 ) + { + if ( (utxo= cJSON_Parse(retstr)) != 0 ) + { + jadd(item,"unspents",utxo); + jaddnum(item,"numunspents",numunspents); + } + free(retstr); + } + free(unspents); + jadd(retjson,coin->symbol,item); + } + } + } + return(retjson); } int32_t is_valid_BTCother(char *other) @@ -1472,9 +412,13 @@ int32_t is_valid_BTCother(char *other) 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) { - struct instantdex_accept *ap; char *str,coinaddr[64]; uint64_t txid = 0; cJSON *json; - struct supernet_info *myinfo; uint8_t pubkey[33]; struct iguana_info *other; int32_t hops = 3; - myinfo = SuperNET_MYINFO(0); + char *str,*retstr,coinaddr[64]; uint64_t txid = 0; cJSON *json=0; + struct instantdex_accept *ap; + struct supernet_info *myinfo; uint8_t pubkey[33]; struct iguana_info *other; + myinfo = SuperNET_accountfind(argjson); + //printf("TRADE with myinfo.%p\n",myinfo); + if ( retstrp != 0 ) + *retstrp = 0; if ( strcmp(base,"BTC") == 0 || strcmp(base,"btc") == 0 ) { base = rel; @@ -1485,54 +429,38 @@ uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,cha } if ( is_valid_BTCother(base) != 0 && (strcmp(rel,"BTC") == 0 || strcmp(rel,"btc") == 0) ) { - ap = 0;//instantdex_acceptable(exchange,base,rel,"BTC",dir,price,volume); if ( dotrade == 0 ) { if ( retstrp != 0 ) - { - if ( ap != 0 ) - *retstrp = jprint(instantdex_acceptjson(ap),1); - else *retstrp = clonestr("{\"result\":\"would issue new trade\"}"); - } + *retstrp = clonestr("{\"result\":\"would issue new trade\"}"); } else { - if ( ap != 0 ) + if ( (other= iguana_coinfind(base)) != 0 ) { - // issue matching response + bitcoin_pubkey33(0,pubkey,myinfo->persistent_priv); + bitcoin_address(coinaddr,other->chain->pubtype,pubkey,sizeof(pubkey)); + jaddstr(argjson,base,coinaddr); } - else if ( dir < 0 ) + else if ( strcmp(base,"NXT") == 0 || (is_decimalstr(base) > 0 && strlen(base) > 13) ) { - printf("bitcoin sell is not yet\n"); + printf("NXT is not yet\n"); return(0); } - else - { - json = cJSON_CreateObject(); - jaddstr(json,"base",base); - jaddstr(json,"rel","BTC"); - jaddnum(json,"maxprice",price); - jaddnum(json,"volume",volume); - if ( (other= iguana_coinfind(base)) != 0 ) - { - bitcoin_pubkey33(pubkey,myinfo->persistent_priv); - bitcoin_address(coinaddr,other->chain->pubtype,pubkey,sizeof(pubkey)); - jaddstr(argjson,base,coinaddr); - } - jaddstr(json,"BTC",myinfo->myaddr.BTC); - if ( (str= instantdex_sendcmd(myinfo,json,"BTCoffer",myinfo->ipaddr,hops)) != 0 ) - free(str); - free_json(json); - if ( (str= instantdex_queueaccept(exchange,base,"BTC",price,volume,-1,"BTC",INSTANTDEX_OFFERDURATION)) != 0 ) - { - if ( (json= cJSON_Parse(str)) != 0 ) - { - txid = j64bits(json,"orderid"); - free_json(json); - } - free(str); - } - } + else return(0); + json = cJSON_CreateObject(); + jaddstr(json,"base",base); + jaddstr(json,"rel","BTC"); + jaddnum(json,dir > 0 ? "maxprice" : "minprice",price); + jaddnum(json,"volume",volume); + jaddstr(json,"BTC",myinfo->myaddr.BTC); + jaddnum(json,"minperc",jdouble(argjson,"minperc")); + //printf("trade dir.%d (%s/%s) %.6f vol %.8f\n",dir,base,"BTC",price,volume); + if ( (str= instantdex_createaccept(myinfo,&ap,exchange,base,"BTC",price,volume,-dir,dir > 0 ? "BTC" : base,INSTANTDEX_OFFERDURATION,myinfo->myaddr.nxt64bits,0,jdouble(argjson,"minperc"))) != 0 && ap != 0 ) + retstr = instantdex_checkoffer(myinfo,&txid,exchange,ap,json), free(str); + else printf("null return queueaccept\n"); + if ( retstrp != 0 ) + *retstrp = retstr; } } return(txid); @@ -1540,34 +468,44 @@ uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,cha char *ORDERSTATUS(struct exchange_info *exchange,uint64_t orderid,cJSON *argjson) { - struct instantdex_accept *ap; cJSON *retjson; - if ( (ap= instantdex_acceptablefind(exchange,0,0,orderid,"*","*")) != 0 ) - { - retjson = cJSON_CreateObject(); + struct instantdex_accept *ap; struct bitcoin_swapinfo *swap; cJSON *retjson; + retjson = cJSON_CreateObject(); + struct supernet_info *myinfo = SuperNET_accountfind(argjson); + if ( (swap= instantdex_statemachinefind(myinfo,exchange,orderid,1)) != 0 ) + jadd(retjson,"result",instantdex_statemachinejson(swap)); + else if ( (ap= instantdex_offerfind(myinfo,exchange,0,0,orderid,"*","*",1)) != 0 ) jadd(retjson,"result",instantdex_acceptjson(ap)); - return(jprint(retjson,1)); - } else return(clonestr("{\"error\":\"couldnt find orderid\"}")); + else if ( (swap= instantdex_historyfind(myinfo,exchange,orderid)) != 0 ) + jadd(retjson,"result",instantdex_historyjson(swap)); + else jaddstr(retjson,"error","couldnt find orderid"); + return(jprint(retjson,1)); } char *CANCELORDER(struct exchange_info *exchange,uint64_t orderid,cJSON *argjson) { - struct instantdex_accept *ap; cJSON *retjson; - if ( (ap= instantdex_acceptablefind(exchange,0,0,orderid,"*","*")) != 0 ) + struct instantdex_accept *ap = 0; cJSON *retjson; struct bitcoin_swapinfo *swap=0; + struct supernet_info *myinfo = SuperNET_accountfind(argjson); + retjson = cJSON_CreateObject(); + if ( (ap= instantdex_offerfind(myinfo,exchange,0,0,orderid,"*","*",1)) != 0 ) { ap->dead = (uint32_t)time(NULL); - retjson = cJSON_CreateObject(); + jadd(retjson,"orderid",instantdex_acceptjson(ap)); jaddstr(retjson,"result","killed orderid, but might have pending"); - jadd(retjson,"order",instantdex_acceptjson(ap)); - return(jprint(retjson,1)); - } else return(clonestr("{\"error\":\"couldnt find orderid\"}")); + } + else if ( (swap= instantdex_statemachinefind(myinfo,exchange,orderid,1)) != 0 ) + { + jadd(retjson,"orderid",instantdex_statemachinejson(swap)); + jaddstr(retjson,"result","killed statemachine orderid, but might have pending"); + } + return(jprint(retjson,1)); } char *OPENORDERS(struct exchange_info *exchange,cJSON *argjson) { - cJSON *retjson,*bids,*asks; + cJSON *retjson,*bids,*asks; struct supernet_info *myinfo = SuperNET_accountfind(argjson); bids = cJSON_CreateArray(); asks = cJSON_CreateArray(); - instantdex_acceptablefind(exchange,bids,asks,0,"*","*"); + instantdex_offerfind(myinfo,exchange,bids,asks,0,"*","*",1); retjson = cJSON_CreateObject(); jaddstr(retjson,"result","success"); jadd(retjson,"bids",bids); @@ -1577,14 +515,25 @@ char *OPENORDERS(struct exchange_info *exchange,cJSON *argjson) char *TRADEHISTORY(struct exchange_info *exchange,cJSON *argjson) { - return(clonestr("{\"error\":\"bitcoin is not yet\"}")); + struct bitcoin_swapinfo PAD,*swap; cJSON *retjson = cJSON_CreateArray(); + memset(&PAD,0,sizeof(PAD)); + queue_enqueue("historyQ",&exchange->historyQ,&PAD.DL,0); + while ( (swap= queue_dequeue(&exchange->historyQ,0)) != 0 && swap != &PAD ) + { + jaddi(retjson,instantdex_historyjson(swap)); + queue_enqueue("historyQ",&exchange->historyQ,&swap->DL,0); + } + return(jprint(retjson,1)); } char *WITHDRAW(struct exchange_info *exchange,char *base,double amount,char *destaddr,cJSON *argjson) { - return(clonestr("{\"error\":\"bitcoin is not yet\"}")); + //struct supernet_info *myinfo = SuperNET_accountfind(argjson); + // invoke conversion or transfer! + return(clonestr("{\"error\":\"what does it mean to withdraw bitcoins that are in your wallet\"}")); } struct exchange_funcs bitcoin_funcs = EXCHANGE_FUNCS(bitcoin,EXCHANGE_NAME); #include "exchange_undefs.h" + diff --git a/iguana/exchanges/bitcoin.h b/iguana/exchanges/bitcoin.h index 7d46eb4f7..42e1b6902 100755 --- a/iguana/exchanges/bitcoin.h +++ b/iguana/exchanges/bitcoin.h @@ -16,10 +16,6 @@ #ifndef H_BITCOIN_H #define H_BITCOIN_H -#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 @@ -34,33 +30,55 @@ #define SCRIPT_OP_RETURN 0x6a #define SCRIPT_OP_DUP 0x76 #define SCRIPT_OP_ENDIF 0x68 -#define OP_DROP 0x75 +#define SCRIPT_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 +#define SCRIPT_OP_CHECKSEQUENCEVERIFY 0xb2 +#define SCRIPT_OP_CHECKLOCKTIMEVERIFY 0xb1 + +#define IGUANA_SCRIPT_NULL 0 +#define IGUANA_SCRIPT_76AC 1 +#define IGUANA_SCRIPT_76A988AC 2 +#define IGUANA_SCRIPT_P2SH 3 +#define IGUANA_SCRIPT_OPRETURN 4 +#define IGUANA_SCRIPT_3of3 5 +#define IGUANA_SCRIPT_2of3 6 +#define IGUANA_SCRIPT_1of3 7 +#define IGUANA_SCRIPT_2of2 8 +#define IGUANA_SCRIPT_1of2 9 +#define IGUANA_SCRIPT_MSIG 10 +#define IGUANA_SCRIPT_DATA 11 +#define IGUANA_SCRIPT_AC 12 +#define IGUANA_SCRIPT_1of1 13 +#define IGUANA_SCRIPT_STRANGE 15 -struct bp_key { EC_KEY *k; }; +#define IGUANA_MAXSCRIPTSIZE 10001 int32_t bitcoin_validaddress(struct iguana_info *coin,char *coinaddr); int32_t bitcoin_cltvscript(uint8_t p2shtype,char *ps2h_coinaddr,uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,char *senderaddr,char *otheraddr,uint8_t secret160[20],uint32_t locktime); int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr); char *bitcoin_cltvtx(struct iguana_info *coin,char *changeaddr,char *senderaddr,char *senders_otheraddr,char *otheraddr,uint32_t locktime,uint64_t satoshis,bits256 txid,int32_t vout,uint64_t inputsatoshis,bits256 privkey); int32_t bitcoin_MofNspendscript(uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,const struct vin_info *vp); -cJSON *bitcoin_createtx(struct iguana_info *coin,int32_t locktime); -cJSON *bitcoin_addoutput(struct iguana_info *coin,cJSON *txobj,uint8_t *paymentscript,int32_t len,uint64_t satoshis); -int32_t bitcoin_changescript(struct iguana_info *coin,uint8_t *changescript,int32_t n,uint64_t *changep,char *changeaddr,uint64_t inputsatoshis,uint64_t satoshis,uint64_t txfee); -cJSON *bitcoin_addinput(struct iguana_info *coin,cJSON *txobj,bits256 txid,int32_t vout,uint32_t sequence); -int32_t bitcoin_verifytx(struct iguana_info *coin,bits256 *signedtxidp,char **signedtx,char *rawtxstr,struct vin_info *V); -char *bitcoin_json2hex(struct iguana_info *coin,bits256 *txidp,cJSON *txjson); int32_t bitcoin_pubkeyspend(uint8_t *script,int32_t n,uint8_t pubkey[66]); int32_t bitcoin_p2shspend(uint8_t *script,int32_t n,uint8_t rmd160[20]); int32_t bitcoin_revealsecret160(uint8_t *script,int32_t n,uint8_t secret160[20]); int32_t bitcoin_standardspend(uint8_t *script,int32_t n,uint8_t rmd160[20]); +int32_t bitcoin_pubkeylen(const uint8_t *pubkey); +int32_t bitcoin_scriptget(struct iguana_info *coin,int32_t *hashtypep,uint32_t *sigsizep,uint32_t *pubkeysizep,uint32_t *suffixp,struct vin_info *vp,uint8_t *scriptsig,int32_t len,int32_t spendtype); +int32_t iguana_expandscript(struct iguana_info *coin,char *asmstr,int32_t maxlen,uint8_t *script,int32_t scriptlen); +int32_t bitcoin_scriptsig(struct iguana_info *coin,uint8_t *script,int32_t n,const struct vin_info *vp,struct iguana_msgtx *msgtx); +char *iguana_scriptget(struct iguana_info *coin,char *scriptstr,char *asmstr,int32_t max,int32_t hdrsi,uint32_t unspentind,bits256 txid,int32_t vout,uint8_t *rmd160,int32_t type,uint8_t *pubkey33); + +int32_t bitcoin_base58decode(uint8_t *data,char *coinaddr); +char *bitcoin_base58encode(char *coinaddr,uint8_t *data_,int32_t datalen); +int32_t bitcoin_sign(void *ctx,char *symbol,uint8_t *sig,bits256 txhash2,bits256 privkey,int32_t recoverflag); +int32_t oldbitcoin_verify(uint8_t *sig,int32_t siglen,uint8_t *data,int32_t datalen,uint8_t *pubkey,int32_t len); + + #endif diff --git a/iguana/exchanges/nxtae.c b/iguana/exchanges/nxtae.c index 1753b0ef7..592532f30 100755 --- a/iguana/exchanges/nxtae.c +++ b/iguana/exchanges/nxtae.c @@ -83,6 +83,13 @@ char *_get_MSoffers(struct supernet_info *myinfo,char *str) return(issue_NXTPOST(cmd)); } +char *issue_startForging(struct supernet_info *myinfo,char *secret) +{ + char cmd[4096]; + sprintf(cmd,"requestType=startForging&secretPhrase=%s",secret); + 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; @@ -718,6 +725,7 @@ uint64_t submit_triggered_nxtae(struct supernet_info *myinfo,int32_t dotrade,cha } if ( (jsonstr= issue_NXTPOST(cmd)) != 0 ) { + printf("NXT.(%s) -> (%s)\n",cmd,jsonstr); _stripwhite(jsonstr,' '); if ( (json= cJSON_Parse(jsonstr)) != 0 ) { diff --git a/iguana/exchanges777.h b/iguana/exchanges777.h index e4b5fcbc7..c0b042a4d 100755 --- a/iguana/exchanges777.h +++ b/iguana/exchanges777.h @@ -17,14 +17,30 @@ #define EXCHANGES777_H #include "iguana777.h" +#ifdef ENABLE_CURL #include #include -#define INSTANTDEX_OFFERDURATION 3600 +#endif + +#define INSTANTDEX_DECKSIZE 2000 +#define INSTANTDEX_HOPS 2 +#define INSTANTDEX_DURATION 60 + +#define INSTANTDEX_INSURANCERATE (1. / 777.) +#define INSTANTDEX_PUBEY "03bc2c7ba671bae4a6fc835244c9762b41647b9827d4780a89a949b984a8ddcc06" +#define INSTANTDEX_RMD160 "ca1e04745e8ca0c60d8c5881531d51bec470743f" +#define TIERNOLAN_RMD160 "daedddd8dbe7a2439841ced40ba9c3d375f98146" +#define INSTANTDEX_BTC "1KRhTPvoxyJmVALwHFXZdeeWFbcJSbkFPu" +#define INSTANTDEX_BTCD "RThtXup6Zo7LZAi8kRWgjAyi1s4u6U9Cpf" +#define INSTANTDEX_MINPERC 50. -#define EXCHANGES777_MINPOLLGAP 3 +#define INSTANTDEX_OFFERDURATION 300 +#define INSTANTDEX_LOCKTIME 3600 + +#define EXCHANGES777_MINPOLLGAP 1 #define EXCHANGES777_MAXDEPTH 200 #define EXCHANGES777_DEFAULT_TIMEOUT 30 - +typedef void CURL; struct exchange_info; struct exchange_funcs @@ -51,7 +67,7 @@ struct exchange_info uint32_t exchangeid,pollgap,lastpoll; uint64_t lastnonce,exchangebits; double commission; void *privatedata; - CURL *cHandle; queue_t requestQ,pricesQ,pendingQ[2],tradebotsQ,acceptableQ; + CURL *cHandle; queue_t requestQ,pricesQ,statemachineQ,tradebotsQ,acceptableQ,historyQ; }; struct instantdex_msghdr @@ -89,24 +105,65 @@ struct exchange_request struct exchange_quote bidasks[]; }; -struct bitcoin_unspent { bits256 txid,privkey; uint64_t value; int32_t vout; }; -struct bitcoin_spend +struct instantdex_offer +{ + char base[24],rel[24]; + uint64_t price64,basevolume64,offer64; + uint32_t expiration,nonce; + char myside,acceptdir,minperc,pad; +}; + +struct instantdex_accept +{ + struct queueitem DL; + uint64_t pendingvolume64,orderid; + uint32_t dead; int32_t didstate; + struct instantdex_offer offer; +}; + +struct bitcoin_statetx +{ + bits256 txid; + uint64_t amount,change,inputsum; + double numconfirms; + char destaddr[64]; + char txbytes[]; +}; + +struct bitcoin_swapinfo +{ + struct queueitem DL; + struct instantdex_accept mine,other; + bits256 privkeys[INSTANTDEX_DECKSIZE+2],mypubs[2],otherpubs[2],privAm,pubAm,privBn,pubBn; + bits256 myorderhash,otherorderhash,mypubkey,othertrader; + uint64_t otherdeck[INSTANTDEX_DECKSIZE][2],deck[INSTANTDEX_DECKSIZE][2]; + uint64_t altsatoshis,BTCsatoshis,insurance,altpremium,matched64; + int32_t isinitiator,choosei,otherchoosei,cutverified,otherverifiedcut; + struct bitcoin_statetx *deposit,*payment,*altpayment,*myfee,*otherfee; + char expectedcmdstr[16],status[16],waitfortx[16]; + struct instantdex_stateinfo *state; uint32_t expiration,dead,reftime; +}; + +struct instantdex_event { char cmdstr[24],sendcmd[16]; int16_t nextstateind; }; + +struct instantdex_stateinfo { - char changeaddr[64]; - int32_t numinputs; - uint64_t txfee,input_satoshis,satoshis; - struct bitcoin_unspent inputs[]; + char name[24]; int16_t ind,initialstate; + cJSON *(*process)(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp); + cJSON *(*timeout)(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp); + int16_t timeoutind,errorind; + struct instantdex_event *events; int32_t numevents; }; -struct instantdex_entry { char base[24],rel[24]; uint64_t price64,basevolume64,offer64; uint32_t expiration,nonce; char myside,acceptdir; }; -struct instantdex_accept { struct queueitem DL; uint64_t pendingvolume64,orderid; uint32_t dead; struct instantdex_entry A; }; +#define instantdex_isbob(swap) (swap)->mine.offer.myside -struct instantdex_accept *instantdex_acceptablefind(struct exchange_info *exchange,cJSON *bids,cJSON *asks,uint64_t orderid,char *base,char *rel); +struct instantdex_accept *instantdex_offerfind(struct supernet_info *myinfo,struct exchange_info *exchange,cJSON *bids,cJSON *asks,uint64_t orderid,char *base,char *rel,int32_t requeue); cJSON *instantdex_acceptjson(struct instantdex_accept *ap); -struct instantdex_accept *instantdex_acceptable(struct exchange_info *exchange,struct instantdex_accept *A,uint64_t offerbits); +cJSON *instantdex_historyjson(struct bitcoin_swapinfo *swap); +struct bitcoin_swapinfo *instantdex_historyfind(struct supernet_info *myinfo,struct exchange_info *exchange,uint64_t orderid); +struct instantdex_accept *instantdex_acceptable(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,double minperc); 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); @@ -121,6 +178,11 @@ double truefx_price(struct exchange_info *exchange,char *base,char *rel,struct e 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); -char *instantdex_queueaccept(struct exchange_info *exchange,char *base,char *rel,double price,double basevolume,int32_t acceptdir,char *myside,int32_t duration); +char *instantdex_createaccept(struct supernet_info *myinfo,struct instantdex_accept **aptrp,struct exchange_info *exchange,char *base,char *rel,double price,double basevolume,int32_t acceptdir,char *mysidestr,int32_t duration,uint64_t offerer,int32_t queueflag,uint8_t minperc); +void instantdex_update(struct supernet_info *myinfo); +char *instantdex_sendcmd(struct supernet_info *myinfo,struct instantdex_offer *offer,cJSON *argjson,char *cmdstr,bits256 desthash,int32_t hops,void *extra,int32_t extralen); +char *instantdex_sendoffer(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *argjson); // Bob sending to network (Alice) +struct bitcoin_swapinfo *instantdex_statemachinefind(struct supernet_info *myinfo,struct exchange_info *exchange,uint64_t orderid,int32_t requeueflag); +char *instantdex_checkoffer(struct supernet_info *myinfo,uint64_t *txidp,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *json); #endif diff --git a/iguana/favicon.ico b/iguana/favicon.ico new file mode 100755 index 000000000..d249e41fe Binary files /dev/null and b/iguana/favicon.ico differ diff --git a/iguana/fonts/MaterialIcons-Regular.woff2 b/iguana/fonts/MaterialIcons-Regular.woff2 old mode 100644 new mode 100755 diff --git a/iguana/fonts/Roboto-Bold.woff2 b/iguana/fonts/Roboto-Bold.woff2 old mode 100644 new mode 100755 diff --git a/iguana/fonts/Roboto-Light.woff2 b/iguana/fonts/Roboto-Light.woff2 old mode 100644 new mode 100755 diff --git a/iguana/fonts/Roboto-Medium.woff2 b/iguana/fonts/Roboto-Medium.woff2 old mode 100644 new mode 100755 diff --git a/iguana/fonts/Roboto-Regular.woff2 b/iguana/fonts/Roboto-Regular.woff2 old mode 100644 new mode 100755 diff --git a/iguana/form-widget.html b/iguana/form-widget.html old mode 100644 new mode 100755 diff --git a/iguana/genbtc b/iguana/genbtc new file mode 100755 index 000000000..5c6c61ec2 --- /dev/null +++ b/iguana/genbtc @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"prefetchlag\":5,\"poll\":1,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"BTC\",\"startpend\":8,\"endpend\":1,\"services\":0,\"maxpeers\":64}" diff --git a/iguana/help/.tmpmarker b/iguana/help/.tmpmarker new file mode 100644 index 000000000..e69de29bb diff --git a/iguana/help/agent.md b/iguana/help/agent.md old mode 100644 new mode 100755 diff --git a/iguana/help/bootstrap-theme.min.css b/iguana/help/bootstrap-theme.min.css old mode 100644 new mode 100755 diff --git a/iguana/help/bootstrap.min.css b/iguana/help/bootstrap.min.css old mode 100644 new mode 100755 diff --git a/iguana/help/bootstrap.min.js b/iguana/help/bootstrap.min.js old mode 100644 new mode 100755 diff --git a/iguana/help/field.html b/iguana/help/field.html old mode 100644 new mode 100755 diff --git a/iguana/help/field.md b/iguana/help/field.md old mode 100644 new mode 100755 diff --git a/iguana/help/footer.html b/iguana/help/footer.html old mode 100644 new mode 100755 diff --git a/iguana/help/footer.md b/iguana/help/footer.md old mode 100644 new mode 100755 diff --git a/iguana/help/formfooter.html b/iguana/help/formfooter.html old mode 100644 new mode 100755 diff --git a/iguana/help/formfooter.md b/iguana/help/formfooter.md old mode 100644 new mode 100755 diff --git a/iguana/help/formheader.html b/iguana/help/formheader.html old mode 100644 new mode 100755 diff --git a/iguana/help/formheader.md b/iguana/help/formheader.md old mode 100644 new mode 100755 diff --git a/iguana/help/header.html b/iguana/help/header.html old mode 100644 new mode 100755 diff --git a/iguana/help/header.md b/iguana/help/header.md old mode 100644 new mode 100755 diff --git a/iguana/help/html5shiv.min.js b/iguana/help/html5shiv.min.js old mode 100644 new mode 100755 diff --git a/iguana/help/jquery-ui.css b/iguana/help/jquery-ui.css old mode 100644 new mode 100755 diff --git a/iguana/help/jquery-ui.min.js b/iguana/help/jquery-ui.min.js old mode 100644 new mode 100755 diff --git a/iguana/help/jquery.min.js b/iguana/help/jquery.min.js old mode 100644 new mode 100755 diff --git a/iguana/help/mime.json b/iguana/help/mime.json new file mode 100755 index 000000000..391a6da8c --- /dev/null +++ b/iguana/help/mime.json @@ -0,0 +1,1020 @@ +{ + "3dml": "text\/vnd.in3d.3dml", + "3ds": "image\/x-3ds", + "3g2": "video\/3gpp2", + "3gp": "video\/3gpp", + "7z": "application\/x-7z-compressed", + "aab": "application\/x-authorware-bin", + "aac": "audio\/x-aac", + "aam": "application\/x-authorware-map", + "aas": "application\/x-authorware-seg", + "abw": "application\/x-abiword", + "ac": "application\/pkix-attr-cert", + "acc": "application\/vnd.americandynamics.acc", + "ace": "application\/x-ace-compressed", + "acu": "application\/vnd.acucobol", + "acutc": "application\/vnd.acucorp", + "adp": "audio\/adpcm", + "aep": "application\/vnd.audiograph", + "afm": "application\/x-font-type1", + "afp": "application\/vnd.ibm.modcap", + "ahead": "application\/vnd.ahead.space", + "ai": "application\/postscript", + "aif": "audio\/x-aiff", + "aifc": "audio\/x-aiff", + "aiff": "audio\/x-aiff", + "air": "application\/vnd.adobe.air-application-installer-package+zip", + "ait": "application\/vnd.dvb.ait", + "ami": "application\/vnd.amiga.ami", + "apk": "application\/vnd.android.package-archive", + "appcache": "text\/cache-manifest", + "application": "application\/x-ms-application", + "apr": "application\/vnd.lotus-approach", + "arc": "application\/x-freearc", + "asa": "text\/plain", + "asax": "application\/octet-stream", + "asc": "application\/pgp-signature", + "ascx": "text\/plain", + "asf": "video\/x-ms-asf", + "ashx": "text\/plain", + "asm": "text\/x-asm", + "asmx": "text\/plain", + "aso": "application\/vnd.accpac.simply.aso", + "asp": "text\/plain", + "aspx": "text\/plain", + "asx": "video\/x-ms-asf", + "atc": "application\/vnd.acucorp", + "atom": "application\/atom+xml", + "atomcat": "application\/atomcat+xml", + "atomsvc": "application\/atomsvc+xml", + "atx": "application\/vnd.antix.game-component", + "au": "audio\/basic", + "avi": "video\/x-msvideo", + "aw": "application\/applixware", + "axd": "text\/plain", + "azf": "application\/vnd.airzip.filesecure.azf", + "azs": "application\/vnd.airzip.filesecure.azs", + "azw": "application\/vnd.amazon.ebook", + "bat": "application\/x-msdownload", + "bcpio": "application\/x-bcpio", + "bdf": "application\/x-font-bdf", + "bdm": "application\/vnd.syncml.dm+wbxml", + "bed": "application\/vnd.realvnc.bed", + "bh2": "application\/vnd.fujitsu.oasysprs", + "bin": "application\/octet-stream", + "blb": "application\/x-blorb", + "blorb": "application\/x-blorb", + "bmi": "application\/vnd.bmi", + "bmp": "image\/bmp", + "book": "application\/vnd.framemaker", + "box": "application\/vnd.previewsystems.box", + "boz": "application\/x-bzip2", + "bpk": "application\/octet-stream", + "btif": "image\/prs.btif", + "bz": "application\/x-bzip", + "bz2": "application\/x-bzip2", + "c": "text\/x-c", + "c11amc": "application\/vnd.cluetrust.cartomobile-config", + "c11amz": "application\/vnd.cluetrust.cartomobile-config-pkg", + "c4d": "application\/vnd.clonk.c4group", + "c4f": "application\/vnd.clonk.c4group", + "c4g": "application\/vnd.clonk.c4group", + "c4p": "application\/vnd.clonk.c4group", + "c4u": "application\/vnd.clonk.c4group", + "cab": "application\/vnd.ms-cab-compressed", + "caf": "audio\/x-caf", + "cap": "application\/vnd.tcpdump.pcap", + "car": "application\/vnd.curl.car", + "cat": "application\/vnd.ms-pki.seccat", + "cb7": "application\/x-cbr", + "cba": "application\/x-cbr", + "cbr": "application\/x-cbr", + "cbt": "application\/x-cbr", + "cbz": "application\/x-cbr", + "cc": "text\/x-c", + "cct": "application\/x-director", + "ccxml": "application\/ccxml+xml", + "cdbcmsg": "application\/vnd.contact.cmsg", + "cdf": "application\/x-netcdf", + "cdkey": "application\/vnd.mediastation.cdkey", + "cdmia": "application\/cdmi-capability", + "cdmic": "application\/cdmi-container", + "cdmid": "application\/cdmi-domain", + "cdmio": "application\/cdmi-object", + "cdmiq": "application\/cdmi-queue", + "cdx": "chemical\/x-cdx", + "cdxml": "application\/vnd.chemdraw+xml", + "cdy": "application\/vnd.cinderella", + "cer": "application\/pkix-cert", + "cfc": "application\/x-coldfusion", + "cfm": "application\/x-coldfusion", + "cfs": "application\/x-cfs-compressed", + "cgm": "image\/cgm", + "chat": "application\/x-chat", + "chm": "application\/vnd.ms-htmlhelp", + "chrt": "application\/vnd.kde.kchart", + "cif": "chemical\/x-cif", + "cii": "application\/vnd.anser-web-certificate-issue-initiation", + "cil": "application\/vnd.ms-artgalry", + "cla": "application\/vnd.claymore", + "class": "application\/java-vm", + "clkk": "application\/vnd.crick.clicker.keyboard", + "clkp": "application\/vnd.crick.clicker.palette", + "clkt": "application\/vnd.crick.clicker.template", + "clkw": "application\/vnd.crick.clicker.wordbank", + "clkx": "application\/vnd.crick.clicker", + "clp": "application\/x-msclip", + "cmc": "application\/vnd.cosmocaller", + "cmdf": "chemical\/x-cmdf", + "cml": "chemical\/x-cml", + "cmp": "application\/vnd.yellowriver-custom-menu", + "cmx": "image\/x-cmx", + "cod": "application\/vnd.rim.cod", + "com": "application\/x-msdownload", + "conf": "text\/plain", + "cpio": "application\/x-cpio", + "cpp": "text\/x-c", + "cpt": "application\/mac-compactpro", + "crd": "application\/x-mscardfile", + "crl": "application\/pkix-crl", + "crt": "application\/x-x509-ca-cert", + "crx": "application\/octet-stream", + "cryptonote": "application\/vnd.rig.cryptonote", + "cs": "text\/plain", + "csh": "application\/x-csh", + "csml": "chemical\/x-csml", + "csp": "application\/vnd.commonspace", + "css": "text\/css", + "cst": "application\/x-director", + "csv": "text\/csv", + "cu": "application\/cu-seeme", + "curl": "text\/vnd.curl", + "cww": "application\/prs.cww", + "cxt": "application\/x-director", + "cxx": "text\/x-c", + "dae": "model\/vnd.collada+xml", + "daf": "application\/vnd.mobius.daf", + "dart": "application\/vnd.dart", + "dataless": "application\/vnd.fdsn.seed", + "davmount": "application\/davmount+xml", + "dbk": "application\/docbook+xml", + "dcr": "application\/x-director", + "dcurl": "text\/vnd.curl.dcurl", + "dd2": "application\/vnd.oma.dd2+xml", + "ddd": "application\/vnd.fujixerox.ddd", + "deb": "application\/x-debian-package", + "def": "text\/plain", + "deploy": "application\/octet-stream", + "der": "application\/x-x509-ca-cert", + "dfac": "application\/vnd.dreamfactory", + "dgc": "application\/x-dgc-compressed", + "dic": "text\/x-c", + "dir": "application\/x-director", + "dis": "application\/vnd.mobius.dis", + "dist": "application\/octet-stream", + "distz": "application\/octet-stream", + "djv": "image\/vnd.djvu", + "djvu": "image\/vnd.djvu", + "dll": "application\/x-msdownload", + "dmg": "application\/x-apple-diskimage", + "dmp": "application\/vnd.tcpdump.pcap", + "dms": "application\/octet-stream", + "dna": "application\/vnd.dna", + "doc": "application\/msword", + "docm": "application\/vnd.ms-word.document.macroenabled.12", + "docx": "application\/vnd.openxmlformats-officedocument.wordprocessingml.document", + "dot": "application\/msword", + "dotm": "application\/vnd.ms-word.template.macroenabled.12", + "dotx": "application\/vnd.openxmlformats-officedocument.wordprocessingml.template", + "dp": "application\/vnd.osgi.dp", + "dpg": "application\/vnd.dpgraph", + "dra": "audio\/vnd.dra", + "dsc": "text\/prs.lines.tag", + "dssc": "application\/dssc+der", + "dtb": "application\/x-dtbook+xml", + "dtd": "application\/xml-dtd", + "dts": "audio\/vnd.dts", + "dtshd": "audio\/vnd.dts.hd", + "dump": "application\/octet-stream", + "dvb": "video\/vnd.dvb.file", + "dvi": "application\/x-dvi", + "dwf": "model\/vnd.dwf", + "dwg": "image\/vnd.dwg", + "dxf": "image\/vnd.dxf", + "dxp": "application\/vnd.spotfire.dxp", + "dxr": "application\/x-director", + "ecelp4800": "audio\/vnd.nuera.ecelp4800", + "ecelp7470": "audio\/vnd.nuera.ecelp7470", + "ecelp9600": "audio\/vnd.nuera.ecelp9600", + "ecma": "application\/ecmascript", + "edm": "application\/vnd.novadigm.edm", + "edx": "application\/vnd.novadigm.edx", + "efif": "application\/vnd.picsel", + "ei6": "application\/vnd.pg.osasli", + "elc": "application\/octet-stream", + "emf": "application\/x-msmetafile", + "eml": "message\/rfc822", + "emma": "application\/emma+xml", + "emz": "application\/x-msmetafile", + "eol": "audio\/vnd.digital-winds", + "eot": "application\/vnd.ms-fontobject", + "eps": "application\/postscript", + "epub": "application\/epub+zip", + "es3": "application\/vnd.eszigno3+xml", + "esa": "application\/vnd.osgi.subsystem", + "esf": "application\/vnd.epson.esf", + "et3": "application\/vnd.eszigno3+xml", + "etx": "text\/x-setext", + "eva": "application\/x-eva", + "evy": "application\/x-envoy", + "exe": "application\/x-msdownload", + "exi": "application\/exi", + "ext": "application\/vnd.novadigm.ext", + "ez": "application\/andrew-inset", + "ez2": "application\/vnd.ezpix-album", + "ez3": "application\/vnd.ezpix-package", + "f": "text\/x-fortran", + "f4v": "video\/x-f4v", + "f77": "text\/x-fortran", + "f90": "text\/x-fortran", + "fbs": "image\/vnd.fastbidsheet", + "fcdt": "application\/vnd.adobe.formscentral.fcdt", + "fcs": "application\/vnd.isac.fcs", + "fdf": "application\/vnd.fdf", + "fe_launch": "application\/vnd.denovo.fcselayout-link", + "fg5": "application\/vnd.fujitsu.oasysgp", + "fgd": "application\/x-director", + "fh": "image\/x-freehand", + "fh4": "image\/x-freehand", + "fh5": "image\/x-freehand", + "fh7": "image\/x-freehand", + "fhc": "image\/x-freehand", + "fig": "application\/x-xfig", + "flac": "audio\/x-flac", + "fli": "video\/x-fli", + "flo": "application\/vnd.micrografx.flo", + "flv": "video\/x-flv", + "flw": "application\/vnd.kde.kivio", + "flx": "text\/vnd.fmi.flexstor", + "fly": "text\/vnd.fly", + "fm": "application\/vnd.framemaker", + "fnc": "application\/vnd.frogans.fnc", + "for": "text\/x-fortran", + "fpx": "image\/vnd.fpx", + "frame": "application\/vnd.framemaker", + "fsc": "application\/vnd.fsc.weblaunch", + "fst": "image\/vnd.fst", + "ftc": "application\/vnd.fluxtime.clip", + "fti": "application\/vnd.anser-web-funds-transfer-initiation", + "fvt": "video\/vnd.fvt", + "fxp": "application\/vnd.adobe.fxp", + "fxpl": "application\/vnd.adobe.fxp", + "fzs": "application\/vnd.fuzzysheet", + "g2w": "application\/vnd.geoplan", + "g3": "image\/g3fax", + "g3w": "application\/vnd.geospace", + "gac": "application\/vnd.groove-account", + "gam": "application\/x-tads", + "gbr": "application\/rpki-ghostbusters", + "gca": "application\/x-gca-compressed", + "gdl": "model\/vnd.gdl", + "geo": "application\/vnd.dynageo", + "gex": "application\/vnd.geometry-explorer", + "ggb": "application\/vnd.geogebra.file", + "ggt": "application\/vnd.geogebra.tool", + "ghf": "application\/vnd.groove-help", + "gif": "image\/gif", + "gim": "application\/vnd.groove-identity-message", + "gml": "application\/gml+xml", + "gmx": "application\/vnd.gmx", + "gnumeric": "application\/x-gnumeric", + "gph": "application\/vnd.flographit", + "gpx": "application\/gpx+xml", + "gqf": "application\/vnd.grafeq", + "gqs": "application\/vnd.grafeq", + "gram": "application\/srgs", + "gramps": "application\/x-gramps-xml", + "gre": "application\/vnd.geometry-explorer", + "grv": "application\/vnd.groove-injector", + "grxml": "application\/srgs+xml", + "gsf": "application\/x-font-ghostscript", + "gtar": "application\/x-gtar", + "gtm": "application\/vnd.groove-tool-message", + "gtw": "model\/vnd.gtw", + "gv": "text\/vnd.graphviz", + "gxf": "application\/gxf", + "gxt": "application\/vnd.geonext", + "gz": "application\/x-gzip", + "h": "text\/x-c", + "h261": "video\/h261", + "h263": "video\/h263", + "h264": "video\/h264", + "hal": "application\/vnd.hal+xml", + "hbci": "application\/vnd.hbci", + "hdf": "application\/x-hdf", + "hh": "text\/x-c", + "hlp": "application\/winhlp", + "hpgl": "application\/vnd.hp-hpgl", + "hpid": "application\/vnd.hp-hpid", + "hps": "application\/vnd.hp-hps", + "hqx": "application\/mac-binhex40", + "hta": "application\/octet-stream", + "htc": "text\/html", + "htke": "application\/vnd.kenameaapp", + "htm": "text\/html", + "html": "text\/html", + "hvd": "application\/vnd.yamaha.hv-dic", + "hvp": "application\/vnd.yamaha.hv-voice", + "hvs": "application\/vnd.yamaha.hv-script", + "i2g": "application\/vnd.intergeo", + "icc": "application\/vnd.iccprofile", + "ice": "x-conference\/x-cooltalk", + "icm": "application\/vnd.iccprofile", + "ico": "image\/x-icon", + "ics": "text\/calendar", + "ief": "image\/ief", + "ifb": "text\/calendar", + "ifm": "application\/vnd.shana.informed.formdata", + "iges": "model\/iges", + "igl": "application\/vnd.igloader", + "igm": "application\/vnd.insors.igm", + "igs": "model\/iges", + "igx": "application\/vnd.micrografx.igx", + "iif": "application\/vnd.shana.informed.interchange", + "imp": "application\/vnd.accpac.simply.imp", + "ims": "application\/vnd.ms-ims", + "in": "text\/plain", + "ini": "text\/plain", + "ink": "application\/inkml+xml", + "inkml": "application\/inkml+xml", + "install": "application\/x-install-instructions", + "iota": "application\/vnd.astraea-software.iota", + "ipa": "application\/octet-stream", + "ipfix": "application\/ipfix", + "ipk": "application\/vnd.shana.informed.package", + "irm": "application\/vnd.ibm.rights-management", + "irp": "application\/vnd.irepository.package+xml", + "iso": "application\/x-iso9660-image", + "itp": "application\/vnd.shana.informed.formtemplate", + "ivp": "application\/vnd.immervision-ivp", + "ivu": "application\/vnd.immervision-ivu", + "jad": "text\/vnd.sun.j2me.app-descriptor", + "jam": "application\/vnd.jam", + "jar": "application\/java-archive", + "java": "text\/x-java-source", + "jisp": "application\/vnd.jisp", + "jlt": "application\/vnd.hp-jlyt", + "jnlp": "application\/x-java-jnlp-file", + "joda": "application\/vnd.joost.joda-archive", + "jpe": "image\/jpeg", + "jpeg": "image\/jpeg", + "jpg": "image\/jpeg", + "jpgm": "video\/jpm", + "jpgv": "video\/jpeg", + "jpm": "video\/jpm", + "js": "text\/javascript", + "json": "application\/json", + "jsonml": "application\/jsonml+json", + "kar": "audio\/midi", + "karbon": "application\/vnd.kde.karbon", + "kfo": "application\/vnd.kde.kformula", + "kia": "application\/vnd.kidspiration", + "kml": "application\/vnd.google-earth.kml+xml", + "kmz": "application\/vnd.google-earth.kmz", + "kne": "application\/vnd.kinar", + "knp": "application\/vnd.kinar", + "kon": "application\/vnd.kde.kontour", + "kpr": "application\/vnd.kde.kpresenter", + "kpt": "application\/vnd.kde.kpresenter", + "kpxx": "application\/vnd.ds-keypoint", + "ksp": "application\/vnd.kde.kspread", + "ktr": "application\/vnd.kahootz", + "ktx": "image\/ktx", + "ktz": "application\/vnd.kahootz", + "kwd": "application\/vnd.kde.kword", + "kwt": "application\/vnd.kde.kword", + "lasxml": "application\/vnd.las.las+xml", + "latex": "application\/x-latex", + "lbd": "application\/vnd.llamagraphics.life-balance.desktop", + "lbe": "application\/vnd.llamagraphics.life-balance.exchange+xml", + "les": "application\/vnd.hhe.lesson-player", + "lha": "application\/x-lzh-compressed", + "link66": "application\/vnd.route66.link66+xml", + "list": "text\/plain", + "list3820": "application\/vnd.ibm.modcap", + "listafp": "application\/vnd.ibm.modcap", + "lnk": "application\/x-ms-shortcut", + "log": "text\/plain", + "lostxml": "application\/lost+xml", + "lrf": "application\/octet-stream", + "lrm": "application\/vnd.ms-lrm", + "ltf": "application\/vnd.frogans.ltf", + "lvp": "audio\/vnd.lucent.voice", + "lwp": "application\/vnd.lotus-wordpro", + "lz": "application\/x-lzip", + "lzh": "application\/x-lzh-compressed", + "lzma": "application\/x-lzma", + "lzo": "application\/x-lzop", + "m13": "application\/x-msmediaview", + "m14": "application\/x-msmediaview", + "m1v": "video\/mpeg", + "m21": "application\/mp21", + "m2a": "audio\/mpeg", + "m2v": "video\/mpeg", + "m3a": "audio\/mpeg", + "m3u": "audio\/x-mpegurl", + "m3u8": "application\/vnd.apple.mpegurl", + "m4a": "audio\/mp4", + "m4u": "video\/vnd.mpegurl", + "m4v": "video\/mp4", + "ma": "application\/mathematica", + "mads": "application\/mads+xml", + "mag": "application\/vnd.ecowin.chart", + "maker": "application\/vnd.framemaker", + "man": "text\/troff", + "mar": "application\/octet-stream", + "mathml": "application\/mathml+xml", + "mb": "application\/mathematica", + "mbk": "application\/vnd.mobius.mbk", + "mbox": "application\/mbox", + "mc1": "application\/vnd.medcalcdata", + "mcd": "application\/vnd.mcd", + "mcurl": "text\/vnd.curl.mcurl", + "mdb": "application\/x-msaccess", + "mdi": "image\/vnd.ms-modi", + "me": "text\/troff", + "mesh": "model\/mesh", + "meta4": "application\/metalink4+xml", + "metalink": "application\/metalink+xml", + "mets": "application\/mets+xml", + "mfm": "application\/vnd.mfmp", + "mft": "application\/rpki-manifest", + "mgp": "application\/vnd.osgeo.mapguide.package", + "mgz": "application\/vnd.proteus.magazine", + "mid": "audio\/midi", + "midi": "audio\/midi", + "mie": "application\/x-mie", + "mif": "application\/vnd.mif", + "mime": "message\/rfc822", + "mj2": "video\/mj2", + "mjp2": "video\/mj2", + "mk3d": "video\/x-matroska", + "mka": "audio\/x-matroska", + "mks": "video\/x-matroska", + "mkv": "video\/x-matroska", + "mlp": "application\/vnd.dolby.mlp", + "mmd": "application\/vnd.chipnuts.karaoke-mmd", + "mmf": "application\/vnd.smaf", + "mmr": "image\/vnd.fujixerox.edmics-mmr", + "mng": "video\/x-mng", + "mny": "application\/x-msmoney", + "mobi": "application\/x-mobipocket-ebook", + "mods": "application\/mods+xml", + "mov": "video\/quicktime", + "movie": "video\/x-sgi-movie", + "mp2": "audio\/mpeg", + "mp21": "application\/mp21", + "mp2a": "audio\/mpeg", + "mp3": "audio\/mpeg", + "mp4": "video\/mp4", + "mp4a": "audio\/mp4", + "mp4s": "application\/mp4", + "mp4v": "video\/mp4", + "mpc": "application\/vnd.mophun.certificate", + "mpe": "video\/mpeg", + "mpeg": "video\/mpeg", + "mpg": "video\/mpeg", + "mpg4": "video\/mp4", + "mpga": "audio\/mpeg", + "mpkg": "application\/vnd.apple.installer+xml", + "mpm": "application\/vnd.blueice.multipass", + "mpn": "application\/vnd.mophun.application", + "mpp": "application\/vnd.ms-project", + "mpt": "application\/vnd.ms-project", + "mpy": "application\/vnd.ibm.minipay", + "mqy": "application\/vnd.mobius.mqy", + "mrc": "application\/marc", + "mrcx": "application\/marcxml+xml", + "ms": "text\/troff", + "mscml": "application\/mediaservercontrol+xml", + "mseed": "application\/vnd.fdsn.mseed", + "mseq": "application\/vnd.mseq", + "msf": "application\/vnd.epson.msf", + "msh": "model\/mesh", + "msi": "application\/x-msdownload", + "msl": "application\/vnd.mobius.msl", + "msty": "application\/vnd.muvee.style", + "mts": "model\/vnd.mts", + "mus": "application\/vnd.musician", + "musicxml": "application\/vnd.recordare.musicxml+xml", + "mvb": "application\/x-msmediaview", + "mwf": "application\/vnd.mfer", + "mxf": "application\/mxf", + "mxl": "application\/vnd.recordare.musicxml", + "mxml": "application\/xv+xml", + "mxs": "application\/vnd.triscape.mxs", + "mxu": "video\/vnd.mpegurl", + "n-gage": "application\/vnd.nokia.n-gage.symbian.install", + "n3": "text\/n3", + "nb": "application\/mathematica", + "nbp": "application\/vnd.wolfram.player", + "nc": "application\/x-netcdf", + "ncx": "application\/x-dtbncx+xml", + "nfo": "text\/x-nfo", + "ngdat": "application\/vnd.nokia.n-gage.data", + "nitf": "application\/vnd.nitf", + "nlu": "application\/vnd.neurolanguage.nlu", + "nml": "application\/vnd.enliven", + "nnd": "application\/vnd.noblenet-directory", + "nns": "application\/vnd.noblenet-sealer", + "nnw": "application\/vnd.noblenet-web", + "npx": "image\/vnd.net-fpx", + "nsc": "application\/x-conference", + "nsf": "application\/vnd.lotus-notes", + "ntf": "application\/vnd.nitf", + "nzb": "application\/x-nzb", + "oa2": "application\/vnd.fujitsu.oasys2", + "oa3": "application\/vnd.fujitsu.oasys3", + "oas": "application\/vnd.fujitsu.oasys", + "obd": "application\/x-msbinder", + "obj": "application\/x-tgif", + "oda": "application\/oda", + "odb": "application\/vnd.oasis.opendocument.database", + "odc": "application\/vnd.oasis.opendocument.chart", + "odf": "application\/vnd.oasis.opendocument.formula", + "odft": "application\/vnd.oasis.opendocument.formula-template", + "odg": "application\/vnd.oasis.opendocument.graphics", + "odi": "application\/vnd.oasis.opendocument.image", + "odm": "application\/vnd.oasis.opendocument.text-master", + "odp": "application\/vnd.oasis.opendocument.presentation", + "ods": "application\/vnd.oasis.opendocument.spreadsheet", + "odt": "application\/vnd.oasis.opendocument.text", + "oga": "audio\/ogg", + "ogg": "audio\/ogg", + "ogv": "video\/ogg", + "ogx": "application\/ogg", + "omdoc": "application\/omdoc+xml", + "onepkg": "application\/onenote", + "onetmp": "application\/onenote", + "onetoc": "application\/onenote", + "onetoc2": "application\/onenote", + "opf": "application\/oebps-package+xml", + "opml": "text\/x-opml", + "oprc": "application\/vnd.palm", + "org": "application\/vnd.lotus-organizer", + "osf": "application\/vnd.yamaha.openscoreformat", + "osfpvg": "application\/vnd.yamaha.openscoreformat.osfpvg+xml", + "otc": "application\/vnd.oasis.opendocument.chart-template", + "otf": "application\/x-font-otf", + "otg": "application\/vnd.oasis.opendocument.graphics-template", + "oth": "application\/vnd.oasis.opendocument.text-web", + "oti": "application\/vnd.oasis.opendocument.image-template", + "otp": "application\/vnd.oasis.opendocument.presentation-template", + "ots": "application\/vnd.oasis.opendocument.spreadsheet-template", + "ott": "application\/vnd.oasis.opendocument.text-template", + "oxps": "application\/oxps", + "oxt": "application\/vnd.openofficeorg.extension", + "p": "text\/x-pascal", + "p10": "application\/pkcs10", + "p12": "application\/x-pkcs12", + "p7b": "application\/x-pkcs7-certificates", + "p7c": "application\/pkcs7-mime", + "p7m": "application\/pkcs7-mime", + "p7r": "application\/x-pkcs7-certreqresp", + "p7s": "application\/pkcs7-signature", + "p8": "application\/pkcs8", + "pas": "text\/x-pascal", + "paw": "application\/vnd.pawaafile", + "pbd": "application\/vnd.powerbuilder6", + "pbm": "image\/x-portable-bitmap", + "pcap": "application\/vnd.tcpdump.pcap", + "pcf": "application\/x-font-pcf", + "pcl": "application\/vnd.hp-pcl", + "pclxl": "application\/vnd.hp-pclxl", + "pct": "image\/x-pict", + "pcurl": "application\/vnd.curl.pcurl", + "pcx": "image\/x-pcx", + "pdb": "application\/vnd.palm", + "pdf": "application\/pdf", + "pfa": "application\/x-font-type1", + "pfb": "application\/x-font-type1", + "pfm": "application\/x-font-type1", + "pfr": "application\/font-tdpfr", + "pfx": "application\/x-pkcs12", + "pgm": "image\/x-portable-graymap", + "pgn": "application\/x-chess-pgn", + "pgp": "application\/pgp-encrypted", + "phar": "application\/octet-stream", + "php": "text\/plain", + "phps": "application\/x-httpd-phps", + "pic": "image\/x-pict", + "pkg": "application\/octet-stream", + "pki": "application\/pkixcmp", + "pkipath": "application\/pkix-pkipath", + "plb": "application\/vnd.3gpp.pic-bw-large", + "plc": "application\/vnd.mobius.plc", + "plf": "application\/vnd.pocketlearn", + "plist": "application\/x-plist", + "pls": "application\/pls+xml", + "pml": "application\/vnd.ctc-posml", + "png": "image\/png", + "pnm": "image\/x-portable-anymap", + "portpkg": "application\/vnd.macports.portpkg", + "pot": "application\/vnd.ms-powerpoint", + "potm": "application\/vnd.ms-powerpoint.template.macroenabled.12", + "potx": "application\/vnd.openxmlformats-officedocument.presentationml.template", + "ppam": "application\/vnd.ms-powerpoint.addin.macroenabled.12", + "ppd": "application\/vnd.cups-ppd", + "ppm": "image\/x-portable-pixmap", + "pps": "application\/vnd.ms-powerpoint", + "ppsm": "application\/vnd.ms-powerpoint.slideshow.macroenabled.12", + "ppsx": "application\/vnd.openxmlformats-officedocument.presentationml.slideshow", + "ppt": "application\/vnd.ms-powerpoint", + "pptm": "application\/vnd.ms-powerpoint.presentation.macroenabled.12", + "pptx": "application\/vnd.openxmlformats-officedocument.presentationml.presentation", + "pqa": "application\/vnd.palm", + "prc": "application\/x-mobipocket-ebook", + "pre": "application\/vnd.lotus-freelance", + "prf": "application\/pics-rules", + "ps": "application\/postscript", + "psb": "application\/vnd.3gpp.pic-bw-small", + "psd": "image\/vnd.adobe.photoshop", + "psf": "application\/x-font-linux-psf", + "pskcxml": "application\/pskc+xml", + "ptid": "application\/vnd.pvi.ptid1", + "pub": "application\/x-mspublisher", + "pvb": "application\/vnd.3gpp.pic-bw-var", + "pwn": "application\/vnd.3m.post-it-notes", + "pya": "audio\/vnd.ms-playready.media.pya", + "pyv": "video\/vnd.ms-playready.media.pyv", + "qam": "application\/vnd.epson.quickanime", + "qbo": "application\/vnd.intu.qbo", + "qfx": "application\/vnd.intu.qfx", + "qps": "application\/vnd.publishare-delta-tree", + "qt": "video\/quicktime", + "qwd": "application\/vnd.quark.quarkxpress", + "qwt": "application\/vnd.quark.quarkxpress", + "qxb": "application\/vnd.quark.quarkxpress", + "qxd": "application\/vnd.quark.quarkxpress", + "qxl": "application\/vnd.quark.quarkxpress", + "qxt": "application\/vnd.quark.quarkxpress", + "ra": "audio\/x-pn-realaudio", + "ram": "audio\/x-pn-realaudio", + "rar": "application\/x-rar-compressed", + "ras": "image\/x-cmu-raster", + "rb": "text\/plain", + "rcprofile": "application\/vnd.ipunplugged.rcprofile", + "rdf": "application\/rdf+xml", + "rdz": "application\/vnd.data-vision.rdz", + "rep": "application\/vnd.businessobjects", + "res": "application\/x-dtbresource+xml", + "resx": "text\/xml", + "rgb": "image\/x-rgb", + "rif": "application\/reginfo+xml", + "rip": "audio\/vnd.rip", + "ris": "application\/x-research-info-systems", + "rl": "application\/resource-lists+xml", + "rlc": "image\/vnd.fujixerox.edmics-rlc", + "rld": "application\/resource-lists-diff+xml", + "rm": "application\/vnd.rn-realmedia", + "rmi": "audio\/midi", + "rmp": "audio\/x-pn-realaudio-plugin", + "rms": "application\/vnd.jcp.javame.midlet-rms", + "rmvb": "application\/vnd.rn-realmedia-vbr", + "rnc": "application\/relax-ng-compact-syntax", + "roa": "application\/rpki-roa", + "roff": "text\/troff", + "rp9": "application\/vnd.cloanto.rp9", + "rpm": "application\/x-rpm", + "rpss": "application\/vnd.nokia.radio-presets", + "rpst": "application\/vnd.nokia.radio-preset", + "rq": "application\/sparql-query", + "rs": "application\/rls-services+xml", + "rsd": "application\/rsd+xml", + "rss": "application\/rss+xml", + "rtf": "application\/rtf", + "rtx": "text\/richtext", + "s": "text\/x-asm", + "s3m": "audio\/s3m", + "s7z": "application\/x-7z-compressed", + "saf": "application\/vnd.yamaha.smaf-audio", + "safariextz": "application\/octet-stream", + "sass": "text\/x-sass", + "sbml": "application\/sbml+xml", + "sc": "application\/vnd.ibm.secure-container", + "scd": "application\/x-msschedule", + "scm": "application\/vnd.lotus-screencam", + "scq": "application\/scvp-cv-request", + "scs": "application\/scvp-cv-response", + "scss": "text\/x-scss", + "scurl": "text\/vnd.curl.scurl", + "sda": "application\/vnd.stardivision.draw", + "sdc": "application\/vnd.stardivision.calc", + "sdd": "application\/vnd.stardivision.impress", + "sdkd": "application\/vnd.solent.sdkm+xml", + "sdkm": "application\/vnd.solent.sdkm+xml", + "sdp": "application\/sdp", + "sdw": "application\/vnd.stardivision.writer", + "see": "application\/vnd.seemail", + "seed": "application\/vnd.fdsn.seed", + "sema": "application\/vnd.sema", + "semd": "application\/vnd.semd", + "semf": "application\/vnd.semf", + "ser": "application\/java-serialized-object", + "setpay": "application\/set-payment-initiation", + "setreg": "application\/set-registration-initiation", + "sfd-hdstx": "application\/vnd.hydrostatix.sof-data", + "sfs": "application\/vnd.spotfire.sfs", + "sfv": "text\/x-sfv", + "sgi": "image\/sgi", + "sgl": "application\/vnd.stardivision.writer-global", + "sgm": "text\/sgml", + "sgml": "text\/sgml", + "sh": "application\/x-sh", + "shar": "application\/x-shar", + "shf": "application\/shf+xml", + "sid": "image\/x-mrsid-image", + "sig": "application\/pgp-signature", + "sil": "audio\/silk", + "silo": "model\/mesh", + "sis": "application\/vnd.symbian.install", + "sisx": "application\/vnd.symbian.install", + "sit": "application\/x-stuffit", + "sitx": "application\/x-stuffitx", + "skd": "application\/vnd.koan", + "skm": "application\/vnd.koan", + "skp": "application\/vnd.koan", + "skt": "application\/vnd.koan", + "sldm": "application\/vnd.ms-powerpoint.slide.macroenabled.12", + "sldx": "application\/vnd.openxmlformats-officedocument.presentationml.slide", + "slt": "application\/vnd.epson.salt", + "sm": "application\/vnd.stepmania.stepchart", + "smf": "application\/vnd.stardivision.math", + "smi": "application\/smil+xml", + "smil": "application\/smil+xml", + "smv": "video\/x-smv", + "smzip": "application\/vnd.stepmania.package", + "snd": "audio\/basic", + "snf": "application\/x-font-snf", + "so": "application\/octet-stream", + "spc": "application\/x-pkcs7-certificates", + "spf": "application\/vnd.yamaha.smaf-phrase", + "spl": "application\/x-futuresplash", + "spot": "text\/vnd.in3d.spot", + "spp": "application\/scvp-vp-response", + "spq": "application\/scvp-vp-request", + "spx": "audio\/ogg", + "sql": "application\/x-sql", + "src": "application\/x-wais-source", + "srt": "application\/x-subrip", + "sru": "application\/sru+xml", + "srx": "application\/sparql-results+xml", + "ssdl": "application\/ssdl+xml", + "sse": "application\/vnd.kodak-descriptor", + "ssf": "application\/vnd.epson.ssf", + "ssml": "application\/ssml+xml", + "st": "application\/vnd.sailingtracker.track", + "stc": "application\/vnd.sun.xml.calc.template", + "std": "application\/vnd.sun.xml.draw.template", + "stf": "application\/vnd.wt.stf", + "sti": "application\/vnd.sun.xml.impress.template", + "stk": "application\/hyperstudio", + "stl": "application\/vnd.ms-pki.stl", + "str": "application\/vnd.pg.format", + "stw": "application\/vnd.sun.xml.writer.template", + "styl": "text\/x-styl", + "sub": "image\/vnd.dvb.subtitle", + "sus": "application\/vnd.sus-calendar", + "susp": "application\/vnd.sus-calendar", + "sv4cpio": "application\/x-sv4cpio", + "sv4crc": "application\/x-sv4crc", + "svc": "application\/vnd.dvb.service", + "svd": "application\/vnd.svd", + "svg": "image\/svg+xml", + "svgz": "image\/svg+xml", + "swa": "application\/x-director", + "swf": "application\/x-shockwave-flash", + "swi": "application\/vnd.aristanetworks.swi", + "sxc": "application\/vnd.sun.xml.calc", + "sxd": "application\/vnd.sun.xml.draw", + "sxg": "application\/vnd.sun.xml.writer.global", + "sxi": "application\/vnd.sun.xml.impress", + "sxm": "application\/vnd.sun.xml.math", + "sxw": "application\/vnd.sun.xml.writer", + "t": "text\/troff", + "t3": "application\/x-t3vm-image", + "taglet": "application\/vnd.mynfc", + "tao": "application\/vnd.tao.intent-module-archive", + "tar": "application\/x-tar", + "tcap": "application\/vnd.3gpp2.tcap", + "tcl": "application\/x-tcl", + "teacher": "application\/vnd.smart.teacher", + "tei": "application\/tei+xml", + "teicorpus": "application\/tei+xml", + "tex": "application\/x-tex", + "texi": "application\/x-texinfo", + "texinfo": "application\/x-texinfo", + "text": "text\/plain", + "tfi": "application\/thraud+xml", + "tfm": "application\/x-tex-tfm", + "tga": "image\/x-tga", + "tgz": "application\/x-gzip", + "thmx": "application\/vnd.ms-officetheme", + "tif": "image\/tiff", + "tiff": "image\/tiff", + "tmo": "application\/vnd.tmobile-livetv", + "torrent": "application\/x-bittorrent", + "tpl": "application\/vnd.groove-tool-template", + "tpt": "application\/vnd.trid.tpt", + "tr": "text\/troff", + "tra": "application\/vnd.trueapp", + "trm": "application\/x-msterminal", + "tsd": "application\/timestamped-data", + "tsv": "text\/tab-separated-values", + "ttc": "application\/x-font-ttf", + "ttf": "application\/x-font-ttf", + "ttl": "text\/turtle", + "twd": "application\/vnd.simtech-mindmapper", + "twds": "application\/vnd.simtech-mindmapper", + "txd": "application\/vnd.genomatix.tuxedo", + "txf": "application\/vnd.mobius.txf", + "txt": "text\/plain", + "u32": "application\/x-authorware-bin", + "udeb": "application\/x-debian-package", + "ufd": "application\/vnd.ufdl", + "ufdl": "application\/vnd.ufdl", + "ulx": "application\/x-glulx", + "umj": "application\/vnd.umajin", + "unityweb": "application\/vnd.unity", + "uoml": "application\/vnd.uoml+xml", + "uri": "text\/uri-list", + "uris": "text\/uri-list", + "urls": "text\/uri-list", + "ustar": "application\/x-ustar", + "utz": "application\/vnd.uiq.theme", + "uu": "text\/x-uuencode", + "uva": "audio\/vnd.dece.audio", + "uvd": "application\/vnd.dece.data", + "uvf": "application\/vnd.dece.data", + "uvg": "image\/vnd.dece.graphic", + "uvh": "video\/vnd.dece.hd", + "uvi": "image\/vnd.dece.graphic", + "uvm": "video\/vnd.dece.mobile", + "uvp": "video\/vnd.dece.pd", + "uvs": "video\/vnd.dece.sd", + "uvt": "application\/vnd.dece.ttml+xml", + "uvu": "video\/vnd.uvvu.mp4", + "uvv": "video\/vnd.dece.video", + "uvva": "audio\/vnd.dece.audio", + "uvvd": "application\/vnd.dece.data", + "uvvf": "application\/vnd.dece.data", + "uvvg": "image\/vnd.dece.graphic", + "uvvh": "video\/vnd.dece.hd", + "uvvi": "image\/vnd.dece.graphic", + "uvvm": "video\/vnd.dece.mobile", + "uvvp": "video\/vnd.dece.pd", + "uvvs": "video\/vnd.dece.sd", + "uvvt": "application\/vnd.dece.ttml+xml", + "uvvu": "video\/vnd.uvvu.mp4", + "uvvv": "video\/vnd.dece.video", + "uvvx": "application\/vnd.dece.unspecified", + "uvvz": "application\/vnd.dece.zip", + "uvx": "application\/vnd.dece.unspecified", + "uvz": "application\/vnd.dece.zip", + "vcard": "text\/vcard", + "vcd": "application\/x-cdlink", + "vcf": "text\/x-vcard", + "vcg": "application\/vnd.groove-vcard", + "vcs": "text\/x-vcalendar", + "vcx": "application\/vnd.vcx", + "vis": "application\/vnd.visionary", + "viv": "video\/vnd.vivo", + "vob": "video\/x-ms-vob", + "vor": "application\/vnd.stardivision.writer", + "vox": "application\/x-authorware-bin", + "vrml": "model\/vrml", + "vsd": "application\/vnd.visio", + "vsf": "application\/vnd.vsf", + "vss": "application\/vnd.visio", + "vst": "application\/vnd.visio", + "vsw": "application\/vnd.visio", + "vtu": "model\/vnd.vtu", + "vxml": "application\/voicexml+xml", + "w3d": "application\/x-director", + "wad": "application\/x-doom", + "wav": "audio\/x-wav", + "wax": "audio\/x-ms-wax", + "wbmp": "image\/vnd.wap.wbmp", + "wbs": "application\/vnd.criticaltools.wbs+xml", + "wbxml": "application\/vnd.wap.wbxml", + "wcm": "application\/vnd.ms-works", + "wdb": "application\/vnd.ms-works", + "wdp": "image\/vnd.ms-photo", + "weba": "audio\/webm", + "webm": "video\/webm", + "webp": "image\/webp", + "wg": "application\/vnd.pmi.widget", + "wgt": "application\/widget", + "wks": "application\/vnd.ms-works", + "wm": "video\/x-ms-wm", + "wma": "audio\/x-ms-wma", + "wmd": "application\/x-ms-wmd", + "wmf": "application\/x-msmetafile", + "wml": "text\/vnd.wap.wml", + "wmlc": "application\/vnd.wap.wmlc", + "wmls": "text\/vnd.wap.wmlscript", + "wmlsc": "application\/vnd.wap.wmlscriptc", + "wmv": "video\/x-ms-wmv", + "wmx": "video\/x-ms-wmx", + "wmz": "application\/x-ms-wmz", + "woff": "application\/x-font-woff", + "wpd": "application\/vnd.wordperfect", + "wpl": "application\/vnd.ms-wpl", + "wps": "application\/vnd.ms-works", + "wqd": "application\/vnd.wqd", + "wri": "application\/x-mswrite", + "wrl": "model\/vrml", + "wsdl": "application\/wsdl+xml", + "wspolicy": "application\/wspolicy+xml", + "wtb": "application\/vnd.webturbo", + "wvx": "video\/x-ms-wvx", + "x32": "application\/x-authorware-bin", + "x3d": "model\/x3d+xml", + "x3db": "model\/x3d+binary", + "x3dbz": "model\/x3d+binary", + "x3dv": "model\/x3d+vrml", + "x3dvz": "model\/x3d+vrml", + "x3dz": "model\/x3d+xml", + "xaml": "application\/xaml+xml", + "xap": "application\/x-silverlight-app", + "xar": "application\/vnd.xara", + "xbap": "application\/x-ms-xbap", + "xbd": "application\/vnd.fujixerox.docuworks.binder", + "xbm": "image\/x-xbitmap", + "xdf": "application\/xcap-diff+xml", + "xdm": "application\/vnd.syncml.dm+xml", + "xdp": "application\/vnd.adobe.xdp+xml", + "xdssc": "application\/dssc+xml", + "xdw": "application\/vnd.fujixerox.docuworks", + "xenc": "application\/xenc+xml", + "xer": "application\/patch-ops-error+xml", + "xfdf": "application\/vnd.adobe.xfdf", + "xfdl": "application\/vnd.xfdl", + "xht": "application\/xhtml+xml", + "xhtml": "application\/xhtml+xml", + "xhvml": "application\/xv+xml", + "xif": "image\/vnd.xiff", + "xla": "application\/vnd.ms-excel", + "xlam": "application\/vnd.ms-excel.addin.macroenabled.12", + "xlc": "application\/vnd.ms-excel", + "xlf": "application\/x-xliff+xml", + "xlm": "application\/vnd.ms-excel", + "xls": "application\/vnd.ms-excel", + "xlsb": "application\/vnd.ms-excel.sheet.binary.macroenabled.12", + "xlsm": "application\/vnd.ms-excel.sheet.macroenabled.12", + "xlsx": "application\/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + "xlt": "application\/vnd.ms-excel", + "xltm": "application\/vnd.ms-excel.template.macroenabled.12", + "xltx": "application\/vnd.openxmlformats-officedocument.spreadsheetml.template", + "xlw": "application\/vnd.ms-excel", + "xm": "audio\/xm", + "xml": "application\/xml", + "xo": "application\/vnd.olpc-sugar", + "xop": "application\/xop+xml", + "xpi": "application\/x-xpinstall", + "xpl": "application\/xproc+xml", + "xpm": "image\/x-xpixmap", + "xpr": "application\/vnd.is-xpr", + "xps": "application\/vnd.ms-xpsdocument", + "xpw": "application\/vnd.intercon.formnet", + "xpx": "application\/vnd.intercon.formnet", + "xsl": "application\/xml", + "xslt": "application\/xslt+xml", + "xsm": "application\/vnd.syncml+xml", + "xspf": "application\/xspf+xml", + "xul": "application\/vnd.mozilla.xul+xml", + "xvm": "application\/xv+xml", + "xvml": "application\/xv+xml", + "xwd": "image\/x-xwindowdump", + "xyz": "chemical\/x-xyz", + "xz": "application\/x-xz", + "yaml": "text\/yaml", + "yang": "application\/yang", + "yin": "application\/yin+xml", + "yml": "text\/yaml", + "z": "application\/x-compress", + "z1": "application\/x-zmachine", + "z2": "application\/x-zmachine", + "z3": "application\/x-zmachine", + "z4": "application\/x-zmachine", + "z5": "application\/x-zmachine", + "z6": "application\/x-zmachine", + "z7": "application\/x-zmachine", + "z8": "application\/x-zmachine", + "zaz": "application\/vnd.zzazz.deck+xml", + "zip": "application\/zip", + "zir": "application\/vnd.zul", + "zirz": "application\/vnd.zul", + "zmm": "application\/vnd.handheld-entertainment+xml", + "123": "application\/vnd.lotus-1-2-3" +} diff --git a/iguana/help/respond.min.js b/iguana/help/respond.min.js old mode 100644 new mode 100755 diff --git a/iguana/icon128.jpg b/iguana/icon128.jpg old mode 100644 new mode 100755 diff --git a/iguana/icon128.png b/iguana/icon128.png old mode 100644 new mode 100755 diff --git a/iguana/iguana.sources b/iguana/iguana.sources index b2fd43338..68a2d7a9e 100755 --- a/iguana/iguana.sources +++ b/iguana/iguana.sources @@ -1,3 +1,2 @@ -#iguana_html.c -SOURCES := SuperNET.c SuperNET_keys.c SuperNET_category.c SuperNET_hexmsg.c peggy.c peggy_consensus.c peggy_price.c peggy_update.c peggy_accts.c peggy_tx.c peggy_txind.c peggy_ramkv.c peggy_serdes.c iguana_exchanges.c iguana_tradebots.c iguana_instantdex.c pangea_api.c pangea_bets.c cards777.c pangea_summary.c pangea_json.c pangea_hand.c poker.c ramchain_api.c iguana_tx.c iguana_wallet.c iguana_pubkeys.c iguana_recv.c iguana_bundles.c iguana_msg.c iguana_rpc.c iguana777.c iguana_chains.c iguana_peers.c iguana_accept.c iguana_bitmap.c iguana_init.c iguana_ramchain.c iguana_blocks.c iguana_json.c main.c +SOURCES := SuperNET.c iguana_bundles.c iguana_interpreter.c mini-gmp.c main.c iguana_payments.c iguana_spendvectors.c iguana_sign.c iguana_txidfind.c iguana_realtime.c iguana_volatiles.c peggy_price.c SuperNET_category.c iguana_chains.c iguana_ramchain.c iguana_secp.c pangea_api.c peggy_ramkv.c SuperNET_hexmsg.c iguana_exchanges.c iguana_recv.c pangea_bets.c peggy_serdes.c SuperNET_keys.c iguana_rpc.c pangea_hand.c peggy_tx.c cards777.c iguana_init.c iguana_scripts.c pangea_json.c peggy_txind.c iguana777.c iguana_instantdex.c iguana_tradebots.c pangea_summary.c peggy_update.c iguana_accept.c iguana_json.c iguana_tx.c peggy.c poker.c iguana_bitmap.c iguana_msg.c iguana_unspents.c peggy_accts.c ramchain_api.c iguana_blocks.c iguana_peers.c iguana_wallet.c peggy_consensus.c databases/iguana_DB.c secp256k1/src/secp256k1.c \ No newline at end of file diff --git a/iguana/iguana777.c b/iguana/iguana777.c index a06b1f67e..41bd0ce19 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -15,7 +15,9 @@ #include "iguana777.h" -const char *Hardcoded_coins[][3] = { { "BTC", "bitcoin", "0" }, { "BTCD", "BitcoinDark", "129" }, { "VPN", "VPNcoin", "129" }, { "LTC", "litecoin", "129" } }; +#include "secp256k1/include/secp256k1.h" + +const char *Hardcoded_coins[][3] = { { "BTC", "bitcoin", "0" }, { "BTCD", "BitcoinDark", "129" }, { "VPN", "VPNcoin", "129" }, { "LTC", "litecoin", "129" } , { "endmarker", "", "" } }; struct iguana_info *iguana_coinfind(const char *symbol) { @@ -28,7 +30,7 @@ struct iguana_info *iguana_coinfind(const char *symbol) return(0); } -struct iguana_info *iguana_coinadd(const char *symbol) +struct iguana_info *iguana_coinadd(const char *symbol,cJSON *argjson) { struct iguana_info *coin; int32_t i = 0; if ( symbol == 0 ) @@ -40,8 +42,7 @@ struct iguana_info *iguana_coinadd(const char *symbol) { if ( Coins[i] == 0 ) { - Coins[i] = mycalloc('c',1,sizeof(*Coins[i])); - //memset(Coins[i],0,sizeof(*Coins[i])); + Coins[i] = mycalloc('C',1,sizeof(*Coins[i])); printf("iguana_coin.(new) -> %p\n",Coins[i]); return(Coins[i]); } return(0); @@ -52,20 +53,30 @@ struct iguana_info *iguana_coinadd(const char *symbol) { for (i=0; i= sizeof(Hardcoded_coins)/sizeof(*Hardcoded_coins) || Hardcoded_coins[i][0] == 0 ) + if ( i >= sizeof(Hardcoded_coins)/sizeof(*Hardcoded_coins) ) break; - if ( strcmp(symbol,Hardcoded_coins[i][0]) == 0 ) + //printf("Hardcoded_coins[i][0] %s vs.(%s)\n",Hardcoded_coins[i][0],symbol); + //if ( symbol[0] == 0 ) + // getchar(); + if ( strcmp("endmarker",Hardcoded_coins[i][0]) == 0 || strcmp(symbol,Hardcoded_coins[i][0]) == 0 ) { if ( Coins[i] == 0 ) - Coins[i] = mycalloc('c',1,sizeof(*Coins[i])); + Coins[i] = mycalloc('C',1,sizeof(*Coins[i])); coin = Coins[i]; if ( coin->chain == 0 ) { - strcpy(coin->name,Hardcoded_coins[i][1]); - //coin->myservices = atoi(Hardcoded_coins[i][2]); + if ( i < sizeof(Hardcoded_coins)/sizeof(*Hardcoded_coins) ) + strcpy(coin->name,Hardcoded_coins[i][1]); + else if (argjson != 0 ) + { + if ( jstr(argjson,"name") != 0 ) + safecopy(coin->name,jstr(argjson,"name"),sizeof(coin->name)); + else strcpy(coin->name,symbol); + } + coin->chain = iguana_chainfind((char *)symbol,argjson,1); + coin->ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); strcpy(coin->symbol,symbol); - coin->chain = iguana_chainfind(coin->symbol); - iguana_initcoin(coin); + iguana_initcoin(coin,argjson); } return(coin); } @@ -89,7 +100,7 @@ void iguana_recvalloc(struct iguana_info *coin,int32_t numitems) { //coin->blocks.ptrs = myrealloc('W',coin->blocks.ptrs,coin->blocks.ptrs==0?0:coin->blocks.maxbits * sizeof(*coin->blocks.ptrs),numitems * sizeof(*coin->blocks.ptrs)); coin->blocks.RO = myrealloc('W',coin->blocks.RO,coin->blocks.RO==0?0:coin->blocks.maxbits * sizeof(*coin->blocks.RO),numitems * sizeof(*coin->blocks.RO)); - printf("realloc waitingbits.%d -> %d\n",coin->blocks.maxbits,numitems); + //printf("realloc waitingbits.%d -> %d\n",coin->blocks.maxbits,numitems); coin->blocks.maxbits = numitems; } @@ -138,10 +149,11 @@ int32_t iguana_peermetrics(struct iguana_info *coin) addr = &coin->peers.active[i]; if ( addr->usock < 0 || addr->dead != 0 || addr->ready == 0 ) continue; + addr->pendblocks = 0; if ( addr->recvblocks > coin->peers.mostreceived ) coin->peers.mostreceived = addr->recvblocks; //printf("[%.0f %.0f] ",addr->recvblocks,addr->recvtotal); - sortbuf[n*2 + 0] = iguana_metric(addr,now,1.); + sortbuf[n*2 + 0] = iguana_metric(addr,now,.995); sortbuf[n*2 + 1] = i; n++; } @@ -156,7 +168,7 @@ int32_t iguana_peermetrics(struct iguana_info *coin) coin->peers.topmetrics[i] = sortbuf[i*2]; ind = (int32_t)sortbuf[i*2 +1]; coin->peers.ranked[i] = &coin->peers.active[ind]; - if ( sortbuf[i*2] > SMALLVAL && (double)i/n > .8 ) + if ( sortbuf[i*2] > SMALLVAL && (double)i/n > .8 && (time(NULL) - addr->ready) > 77 ) slowest = coin->peers.ranked[i]; //printf("(%.5f %s) ",sortbuf[i*2],coin->peers.ranked[i]->ipaddr); coin->peers.ranked[i]->rank = i + 1; @@ -169,9 +181,9 @@ int32_t iguana_peermetrics(struct iguana_info *coin) if ( i > 0 ) { coin->peers.avemetric = (sum / i); - if ( i >= (coin->MAXPEERS - 1) && slowest != 0 ) + if ( i >= 7*(coin->MAXPEERS/8) && slowest != 0 ) { - printf("prune slowest peer.(%s) numranked.%d\n",slowest->ipaddr,n); + printf("prune slowest peer.(%s) numranked.%d MAXPEERS.%d\n",slowest->ipaddr,n,coin->MAXPEERS); slowest->dead = 1; } } @@ -199,24 +211,42 @@ void *iguana_kviAddriterator(struct iguana_info *coin,struct iguanakv *kv,struct uint32_t iguana_updatemetrics(struct iguana_info *coin) { - char fname[512],tmpfname[512],oldfname[512]; int32_t i; struct iguana_peer *addr; FILE *fp; + char fname[512],tmpfname[512],oldfname[512],ipaddr[64]; int32_t i,j; struct iguana_peer *addr,*tmpaddr; FILE *fp; iguana_peermetrics(coin); - sprintf(fname,"confs/%s_peers.txt",coin->symbol), OS_compatible_path(fname); - sprintf(oldfname,"confs/%s_oldpeers.txt",coin->symbol), OS_compatible_path(oldfname); - sprintf(tmpfname,"tmp/%s/peers.txt",coin->symbol), OS_compatible_path(tmpfname); + sprintf(fname,"%s/%s_peers.txt",GLOBAL_CONFSDIR,coin->symbol), OS_compatible_path(fname); + sprintf(oldfname,"%s/%s_oldpeers.txt",GLOBAL_CONFSDIR,coin->symbol), OS_compatible_path(oldfname); + sprintf(tmpfname,"%s/%s/peers.txt",GLOBAL_TMPDIR,coin->symbol), OS_compatible_path(tmpfname); if ( (fp= fopen(tmpfname,"w")) != 0 ) { for (i=0; ipeers.numranked; i++) - if ( (addr= coin->peers.ranked[i]) != 0 && strcmp(addr->ipaddr,"127.0.0.1") != 0 ) - fprintf(fp,"%s\n",addr->ipaddr); + { + if ( (addr= coin->peers.ranked[i]) != 0 && addr->relayflag != 0 && strcmp(addr->ipaddr,"127.0.0.1") != 0 ) + { + for (j=0; jpeers.numranked; j++) + { + if ( i != j && (tmpaddr= coin->peers.ranked[j]) != 0 && (uint32_t)addr->ipbits == (uint32_t)tmpaddr->ipbits ) + break; + } + if ( j == coin->peers.numranked ) + { + expand_ipbits(ipaddr,(uint32_t)addr->ipbits); + fprintf(fp,"%s\n",ipaddr); + } + } + } if ( ftell(fp) > OS_filesize(fname) ) { - printf("new peers.txt %ld vs (%s) %ld\n",ftell(fp),fname,(long)OS_filesize(fname)); + printf("new peers.txt %ld vs (%s) %ld (%s)\n",ftell(fp),fname,(long)OS_filesize(fname),GLOBAL_CONFSDIR); fclose(fp); OS_renamefile(fname,oldfname); OS_copyfile(tmpfname,fname,1); } else fclose(fp); } + else + { + printf("iguana_updatemetrics: couldnt create.(%s)\n",tmpfname); + return(0); + } return((uint32_t)time(NULL)); } @@ -230,26 +260,14 @@ void iguana_emitQ(struct iguana_info *coin,struct iguana_bundle *bp) ptr->type = 'E'; ptr->starttime = (uint32_t)time(NULL); //printf("%s EMIT.%d[%d] emitfinish.%u\n",coin->symbol,ptr->hdrsi,bp->n,bp->emitfinish); - queue_enqueue("helperQ",&helperQ,&ptr->DL,0); -} - -void iguana_mergeQ(struct iguana_info *coin,struct iguana_bundle *bp,struct iguana_bundle *nextbp) -{ - struct iguana_helper *ptr; - ptr = mycalloc('i',1,sizeof(*ptr)); - ptr->allocsize = sizeof(*ptr); - ptr->coin = coin; - ptr->bp = bp, ptr->hdrsi = bp->hdrsi; - ptr->nextbp = nextbp; - ptr->type = 'M'; - ptr->starttime = (uint32_t)time(NULL); - //printf("%s EMIT.%d[%d] emitfinish.%u\n",coin->symbol,ptr->hdrsi,bp->n,bp->emitfinish); - queue_enqueue("helperQ",&helperQ,&ptr->DL,0); + queue_enqueue("emitQ",&emitQ,&ptr->DL,0); } void iguana_bundleQ(struct iguana_info *coin,struct iguana_bundle *bp,int32_t timelimit) { struct iguana_helper *ptr; + if ( bp->queued == 0 && bp->emitfinish <= 1 && iguana_bundleready(coin,bp,0) == bp->n ) + printf("bundle.[%d] is ready\n",bp->hdrsi); bp->queued = (uint32_t)time(NULL); ptr = mycalloc('i',1,sizeof(*ptr)); ptr->allocsize = sizeof(*ptr); @@ -259,222 +277,557 @@ void iguana_bundleQ(struct iguana_info *coin,struct iguana_bundle *bp,int32_t ti ptr->starttime = (uint32_t)time(NULL); ptr->timelimit = timelimit; coin->numbundlesQ++; - //printf("%s bundle.%d[%d] emitfinish.%u\n",coin->symbol,ptr->hdrsi,bp->n,bp->emitfinish); + if ( 0 && bp->hdrsi > 170 ) + printf("%s %p bundle.%d[%d] ht.%d emitfinish.%u\n",coin->symbol,bp,ptr->hdrsi,bp->n,bp->bundleheight,bp->emitfinish); queue_enqueue("bundlesQ",&bundlesQ,&ptr->DL,0); } -int32_t iguana_helpertask(FILE *fp,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_helper *ptr) +void iguana_validateQ(struct iguana_info *coin,struct iguana_bundle *bp) +{ + /*struct iguana_helper *ptr; + //if ( bp->validated <= 1 ) + { + ptr = mycalloc('i',1,sizeof(*ptr)); + ptr->allocsize = sizeof(*ptr); + ptr->coin = coin; + ptr->bp = bp, ptr->hdrsi = bp->hdrsi; + ptr->type = 'V'; + ptr->starttime = (uint32_t)time(NULL); + ptr->timelimit = 0; + bp->validated = 1; + //printf("VALIDATE Q %s bundle.%d[%d] utxofinish.%u balancefinish.%u\n",coin->symbol,ptr->hdrsi,bp->n,bp->utxofinish,bp->balancefinish); + queue_enqueue("validateQ",&validateQ,&ptr->DL,0); + }*/ +} + +int32_t iguana_emitfinished(struct iguana_info *coin,int32_t queueincomplete) +{ + struct iguana_bundle *bp; int32_t i,n = 0; + for (i=0; ibundlescount-1; i++) + { + if ( (bp= coin->bundles[i]) != 0 ) + { + if ( bp->emitfinish > 1 ) + n++; + else if ( bp->emitfinish == 0 && bp->queued == 0 ) + iguana_bundleQ(coin,bp,1000); + } + } + return(n); +} + +int32_t iguana_utxofinished(struct iguana_info *coin) +{ + struct iguana_bundle *bp; int32_t i,n = 0; + for (i=0; ibundlescount-1; i++) + { + if ( (bp= coin->bundles[i]) != 0 && bp->utxofinish > 1 ) + n++; + } + return(n); +} + +int32_t iguana_convertfinished(struct iguana_info *coin) +{ + struct iguana_bundle *bp; int32_t i,n = 0; + for (i=0; ibundlescount-1; i++) + { + if ( (bp= coin->bundles[i]) != 0 && bp->converted > 1 ) + n++; + } + return(n); +} + +int32_t iguana_balancefinished(struct iguana_info *coin) +{ + struct iguana_bundle *bp; int32_t i,n = 0; + for (i=0; ibundlescount-1; i++) + { + if ( (bp= coin->bundles[i]) != 0 && bp->balancefinish > 1 ) + n++; + } + return(n); +} + +int32_t iguana_validated(struct iguana_info *coin) +{ + struct iguana_bundle *bp; int32_t i,n = 0; + for (i=0; ibundlescount-1; i++) + { + if ( (bp= coin->bundles[i]) != 0 && bp->validated > 1 ) + n++; + } + return(n); +} + +int32_t iguana_helperA(struct iguana_info *coin,struct iguana_bundle *bp,int32_t convertflag) { - struct iguana_info *coin; struct iguana_peer *addr; struct iguana_bundle *bp,*nextbp; - addr = ptr->addr; - if ( (coin= ptr->coin) != 0 ) + int32_t retval,num = 0; + if ( bp == 0 ) + { + printf("iguana_helperA unexpected null bp\n"); + return(-1); + } + //printf("validate incr.%d and gen utxo.[%d] utxofinish.%u Xspends.%p\n",incr,hdrsi,bp->utxofinish,bp->ramchain.Xspendinds); + if ( strcmp("BTC",coin->symbol) == 0 || iguana_bundlevalidate(coin,bp,0) == bp->n ) // { - if ( (bp= ptr->bp) != 0 ) + retval = 0; + if ( bp->utxofinish > 1 || (retval= iguana_spendvectors(coin,bp,&bp->ramchain,0,bp->n,convertflag,0)) >= 0 ) { - if ( 0 && ptr->type == 'M' ) + if ( retval > 0 ) { - if ( (nextbp= ptr->nextbp) != 0 ) - { - bp->mergefinish = nextbp->mergefinish = (uint32_t)time(NULL); - if ( iguana_bundlemergeHT(coin,mem,memB,bp,nextbp,ptr->starttime) < 0 ) - bp->mergefinish = nextbp->mergefinish = 0; - } + printf("GENERATED UTXO.%d for ht.%d duration %d seconds\n",bp->hdrsi,bp->bundleheight,(uint32_t)time(NULL) - bp->startutxo); + num++; } - else if ( ptr->type == 'B' ) + bp->utxofinish = (uint32_t)time(NULL); + } else printf("UTXO gen.[%d] utxo error\n",bp->hdrsi); + } + else + { + printf("error validating.[%d], restart iguana\n",bp->hdrsi); + exit(-1); + } + return(num); +} + +int32_t iguana_helperB(struct iguana_info *coin,int32_t helperid,struct iguana_bundle *bp,int32_t convertflag) +{ + if ( bp == 0 ) + { + printf("iguana_helperB unexpected null bp\n"); + return(-1); + } + if ( bp != coin->current ) + { + iguana_ramchain_prefetch(coin,&bp->ramchain,7); + if ( convertflag == 0 ) + { + bp->converted = 1; + iguana_convert(coin,helperid,bp,0,0); + } + bp->converted = (uint32_t)time(NULL); + return(1); + } + return(0); +} + +int32_t iguana_utxogen(struct iguana_info *coin,int32_t helperid,int32_t convertflag) +{ + int32_t hdrsi,n,i,max,incr,num = 0; struct iguana_bundle *bp; + if ( coin->spendvectorsaved > 1 ) + { + printf("skip utxogen as spendvectorsaved.%u\n",coin->spendvectorsaved); + return(0); + } + printf("helperid.%d start utxogen\n",helperid); + incr = 1;//IGUANA_NUMHELPERS; + //if ( 1 || coin->PREFETCHLAG > 0 ) // data issues on slow systems + // incr = 1; + max = coin->bundlescount; + if ( coin->bundles[max-1] != 0 && coin->bundles[max-1]->emitfinish <= 1 ) + max--; + if ( helperid < incr ) + { + for (hdrsi=helperid; hdrsibundles[hdrsi],convertflag); + } + while ( (n= iguana_utxofinished(coin)) < max ) + { + //printf("helperid.%d utxofinished.%d vs %d\n",helperid,n,max); + sleep(IGUANA_NUMHELPERS+3); + } + if ( helperid < incr ) + { + for (hdrsi=helperid; hdrsibundles[hdrsi],convertflag); + } + while ( (n= iguana_convertfinished(coin)) < max ) + { + //printf("helperid.%d convertfinished.%d vs max %d bundlescount.%d\n",helperid,n,max,coin->bundlescount); + sleep(IGUANA_NUMHELPERS+3); + } + if ( helperid == 0 ) + { + if ( iguana_balancefinished(coin) < max && iguana_spendvectorsaves(coin) == 0 ) + { + if ( 1 || coin->origbalanceswritten <= 1 ) + hdrsi = 0; + else hdrsi = coin->origbalanceswritten; + for (i=0; ibundles[i]) != 0 && bp != coin->current ) + iguana_volatilesalloc(coin,&bp->ramchain,i < hdrsi); + for (; hdrsitimelimit); + if ( (bp= coin->bundles[hdrsi]) != 0 ) + { + //iguana_ramchain_prefetch(coin,&bp->ramchain,3); + if ( iguana_balancegen(coin,0,bp,0,coin->chain->bundlesize-1,0) == 0 ) + bp->balancefinish = (uint32_t)time(NULL); + } } - else if ( ptr->type == 'E' ) + if ( max != coin->origbalanceswritten ) { - //printf("emitQ coin.%p bp.%p\n",ptr->coin,ptr->bp); - if ( iguana_bundlesaveHT(coin,mem,memB,bp,ptr->starttime) == 0 ) + coin->balanceflush = max+1; + while ( coin->balanceflush != 0 ) + sleep(3); + } else printf("skip flush when max.%d and orig.%d\n",max,coin->origbalanceswritten); + } + if ( 1 ) + { + for (i=0; ibundles[i]) != 0 ) { - bp->emitfinish = (uint32_t)time(NULL); - coin->numemitted++; + //iguana_volatilespurge(coin,&bp->ramchain); + iguana_volatilesmap(coin,&bp->ramchain); } - else bp->emitfinish = 0; - } - } else printf("no bundle in helperrequest\n"); - } else printf("no coin in helperrequest\n"); - return(0); + } + } + while ( iguana_balancefinished(coin) < max || coin->balanceflush != 0 ) + sleep(3); + //printf("helper.%d check validates\n",helperid); + incr = IGUANA_NUMHELPERS; + if ( helperid < incr ) + { + for (hdrsi=helperid; hdrsibundles[hdrsi]) == 0 ) + break; + if ( iguana_bundlevalidate(coin,bp,0) != bp->n ) + { + printf("validate.[%d] error. refresh page or restart iguana and it should regenerate\n",bp->hdrsi); + exit(-1); + } //else printf("helperid.%d validated.[%d]\n",helperid,hdrsi); + } + } + /*while ( iguana_validated(coin) < max || iguana_utxofinished(coin) < max || iguana_balancefinished(coin) < max ) + { + printf("helperid.%d waiting for spendvectorsaved.%u v.%d u.%d b.%d vs max.%d\n",helperid,coin->spendvectorsaved,iguana_validated(coin),iguana_utxofinished(coin),iguana_balancefinished(coin),max); + sleep(IGUANA_NUMHELPERS+3); + }*/ + if ( helperid == 0 ) + { + coin->spendvectorsaved = (uint32_t)time(NULL); + //printf("UTXOGEN spendvectorsaved <- %u\n",coin->spendvectorsaved); + } + else + { + while ( coin->spendvectorsaved <= 1 ) + sleep(IGUANA_NUMHELPERS+3); + } + //printf("helper.%d helperdone\n",helperid); + return(num); } void iguana_helper(void *arg) { - FILE *fp = 0; char fname[512],name[64],*helpername = 0; cJSON *argjson=0; int32_t flag; - struct iguana_helper *ptr; struct iguana_info *coin; struct OS_memspace MEM,*MEMB; + cJSON *argjson=0; int32_t iter,i,n,j,polltimeout,type,helperid=rand(),flag,allcurrent,idle=0; + struct iguana_helper *ptr; struct iguana_info *coin; struct OS_memspace MEM,*MEMB; struct iguana_bundle *bp; if ( arg != 0 && (argjson= cJSON_Parse(arg)) != 0 ) - helpername = jstr(argjson,"name"); - if ( helpername == 0 ) - { - sprintf(name,"helper.%d",rand()); - helpername = name; - } - sprintf(fname,"tmp/%s",helpername); - OS_compatible_path(fname); - fp = fopen(fname,"wb"); + helperid = juint(argjson,"helperid"); + if ( IGUANA_NUMHELPERS < 2 ) + type = 3; + else type = (1 << (helperid % 2)); if ( argjson != 0 ) free_json(argjson); + printf("HELPER.%d started arg.(%s) type.%d\n",helperid,(char *)(arg!=0?arg:0),type); memset(&MEM,0,sizeof(MEM)); MEMB = mycalloc('b',IGUANA_MAXBUNDLESIZE,sizeof(*MEMB)); + sleep(2); while ( 1 ) { - //iguana_jsonQ(); + //iguana_jsonQ(); cant do this here flag = 0; - if ( (ptr= queue_dequeue(&helperQ,0)) != 0 ) + allcurrent = 2; + polltimeout = 100; + for (i=0; icoin) != 0 && myallocated(0,-1) > coin->MAXMEM ) - queue_enqueue("reQ",&helperQ,&ptr->DL,0); - else + if ( (coin= Coins[i]) != 0 ) { - coin->helperdepth++; - iguana_helpertask(fp,&MEM,MEMB,ptr); - coin->helperdepth--; - myfree(ptr,ptr->allocsize); + if ( coin->spendvectorsaved == 1 ) + iguana_utxogen(coin,helperid,0); + else if ( coin->spendvectorsaved > 1 ) + { + for (j=helperid; jbundlescount-1; j+=IGUANA_NUMHELPERS) + if ( (bp= coin->bundles[j]) != 0 ) + iguana_bundlevalidate(coin,bp,0); + } } - flag++; } - else + n = queue_size(&bundlesQ); + for (iter=0; iterbp != 0 && ptr->coin != 0 ) - flag += iguana_bundleiters(ptr->coin,ptr->bp,ptr->timelimit); + idle = 0; + coin = ptr->coin; + if ( (bp= ptr->bp) != 0 && coin != 0 ) + { + if ( coin->polltimeout < polltimeout ) + polltimeout = coin->polltimeout; + if ( coin->current != 0 && coin->current->hdrsi != coin->bundlescount-1 ) + allcurrent = 0; + //printf("[%d] bundleQ size.%d lag.%ld\n",bp->hdrsi,queue_size(&bundlesQ),time(NULL) - bp->nexttime); + coin->numbundlesQ--; + if ( coin->started != 0 && (bp->nexttime == 0 || time(NULL) > bp->nexttime) && coin->active != 0 ) + { + flag += iguana_bundleiters(ptr->coin,&MEM,MEMB,bp,ptr->timelimit,IGUANA_DEFAULTLAG); + } + else + { + //printf("skip.[%d] nexttime.%u lag.%ld coin->active.%d\n",bp->hdrsi,bp->nexttime,time(NULL)-bp->nexttime,coin->active); + allcurrent--; + iguana_bundleQ(coin,bp,1000); + } + } + else //if ( coin->active != 0 ) + printf("helper missing param? %p %p %u\n",ptr->coin,bp,ptr->timelimit); myfree(ptr,ptr->allocsize); + } else break; + } + /*n = queue_size(&validateQ) / IGUANA_NUMHELPERS + 1; + printf("vQ is n.%d\n",n); + for (iter=0; iterbp) != 0 && (coin= ptr->coin) != 0 && coin->active != 0 ) + { + printf("helper.%d validate.[%d] %d vs %d\n",helperid,bp->hdrsi,coin->blocks.hwmchain.height/coin->chain->bundlesize,(coin->longestchain-1)/coin->chain->bundlesize); + if ( coin->blocks.hwmchain.height/coin->chain->bundlesize >= (coin->longestchain-1)/coin->chain->bundlesize ) + flag += iguana_bundlevalidate(coin,bp,0); + else + { + usleep(10000); + printf("requeue vQ.[%d]\n",bp->hdrsi); + iguana_validateQ(coin,bp); + } } + else if ( coin->active != 0 ) + printf("helper validate missing param? %p %p\n",ptr->coin,ptr->bp); + myfree(ptr,ptr->allocsize); + flag++; + }*/ + if ( queue_size(&bundlesQ) > 1 ) + allcurrent = 0; + if ( flag != 0 ) + usleep(polltimeout * 100 + 1); + else if ( allcurrent > 0 ) + { + //printf("bundlesQ allcurrent\n"); + usleep(polltimeout * 10000); } - if ( flag == 0 ) - sleep(10); + else usleep(polltimeout * 1000); } } void iguana_coinloop(void *arg) { struct iguana_info *coin,**coins = arg; - struct iguana_bundle *bp; int32_t flag,i,n,bundlei; bits256 zero; char str[1024]; + struct iguana_bundle *bp; int32_t flag,i,n,bundlei; bits256 zero; char str[2065]; uint32_t now; n = (int32_t)(long)coins[0]; coins++; printf("begin coinloop[%d]\n",n); - for (i=0; istarted == 0 ) - { - iguana_coinstart(coin,coin->initialheight,coin->mapflags); - printf("init.(%s) maxpeers.%d maxrecvcache.%s services.%llx MAXMEM.%s polltimeout.%d\n",coin->symbol,coin->MAXPEERS,mbstr(str,coin->MAXRECVCACHE),(long long)coin->myservices,mbstr(str,coin->MAXMEM),coin->polltimeout); - coin->started = coin; - coin->chain->minconfirms = coin->minconfirms; - } - } coin = coins[0]; - iguana_rwiAddrind(coin,0,0,0); - iguana_possible_peer(coin,"127.0.0.1"); - //while ( 1 ) sleep(1); - + iguana_launchpeer(coin,"127.0.0.1"); memset(zero.bytes,0,sizeof(zero)); - if ( (bp= iguana_bundlecreate(coin,&bundlei,0,*(bits256 *)coin->chain->genesis_hashdata,zero,1)) != 0 ) - bp->bundleheight = 0; while ( 1 ) { - //printf("iter\n"); flag = 0; for (i=0; iMAXPEERS > IGUANA_MAXPEERS ) + coin->MAXPEERS = IGUANA_MAXPEERS; + if ( coin->MAXPEERS < IGUANA_MINPEERS ) + coin->MAXPEERS = IGUANA_MAXPEERS; +#ifdef __PNACL__ + if ( strcmp(coin->symbol,"BTC") == 0 ) + continue; + if ( coin->MAXPEERS > 64 ) + coin->MAXPEERS = 64; +#endif + if ( coin->started == 0 && coin->active != 0 ) + { + iguana_rwiAddrind(coin,0,0,0); + iguana_coinstart(coin,coin->initialheight,coin->mapflags); + printf("init.(%s) maxpeers.%d maxrecvcache.%s services.%llx MAXMEM.%s polltimeout.%d cache.%d pend.(%d -> %d)\n",coin->symbol,coin->MAXPEERS,mbstr(str,coin->MAXRECVCACHE),(long long)coin->myservices,mbstr(str,coin->MAXMEM),coin->polltimeout,coin->enableCACHE,coin->startPEND,coin->endPEND); + coin->chain->minconfirms = coin->minconfirms; + coin->started = coin; + coin->startutc = (uint32_t)time(NULL); + if ( (bp= iguana_bundlecreate(coin,&bundlei,0,*(bits256 *)coin->chain->genesis_hashdata,zero,1)) != 0 ) + bp->bundleheight = 0; + } now = (uint32_t)time(NULL); - if ( coin->active != 0 ) + coin->idletime = 0; + if ( coin->started != 0 && coin->active != 0 ) { - if ( coin->isRT == 0 && now > coin->startutc+600 && coin->blocksrecv >= coin->longestchain-1 && coin->blocks.hwmchain.height >= coin->longestchain-1 ) + if ( coin->peers.numranked > 4 && coin->isRT == 0 && now > coin->startutc+77 && coin->numsaved >= (coin->longestchain/coin->chain->bundlesize)*coin->chain->bundlesize && coin->blocks.hwmchain.height >= coin->longestchain-30 ) { - printf(">>>>>>> %s isRT blockrecv.%d vs longest.%d\n",coin->symbol,coin->blocksrecv,coin->longestchain); + fprintf(stderr,">>>>>>> %s isRT blockrecv.%d vs longest.%d\n",coin->symbol,coin->blocksrecv,coin->longestchain); coin->isRT = 1; if ( coin->polltimeout > 100 ) coin->polltimeout = 100; - coin->MAXPEERS = 8; + if ( coin->MAXPEERS > IGUANA_MINPEERS ) + coin->MAXPEERS = IGUANA_MINPEERS; + } + if ( coin->isRT != 0 && coin->current != 0 && coin->numverified >= coin->current->hdrsi ) + { + //static int32_t saved; + //if ( saved++ == 0 ) + // iguana_coinflush(coin,1); } if ( coin->bindsock >= 0 ) { - if ( coin->peers.numranked < 8 && now > coin->lastpossible+60 ) + if ( coin->peers.numranked < (7*coin->MAXPEERS/8) && now > coin->lastpossible ) { - //printf("possible\n"); + //fprintf(stderr,"possible\n"); + if ( coin->peers.numranked > 0 && (now % 60) == 0 ) + iguana_send_ping(coin,coin->peers.ranked[rand() % coin->peers.numranked]); coin->lastpossible = iguana_possible_peer(coin,0); // tries to connect to new peers } } else { - if ( coin->peers.numranked != 0 && coin->peers.numranked < (coin->MAXPEERS>>1) && now > coin->lastpossible+6 ) + if ( coin->peers.numranked < ((7*coin->MAXPEERS)>>3) && now > coin->lastpossible ) { - //printf("possible\n"); + if ( coin->peers.numranked > 0 && (now % 60) == 0 ) + iguana_send_ping(coin,coin->peers.ranked[rand() % coin->peers.numranked]); coin->lastpossible = iguana_possible_peer(coin,0); // tries to connect to new peers } } - if ( now > coin->peers.lastmetrics+6 ) + if ( now > coin->peers.lastmetrics+10 ) { - //printf("metrics\n"); + //fprintf(stderr,"metrics\n"); coin->peers.lastmetrics = iguana_updatemetrics(coin); // ranks peers } - //printf("process\n"); - iguana_bundlestats(coin,str); + if ( coin->longestchain+10000 > coin->blocks.maxbits ) + iguana_recvalloc(coin,coin->longestchain + 100000); flag += iguana_processrecv(coin); } + coin->idletime = (uint32_t)time(NULL); } } - if ( flag == 0 ) - usleep(coin->polltimeout * 1000); + if ( flag == 0 && coin->isRT == 0 ) + usleep(coin->polltimeout*1000 + (coin->peers.numranked == 0)*1000000); + else if ( coin->current != 0 && coin->current->hdrsi == coin->longestchain/coin->chain->bundlesize ) + usleep(coin->polltimeout*1000 + 90000 + (coin->peers.numranked == 0)*1000000); + else usleep(coin->polltimeout*1000); } } -void iguana_coinargs(char *symbol,int64_t *maxrecvcachep,int32_t *minconfirmsp,int32_t *maxpeersp,int32_t *initialheightp,uint64_t *servicesp,int32_t *maxpendingp,int32_t *maxbundlesp,cJSON *json) +void iguana_coinargs(char *symbol,int64_t *maxrecvcachep,int32_t *minconfirmsp,int32_t *maxpeersp,int32_t *initialheightp,uint64_t *servicesp,int32_t *maxrequestsp,int32_t *maxbundlesp,cJSON *json) { if ( (*maxrecvcachep= j64bits(json,"maxrecvcache")) != 0 ) *maxrecvcachep *= 1024 * 1024 * 1024L; *minconfirmsp = juint(json,"minconfirms"); *maxpeersp = juint(json,"maxpeers"); - *maxpendingp = juint(json,"maxpending"); + *maxrequestsp = juint(json,"maxrequests"); *maxbundlesp = juint(json,"maxbundles"); if ( (*initialheightp= juint(json,"initialheight")) == 0 ) *initialheightp = (strcmp(symbol,"BTC") == 0) ? 400000 : 100000; *servicesp = j64bits(json,"services"); } -struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers,int64_t maxrecvcache,uint64_t services,int32_t initialheight,int32_t maphash,int32_t minconfirms,int32_t maxpending,int32_t maxbundles,cJSON *json) +struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers,int64_t maxrecvcache,uint64_t services,int32_t initialheight,int32_t maphash,int32_t minconfirms,int32_t maxrequests,int32_t maxbundles,cJSON *json) { struct iguana_chain *iguana_createchain(cJSON *json); - struct iguana_info *coin; int32_t j,m,mapflags; char dirname[512]; cJSON *peers; + struct iguana_info *coin; int32_t j,m,mult,maxval,mapflags; char dirname[512]; cJSON *peers; mapflags = IGUANA_MAPRECVDATA | maphash*IGUANA_MAPTXIDITEMS | maphash*IGUANA_MAPPKITEMS | maphash*IGUANA_MAPBLOCKITEMS | maphash*IGUANA_MAPPEERITEMS; - coin = iguana_coinadd(symbol); - coin->launched = launched; + coin = iguana_coinadd(symbol,json); if ( (coin->MAXPEERS= maxpeers) <= 0 ) - coin->MAXPEERS = (strcmp(symbol,"BTC") == 0) ? 64 : 32; + coin->MAXPEERS = (strcmp(symbol,"BTC") == 0) ? 128 : 64; if ( (coin->MAXRECVCACHE= maxrecvcache) == 0 ) coin->MAXRECVCACHE = IGUANA_MAXRECVCACHE; - if ( (coin->MAXPENDING= maxpending) <= 0 ) - coin->MAXPENDING = (strcmp(symbol,"BTC") == 0) ? _IGUANA_MAXPENDING : _IGUANA_MAXPENDING*32; - if ( (coin->MAXBUNDLES= maxbundles) <= 0 ) - coin->MAXBUNDLES = (strcmp(symbol,"BTC") == 0) ? _IGUANA_MAXBUNDLES : _IGUANA_MAXBUNDLES*64; + if ( (coin->MAXPENDINGREQUESTS= maxrequests) <= 0 ) + coin->MAXPENDINGREQUESTS = (strcmp(symbol,"BTC") == 0) ? IGUANA_MAXPENDINGREQUESTS : IGUANA_PENDINGREQUESTS; coin->myservices = services; - sprintf(dirname,"DB/%s",symbol); - OS_ensure_directory(dirname); - sprintf(dirname,"tmp/%s",symbol); - OS_ensure_directory(dirname); coin->initialheight = initialheight; coin->mapflags = mapflags; + mult = (strcmp("BTC",coin->symbol) != 0) ? 8 : 8; + maxval = IGUANA_MAXPENDBUNDLES; coin->MAXMEM = juint(json,"RAM"); + if ( jobj(json,"prefetchlag") != 0 ) + coin->PREFETCHLAG = jint(json,"prefetchlag"); + else if ( strcmp("BTC",coin->symbol) == 0 ) + coin->PREFETCHLAG = 13; + else coin->PREFETCHLAG = -1; + if ( (coin->MAXSTUCKTIME= juint(json,"maxstuck")) == 0 ) + coin->MAXSTUCKTIME = _IGUANA_MAXSTUCKTIME; if ( coin->MAXMEM == 0 ) coin->MAXMEM = IGUANA_DEFAULTRAM; - coin->MAXMEM *= (1024 * 1024 * 1024); + //if ( strcmp("BTC",coin->symbol) == 0 && coin->MAXMEM < 4 ) + // maxval = (int32_t)coin->MAXMEM; + coin->MAXMEM *= (1024L * 1024 * 1024); +#ifdef __PNACL__ + maxval = 1;// * (strcmp("BTC",coin->symbol) != 0) + 8; + //if ( mult > 1 ) + // mult /= 2; +#endif + if ( (coin->startPEND= juint(json,"startpend")) == 0 ) + { + if ( strcmp("BTCD",coin->symbol) == 0 ) + coin->startPEND = 500; + else coin->startPEND = IGUANA_MAXPENDBUNDLES*mult; + } + if ( coin->startPEND > maxval*mult ) + coin->startPEND = maxval*mult; + else if ( coin->startPEND < 2 ) + coin->startPEND = 2; + coin->MAXBUNDLES = coin->startPEND; + if ( (coin->endPEND= juint(json,"endpend")) == 0 ) + { + if ( strcmp("BTCD",coin->symbol) == 0 ) + coin->endPEND = 500; + else coin->endPEND = IGUANA_MINPENDBUNDLES*mult; + } + if ( coin->endPEND > maxval*mult ) + coin->endPEND = maxval*mult; + else if ( coin->endPEND < 2 ) + coin->endPEND = 2; +#ifdef __PNACL__ + //coin->startPEND = coin->endPEND = 1; +#endif + coin->enableCACHE = 0;//(strcmp("BTC",coin->symbol) != 0); + if ( jobj(json,"cache") != 0 ) + coin->enableCACHE = juint(json,"cache"); if ( (coin->polltimeout= juint(json,"poll")) <= 0 ) - coin->polltimeout = 10; - char str[65]; printf("MAXMEM.%s\n",mbstr(str,coin->MAXMEM)); + coin->polltimeout = IGUANA_DEFAULT_POLLTIMEOUT; coin->active = juint(json,"active"); if ( (coin->minconfirms = minconfirms) == 0 ) coin->minconfirms = (strcmp(symbol,"BTC") == 0) ? 3 : 10; + printf("ensure directories maxval.%d mult.%d start.%d end.%d\n",maxval,mult,coin->startPEND,coin->endPEND); + sprintf(dirname,"%s/ro",GLOBAL_DBDIR), OS_ensure_directory(dirname); + sprintf(dirname,"%s/ro/%s",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname); + sprintf(dirname,"%s/%s",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname); + sprintf(dirname,"%s/%s/validated",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname); + sprintf(dirname,"%s/%s/accounts",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname); + sprintf(dirname,"%s/%s/spends",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname); + sprintf(dirname,"%s/%s/vouts",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname); + if ( coin->VALIDATEDIR[0] != 0 ) + { + sprintf(dirname,"%s",coin->VALIDATEDIR), OS_ensure_directory(dirname); + sprintf(dirname,"%s/%s",coin->VALIDATEDIR,symbol), OS_ensure_directory(dirname); + } + sprintf(dirname,"%s/%s",GLOBAL_TMPDIR,symbol), OS_ensure_directory(dirname); if ( coin->chain == 0 && (coin->chain= iguana_createchain(json)) == 0 ) { printf("cant initialize chain.(%s)\n",jstr(json,0)); + strcpy(coin->name,"illegalcoin"); + coin->symbol[0] = 0; return(0); - } + } else iguana_chainparms(coin->chain,json); + if ( jobj(json,"RELAY") != 0 ) + coin->RELAYNODE = juint(json,"RELAY"); + else coin->RELAYNODE = 1; + if ( jobj(json,"VALIDATE") != 0 ) + coin->VALIDATENODE = juint(json,"VALIDATE"); + else coin->VALIDATENODE = 1; + if ( jobj(json,"validatedir") != 0 ) + safecopy(coin->VALIDATEDIR,jstr(json,"validatedir"),sizeof(coin->VALIDATEDIR)); + else strcpy(coin->VALIDATEDIR,GLOBAL_VALIDATEDIR); if ( (peers= jarray(&m,json,"peers")) != 0 ) { for (j=0; j %d) MAXMEM.%s enablecache.%d VALIDATEDIR.(%s)\n",coin->startPEND,coin->endPEND,mbstr(str,coin->MAXMEM),coin->enableCACHE,coin->VALIDATEDIR); return(coin); } -int32_t iguana_launchcoin(char *symbol,cJSON *json) +int32_t iguana_launchcoin(struct supernet_info *myinfo,char *symbol,cJSON *json) { - int32_t maxpeers,maphash,initialheight,minconfirms,maxpending,maxbundles; + int32_t maxpeers,maphash,initialheight,minconfirms,maxrequests,maxbundles; int64_t maxrecvcache; uint64_t services; struct iguana_info **coins,*coin; if ( symbol == 0 ) return(-1); - if ( (coin= iguana_coinadd(symbol)) == 0 ) + printf("launchcoin.%s\n",symbol); + if ( (coin= iguana_coinadd(symbol,json)) == 0 ) return(-1); + if ( myinfo->rpcsymbol[0] == 0 || iguana_coinfind(myinfo->rpcsymbol) == 0 ) + strcpy(myinfo->rpcsymbol,symbol); if ( coin->launched == 0 ) { if ( juint(json,"GBavail") < 8 ) maphash = IGUANA_MAPHASHTABLES; else maphash = 0; - iguana_coinargs(symbol,&maxrecvcache,&minconfirms,&maxpeers,&initialheight,&services,&maxpending,&maxbundles,json); + iguana_coinargs(symbol,&maxrecvcache,&minconfirms,&maxpeers,&initialheight,&services,&maxrequests,&maxbundles,json); coins = mycalloc('A',1+1,sizeof(*coins)); - if ( (coin= iguana_setcoin(coin->symbol,coins,maxpeers,maxrecvcache,services,initialheight,maphash,minconfirms,maxpending,maxbundles,json)) != 0 ) + if ( (coin= iguana_setcoin(symbol,coins,maxpeers,maxrecvcache,services,initialheight,maphash,minconfirms,maxrequests,maxbundles,json)) != 0 ) { coins[0] = (void *)((long)1); coins[1] = coin; printf("launch coinloop for.%s services.%llx\n",coin->symbol,(long long)services); - iguana_launch(coin,"iguana_coinloop",iguana_coinloop,coins,IGUANA_PERMTHREAD); + coin->launched = iguana_launch(coin,"iguana_coinloop",iguana_coinloop,coins,IGUANA_PERMTHREAD); coin->active = 1; return(1); } else { + printf("launchcoin: couldnt initialize.(%s)\n",symbol); myfree(coins,sizeof(*coins) * 2); return(-1); } @@ -523,8 +881,9 @@ int32_t iguana_launchcoin(char *symbol,cJSON *json) void iguana_coins(void *arg) { struct iguana_info **coins,*coin; char *jsonstr,*symbol; cJSON *array,*item,*json; - int32_t i,n,maxpeers,maphash,initialheight,minconfirms,maxpending,maxbundles; - int64_t maxrecvcache; uint64_t services; + int32_t i,n,maxpeers,maphash,initialheight,minconfirms,maxrequests,maxbundles; + int64_t maxrecvcache; uint64_t services; struct vin_info V; + memset(&V,0,sizeof(V)); if ( (jsonstr= arg) != 0 && (json= cJSON_Parse(jsonstr)) != 0 ) { if ( (array= jarray(&n,json,"coins")) == 0 ) @@ -532,9 +891,17 @@ void iguana_coins(void *arg) if ( (symbol= jstr(json,"coin")) != 0 && strncmp(symbol,"BTC",3) == 0 ) { coins = mycalloc('A',1+1,sizeof(*coins)); - coins[1] = iguana_setcoin(symbol,coins,0,0,0,0,0,0,0,0,json); - coins[0] = (void *)((long)1); - iguana_coinloop(coins); + if ( (coins[1]= iguana_setcoin(symbol,coins,0,0,0,0,0,0,0,0,json)) != 0 ) + { + _iguana_calcrmd160(coins[1],&V); + coins[0] = (void *)((long)1); + iguana_coinloop(coins); + } + else + { + printf("iguana_coins: couldnt initialize.(%s)\n",symbol); + return; + } } else printf("no coins[] array in JSON.(%s) only BTCD and BTC can be quicklaunched\n",jsonstr); free_json(json); return; @@ -551,8 +918,13 @@ void iguana_coins(void *arg) printf("skip strange coin.(%s)\n",symbol); continue; } - iguana_coinargs(symbol,&maxrecvcache,&minconfirms,&maxpeers,&initialheight,&services,&maxpending,&maxbundles,item); - coins[1 + i] = coin = iguana_setcoin(symbol,coins,maxpeers,maxrecvcache,services,initialheight,maphash,minconfirms,maxpending,maxbundles,item); + iguana_coinargs(symbol,&maxrecvcache,&minconfirms,&maxpeers,&initialheight,&services,&maxrequests,&maxbundles,item); + coins[1 + i] = coin = iguana_setcoin(symbol,coins,maxpeers,maxrecvcache,services,initialheight,maphash,minconfirms,maxrequests,maxbundles,item); + if ( coin == 0 ) + { + printf("iguana_coins: couldnt initialize.(%s)\n",symbol); + return; + } } coins[0] = (void *)((long)n); iguana_coinloop(coins); @@ -564,4 +936,3 @@ char *busdata_sync(uint32_t *noncep,char *jsonstr,char *broadcastmode,char *dest printf("busdata_sync.(%s)\n",jsonstr); return(0); } - diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 5adc10fac..9c8002e53 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -18,11 +18,25 @@ #include "../crypto777/OS_portable.h" #include "SuperNET.h" -#define IGUANA_MAXSCRIPTSIZE 8192 +#define SPARSECOUNT(x) ((x) << 1) +typedef int32_t (*blockhashfunc)(uint8_t *blockhashp,uint8_t *serialized,int32_t len); + +#define IGUANA_MAXSCRIPTSIZE 10001 +#define IGUANA_SERIALIZE_SPENDVECTORGEN //#define IGUANA_DISABLEPEERS +#define _IGUANA_MAXSTUCKTIME 10 +#ifdef __PNACL__ +#define IGUANA_MAXITERATIONS 77 +#else +#define IGUANA_MAXITERATIONS 10000 +#endif +#define IGUANA_DEFAULTLAG 30 + +#define IGUANA_MAXHEIGHT (1 << 30) #define IGUANA_MAXCOINS 64 #define IGUANA_MAXDELAY_MILLIS (3600 * 1000) +#define IGUANA_DEFAULT_POLLTIMEOUT 10 #define IGUANA_EXCHANGEIDLE 10 #define IGUANS_JSMILLIS 100 @@ -30,20 +44,27 @@ #define IGUANA_WIDTH 1024 #define IGUANA_HEIGHT 200 +#define IGUANA_HEADPERCENTAGE 0. +#define IGUANA_TAILPERCENTAGE 1.0 #define IGUANA_MAXPENDHDRS 1 -#define _IGUANA_MAXPENDING 64 //64 -#define _IGUANA_MAXBUNDLES 8 -#define IGUANA_MAXACTIVEBUNDLES 32 -#define IGUANA_MAXFILES 4096 -#define IGUANA_BUNDLELOOP 100 +#define IGUANA_MAXPENDINGREQUESTS 8 +#define IGUANA_PENDINGREQUESTS 500 +#define IGUANA_MINPENDBUNDLES 4 +#define IGUANA_MAXPENDBUNDLES 64 +#ifdef __APPLE__ +#define IGUANA_RPCPORT 7778 +#else #define IGUANA_RPCPORT 7778 +#endif #define IGUANA_MAXRAMCHAINSIZE ((uint64_t)1024L * 1024L * 1024L * 16) #define IGUANA_MAPHASHTABLES 1 #define IGUANA_DEFAULTRAM 4 #define IGUANA_MAXRECVCACHE ((int64_t)1024L * 1024 * 1024L) -#define IGUANA_MAXBUNDLES (5000000 / 500) -#define IGUANA_LOG2MAXPEERS 9 +#define IGUANA_MAXBUNDLES (50000000 / 500) + +#define IGUANA_MINPEERS 24 +#define IGUANA_LOG2MAXPEERS 10 #define IGUANA_LOG2PACKETSIZE 21 #define IGUANA_LOG2PEERFILESIZE 23 @@ -53,7 +74,6 @@ struct iguana_txdatabits { uint64_t addrind:IGUANA_LOG2MAXPEERS,filecount:10,fpos:IGUANA_LOG2PEERFILESIZE,datalen:IGUANA_LOG2PACKETSIZE,isdir:1; }; #define IGUANA_MAXFILEITEMS 8192 - #define IGUANA_RECENTPEER (3600 * 24 * 7) #define IGUANA_PERMTHREAD 0 @@ -65,15 +85,16 @@ struct iguana_txdatabits { uint64_t addrind:IGUANA_LOG2MAXPEERS,filecount:10,fpo #define IGUANA_DEDICATED_THREADS #ifdef IGUANA_DEDICATED_THREADS -#define IGUANA_MAXCONNTHREADS 3 -#define IGUANA_MAXSENDTHREADS IGUANA_MAXPEERS -#define IGUANA_MAXRECVTHREADS IGUANA_MAXPEERS +#define IGUANA_MAXCONNTHREADS IGUANA_MINPEERS +#define IGUANA_MAXSENDTHREADS (IGUANA_MAXPEERS>>2) +#define IGUANA_MAXRECVTHREADS (IGUANA_MAXPEERS>>2) #else -#define IGUANA_MAXCONNTHREADS 64 -#define IGUANA_MAXSENDTHREADS 64 -#define IGUANA_MAXRECVTHREADS 64 +#define IGUANA_MAXCONNTHREADS 16 +#define IGUANA_MAXSENDTHREADS 16 +#define IGUANA_MAXRECVTHREADS 16 #endif +#define IGUANA_SUBDIRDIVISOR 28000 #ifdef __PNACL void PNACL_message(const char* format, ...); @@ -107,7 +128,7 @@ extern int32_t IGUANA_NUMHELPERS; #define NODE_GETUTXO (1 << 1) #define NODE_BLOOM (1 << 2) -#define PROTOCOL_VERSION 70011 +#define PROTOCOL_VERSION 70001 #define INIT_PROTO_VERSION 209 // initial proto version, to be increased after version/verack negotiation #define GETHEADERS_VERSION 31800 // In this version, 'getheaders' was introduced. #define MIN_PEER_PROTO_VERSION GETHEADERS_VERSION // disconnect from peers older than this proto version @@ -124,6 +145,8 @@ extern int32_t IGUANA_NUMHELPERS; #define MSG_TX 1 #define MSG_BLOCK 2 #define MSG_FILTERED_BLOCK 3 +#define MSG_BUNDLE_HEADERS 255 +#define MSG_BUNDLE 254 #define IGUANA_MAXLOCATORS 64 #define IGUANA_MAXINV 50000 @@ -135,7 +158,7 @@ extern int32_t IGUANA_NUMHELPERS; #define IGUANA_ALLOC_MULT 1.1 #define IGUANA_ALLOC_INCR 1000 -#define IGUANA_JSONTIMEOUT 1000 +#define IGUANA_JSONTIMEOUT 10000 #define IGUANA_MAPRECVDATA 1 #define IGUANA_MAPTXIDITEMS 2 @@ -172,18 +195,27 @@ struct iguana_thread void *arg; }; +struct iguana_blockreq { struct queueitem DL; bits256 hash2,*blockhashes; struct iguana_bundle *bp; int32_t n,height,bundlei; }; + +struct iguana_peermsgrequest { struct queueitem DL; struct iguana_peer *addr; bits256 hash2; int32_t type; }; + struct iguana_chain { //const int32_t chain_id; - char name[32],symbol[8]; + char name[32],symbol[8],messagemagic[64]; uint8_t pubtype,p2shtype,wiftype,netmagic[4]; char *genesis_hash,*genesis_hex; // hex string - uint16_t portp2p,portrpc; + uint16_t portp2p,rpcport; uint8_t hastimestamp,unitval; uint64_t rewards[512][2]; uint8_t genesis_hashdata[32],minconfirms; uint16_t ramchainport,bundlesize,hasheaders; char gethdrsmsg[16]; + uint64_t txfee,minoutput,dust; + blockhashfunc hashalgo; + char userhome[512],serverport[128],userpass[1024]; + char use_addmultisig,do_opreturn; + int32_t estblocktime; }; struct iguana_msgaddress { uint32_t nTime; uint64_t nServices; uint8_t ip[16]; uint16_t port; } __attribute__((packed)); @@ -225,7 +257,7 @@ struct iguana_msgblock uint32_t txn_count; } __attribute__((packed)); -struct iguana_msgvin { bits256 prev_hash; uint8_t *script; uint32_t prev_vout,scriptlen,sequence; } __attribute__((packed)); +struct iguana_msgvin { bits256 prev_hash; uint8_t *vinscript,*spendscript,*redeemscript; uint32_t prev_vout,sequence; uint16_t scriptlen,p2shlen,suffixlen,spendlen; } __attribute__((packed)); struct iguana_msgvout { uint64_t value; uint32_t pk_scriptlen; uint8_t *pk_script; } __attribute__((packed)); @@ -244,7 +276,7 @@ struct msgcounts { uint32_t version,verack,getaddr,addr,inv,getdata,notfound,get struct iguana_fileitem { bits256 hash2; struct iguana_txdatabits txdatabits; }; -struct iguana_kvitem { UT_hash_handle hh; uint8_t keyvalue[]; } __attribute__((packed)); +struct iguana_kvitem { UT_hash_handle hh; uint8_t keyvalue[]; };// __attribute__((packed)); struct iguana_iAddr { @@ -268,9 +300,9 @@ struct iguana_block { struct iguana_blockRO RO; double PoW; // NOT consensus safe, for estimation purposes only - int32_t height,fpos; uint32_t fpipbits,numrequests,issued; - uint16_t hdrsi,bundlei:12,mainchain:1,valid:1,queued:1,tbd:1,extra:8; - UT_hash_handle hh; bits256 *blockhashes; + int32_t height,fpos; uint32_t fpipbits,issued,lag:20,peerid:12; + uint16_t hdrsi:15,mainchain:1,bundlei:11,valid:1,queued:1,txvalid:1,newtx:1,processed:1; + UT_hash_handle hh; struct iguana_bundlereq *req; //void *serdata; } __attribute__((packed)); @@ -279,12 +311,11 @@ struct iguana_block #define IGUANA_LHASH_UNSPENTS 2 // #define IGUANA_LHASH_SPENDS 3 // #define IGUANA_LHASH_PKHASHES 4 // -//#define IGUANA_LHASH_SPENTINDS 5 -//#define IGUANA_LHASH_FIRSTSPENDS 5 // #define IGUANA_LHASH_ACCOUNTS 5 // #define IGUANA_LHASH_EXTERNALS 6 // -#define IGUANA_LHASH_TXBITS 7 // -#define IGUANA_LHASH_PKBITS 8 // +#define IGUANA_LHASH_KSPACE 7 // +#define IGUANA_LHASH_TXBITS 8 // +#define IGUANA_LHASH_PKBITS 9 // #define IGUANA_NUMLHASHES (IGUANA_LHASH_PKBITS + 1) struct iguana_counts @@ -313,22 +344,27 @@ struct iguana_ledger //struct iguana_account accounts[]; } __attribute__((packed)); -// ramchain append only structs -> canonical 32bit inds and ledgerhashes -struct iguana_txid { bits256 txid; uint32_t txidind,firstvout,firstvin,locktime,version,timestamp; uint16_t numvouts,numvins; } __attribute__((packed)); +// ramchain temp file structures +struct iguana_unspent20 { uint64_t value; uint32_t scriptpos,txidind:28,type:4; uint16_t scriptlen,fileid; uint8_t rmd160[20]; } __attribute__((packed)); +struct iguana_spend256 { bits256 prevhash2; uint64_t scriptpos:48,vinscriptlen:16; uint32_t sequenceid; int16_t prevout; uint16_t spendind,fileid; } __attribute__((packed)); + +// permanent readonly structs +struct iguana_txid { bits256 txid; uint32_t txidind:29,firstvout:28,firstvin:28,bundlei:11,locktime,version,timestamp,extraoffset; uint16_t numvouts,numvins; } __attribute__((packed)); -struct iguana_unspent { uint64_t value; uint32_t txidind,pkind,prevunspentind; uint16_t hdrsi:12,type:4,vout; } __attribute__((packed)); -struct iguana_unspent20 { uint64_t value; uint32_t txidind:28,type:4; uint8_t rmd160[20]; } __attribute__((packed)); +struct iguana_unspent { uint64_t value; uint32_t txidind,pkind,prevunspentind,scriptpos; uint16_t scriptlen,hdrsi; uint16_t fileid:11,type:5; int16_t vout; } __attribute__((packed)); -struct iguana_spend256 { bits256 prevhash2; int16_t prevout; uint16_t spendind:15,diffsequence:1; } __attribute__((packed)); -struct iguana_spend { uint32_t spendtxidind; int16_t prevout; uint16_t tbd:14,external:1,diffsequence:1; } __attribute__((packed)); +struct iguana_spend { uint64_t scriptpos:48,scriptlen:16; uint32_t spendtxidind,sequenceid; int16_t prevout; uint16_t fileid:15,external:1; } __attribute__((packed)); // numsigs:4,numpubkeys:4,p2sh:1,sighash:4 -struct iguana_pkhash { uint8_t rmd160[20]; uint32_t pkind,firstunspentind,flags:23,type:8,ps2h:1; } __attribute__((packed)); +struct iguana_pkhash { uint8_t rmd160[20]; uint32_t pkind; } __attribute__((packed)); //firstunspentind,pubkeyoffset // dynamic -struct iguana_account { uint64_t balance; uint32_t lastunspentind; } __attribute__((packed)); // pkind +struct iguana_account { int64_t total; uint32_t lastunspentind; } __attribute__((packed)); +struct iguana_utxo { uint32_t fromheight:31,lockedflag:1,prevunspentind:31,spentflag:1; } __attribute__((packed)); +struct iguana_hhaccount { UT_hash_handle hh; uint64_t pval; struct iguana_account a; } __attribute__((packed)); +struct iguana_hhutxo { UT_hash_handle hh; uint64_t uval; struct iguana_utxo u; } __attribute__((packed)); // GLOBAL one zero to non-zero write (unless reorg) -struct iguana_Uextra { uint32_t spendind; uint16_t hdrsi; } __attribute__((packed)); // unspentind +struct iguana_spendvector { uint64_t value; uint32_t pkind,unspentind; int32_t fromheight; uint16_t hdrsi:15,tmpflag:1; } __attribute__((packed)); // unspentind //struct iguana_pkextra { uint32_t firstspendind; } __attribute__((packed)); // pkind struct iguana_txblock @@ -340,29 +376,36 @@ struct iguana_txblock struct iguana_block block; }; +#define RAMCHAIN_PTR(rdata,offset) ((void *)(long)((long)(rdata) + (long)(rdata)->offset)) struct iguana_ramchaindata { bits256 sha256; - bits256 lhashes[IGUANA_NUMLHASHES],firsthash2,lasthash2; - int64_t allocsize,Boffset,Toffset,Uoffset,Soffset,Poffset,Aoffset,Xoffset,TXoffset,PKoffset; + bits256 lhashes[IGUANA_NUMLHASHES],firsthash2,prevhash2; + int64_t allocsize,Boffset,Toffset,Uoffset,Soffset,Poffset,Aoffset,Xoffset,TXoffset,PKoffset,Koffset; int32_t numblocks,height,firsti,hdrsi,txsparsebits,pksparsebits; - uint32_t numtxids,numunspents,numspends,numpkinds,numexternaltxids,numtxsparse,numpksparse; + uint32_t numtxids,numunspents,numspends,numpkinds,numexternaltxids,numtxsparse,numpksparse,scriptspace,stackspace; uint8_t rdata[]; }; struct iguana_ramchain_hdr { - uint32_t txidind,unspentind,spendind; uint16_t hdrsi,bundlei:15,ROflag:1; + uint32_t txidind,unspentind,spendind,scriptoffset,stacksize; uint16_t hdrsi,bundlei:15,ROflag:1; struct iguana_ramchaindata *data; }; struct iguana_ramchain { - struct iguana_ramchain_hdr H; bits256 lasthash2; uint64_t datasize; - uint32_t numblocks:31,expanded:1,pkind,externalind,height; + struct iguana_ramchain_hdr H; bits256 lasthash2; uint64_t datasize,allocatedA2,allocatedU2; + uint32_t numblocks:31,expanded:1,pkind,externalind,height,numXspends; + long sparseadds,sparsesearches,sparseadditers,sparsesearchiters,sparsehits,sparsemax; struct iguana_kvitem *txids,*pkhashes; - struct OS_memspace *hashmem; long filesize; void *fileptr; - struct iguana_account *A,*roA; //struct iguana_Uextra *U2,*roU2; struct iguana_pkextra *P2,*roP2; + struct OS_memspace *hashmem; long filesize,sigsfilesize,debitsfilesize,lastspendsfilesize; + void *fileptr,*sigsfileptr,*Xspendptr,*debitsfileptr,*lastspendsfileptr; + char from_ro,from_roX,from_roA,from_roU; + struct iguana_account *A,*A2,*creditsA; struct iguana_spendvector *Xspendinds; + struct iguana_utxo *Uextras; uint8_t *txbits; struct iguana_txid *cacheT; + //int16_t permutation[IGUANA_MAXBUNDLES]; +//struct iguana_Uextra *U2,*roU2; struct iguana_pkextra *P2,*roP2; }; struct iguana_peer @@ -373,16 +416,18 @@ struct iguana_peer struct iguana_msgaddress A; char ipaddr[64],lastcommand[16],coinstr[16],symbol[16]; uint64_t pingnonce,totalsent,totalrecv,ipbits; double pingtime,sendmillis,pingsum,getdatamillis; - uint32_t lastcontact,sendtime,ready,startsend,startrecv,pending,lastgotaddr,lastblockrecv,pendtime,lastflush,lastpoll,myipbits,persistent_peer; - int32_t supernet,dead,addrind,usock,lastheight,protover,relayflag,numpackets,numpings,ipv6,height,rank,pendhdrs,pendblocks,recvhdrs,lastlefti,validpub,othervalid; + uint32_t lastcontact,sendtime,ready,startsend,startrecv,pending,lastgotaddr,lastblockrecv,pendtime,lastflush,lastpoll,myipbits,persistent_peer,protover; + int32_t supernet,dead,addrind,usock,lastheight,relayflag,numpackets,numpings,ipv6,height,rank,pendhdrs,pendblocks,recvhdrs,lastlefti,validpub,othervalid,dirty[2],laggard; double recvblocks,recvtotal; int64_t allocated,freed; + bits256 RThashes[IGUANA_MAXBUNDLESIZE]; int32_t numRThashes; struct msgcounts msgcounts; - //FILE *fp; int32_t filecount,addrind; struct OS_memspace RAWMEM,TXDATA,HASHMEM; struct iguana_ramchain ramchain; - //struct iguana_kvitem *txids,*pkhashes; struct iguana_fileitem *filehash2; int32_t numfilehash2,maxfilehash2; + //struct iguana_bundle *bp; + FILE *voutsfp,*vinsfp; + uint8_t *blockspace;//[IGUANA_MAXPACKETSIZE + 8192]; #ifdef IGUANA_PEERALLOC struct OS_memspace *SEROUT[128]; #endif @@ -391,26 +436,31 @@ struct iguana_peer struct iguana_peers { bits256 lastrequest; - struct iguana_peer active[IGUANA_MAXPEERS],*ranked[IGUANA_MAXPEERS],*localaddr; + struct iguana_peer active[IGUANA_MAXPEERS+1],*ranked[IGUANA_MAXPEERS+1],*localaddr; struct iguana_thread *peersloop,*recvloop; pthread_t *acceptloop; - double topmetrics[IGUANA_MAXPEERS],avemetric; + double topmetrics[IGUANA_MAXPEERS+1],avemetric; + long vinptrs[IGUANA_MAXPEERS+1][2],voutptrs[IGUANA_MAXPEERS+1][2]; uint32_t numranked,mostreceived,shuttingdown,lastpeer,lastmetrics,numconnected; int32_t numfiles; }; struct iguana_bloom16 { uint8_t hash2bits[65536 / 8]; }; +struct iguana_bloominds { uint16_t inds[8]; }; struct iguana_bundle { struct queueitem DL; struct iguana_info *coin; struct iguana_bundle *nextbp; - struct iguana_bloom16 bloom; - uint32_t issuetime,hdrtime,emitfinish,mergefinish,purgetime,queued; - int32_t numhashes,numrecv,numsaved,numcached; - int32_t minrequests,n,hdrsi,bundleheight,numtxids,numspends,numunspents,numspec; + struct iguana_bloom16 bloom; int64_t totaldurations,duplicatedurations; int32_t durationscount,duplicatescount; + uint32_t issuetime,hdrtime,emitfinish,mergefinish,purgetime,queued,startutxo,utxofinish,balancefinish,validated,lastspeculative,dirty,nexttime,currenttime,lastprefetch,lastRT,missingstime,unsticktime,converted; + int32_t numhashes,numrecv,numsaved,numcached,generrs,currentflag,origmissings,numissued,Xvalid; + int32_t minrequests,n,hdrsi,bundleheight,numtxids,numspends,numunspents,numspec,isRT; double avetime,threshold,metric; uint64_t datasize,estsize; - struct iguana_block *blocks[IGUANA_MAXBUNDLESIZE]; uint32_t issued[IGUANA_MAXBUNDLESIZE]; - bits256 prevbundlehash2,hashes[IGUANA_MAXBUNDLESIZE+1],nextbundlehash2,allhash,*speculative; + struct iguana_block *blocks[IGUANA_MAXBUNDLESIZE]; + uint8_t *speculativecache[IGUANA_MAXBUNDLESIZE],haveblock[IGUANA_MAXBUNDLESIZE/3+1]; + uint32_t issued[IGUANA_MAXBUNDLESIZE]; + bits256 prevbundlehash2,hashes[IGUANA_MAXBUNDLESIZE+1],nextbundlehash2,allhash,*speculative,validatehash; struct iguana_ramchain ramchain; uint8_t red,green,blue; + struct iguana_spendvector *tmpspends; int32_t numtmpspends; }; struct iguana_bundlereq @@ -425,57 +475,74 @@ struct iguana_bundlereq struct iguana_bitmap { int32_t width,height,amplitude; char name[52]; uint8_t data[IGUANA_WIDTH*IGUANA_HEIGHT*3]; }; -struct iguana_waddress { UT_hash_handle hh; uint8_t rmd160[20],type,pubkey[33],wiftype; uint32_t symbolbits; bits256 privkey; char coinaddr[36],wifstr[54]; }; -struct iguana_waccount { UT_hash_handle hh; char account[128]; struct iguana_waddress *waddrs; }; -struct iguana_wallet { UT_hash_handle hh; struct iguana_waccount *waccts; }; +struct iguana_waddress { UT_hash_handle hh; uint64_t balance,*unspents; uint32_t maxunspents,numunspents; uint16_t scriptlen; uint8_t rmd160[20],pubkey[33],wiftype,addrtype; bits256 privkey; char symbol[8],coinaddr[36],wifstr[54]; uint8_t redeemScript[]; }; +struct iguana_waccount { UT_hash_handle hh; char account[128]; struct iguana_waddress *waddr,*current; }; +struct iguana_wallet { UT_hash_handle hh; struct iguana_waccount *wacct; }; + +struct scriptinfo { UT_hash_handle hh; uint32_t fpos; uint16_t scriptlen; uint8_t script[]; }; +struct hhbits256 { UT_hash_handle hh; bits256 txid; int32_t height; uint16_t firstvout; }; struct iguana_info { - char name[64],symbol[8],statusstr[512]; - struct iguana_peers peers; + char name[64],symbol[8],statusstr[512],scriptsfname[2][512]; + struct iguana_peers peers; struct iguana_peer internaladdr; + uint32_t fastfind; FILE *fastfps[0x100]; uint8_t *fast[0x100]; int32_t *fasttables[0x100]; long fastsizes[0x100]; uint64_t instance_nonce,myservices,totalsize,totalrecv,totalpackets,sleeptime; - int64_t mining,totalfees,TMPallocated,MAXRECVCACHE,MAXMEM,estsize,activebundles; - int32_t MAXPEERS,MAXPENDING,MAXBUNDLES,active,closestbundle,numemitted,lastsweep,startutc,newramchain,numcached,cachefreed,helperdepth; - uint32_t longestchain,lastsync,parsetime,numiAddrs,firstblock,lastpossible,bundlescount,savedblocks; + int64_t mining,totalfees,TMPallocated,MAXRECVCACHE,MAXMEM,PREFETCHLAG,estsize,activebundles; + int32_t MAXPEERS,MAXPENDINGREQUESTS,MAXBUNDLES,MAXSTUCKTIME,active,closestbundle,numemitted,lastsweep,numemit,startutc,newramchain,numcached,cachefreed,helperdepth,startPEND,endPEND,enableCACHE,RELAYNODE,VALIDATENODE,origbalanceswritten,balanceswritten,RTheight,RTdatabad; + bits256 balancehash,allbundles; + uint32_t lastsync,parsetime,numiAddrs,lastpossible,bundlescount,savedblocks,backlog,spendvectorsaved,laststats; char VALIDATEDIR[512]; + int32_t longestchain,badlongestchain,longestchain_strange,RTramchain_busy,emitbusy,stuckiters; struct tai starttime; double startmillis; struct iguana_chain *chain; struct iguana_iAddr *iAddrs; - struct iguanakv *txids,*spends,*unspents,*pkhashes; - struct iguana_txid *T; - struct iguana_unspent *U; struct iguana_Uextra *Uextras; - struct iguana_spend *S; struct iguana_Sextra *Sextras; - struct iguana_pkhash *P; struct iguana_account *accounts; struct iguana_pkextra *pkextras; - //struct iguana_counts latest; - //struct iguana_ledger LEDGER,loadedLEDGER; - + void *ctx; struct iguana_bitmap screen; //struct pollfd fds[IGUANA_MAXPEERS]; struct iguana_peer bindaddr; int32_t numsocks; - struct OS_memspace TXMEM; - queue_t acceptQ,bundlesQ,hdrsQ,blocksQ,priorityQ,possibleQ,TerminateQ,cacheQ; + struct OS_memspace TXMEM,MEM,MEMB[IGUANA_MAXBUNDLESIZE]; + queue_t acceptQ,hdrsQ,blocksQ,priorityQ,possibleQ,cacheQ,recvQ,msgrequestQ; double parsemillis,avetime; uint32_t Launched[8],Terminated[8]; portable_mutex_t peers_mutex,blocks_mutex; - struct iguana_bundle *bundles[IGUANA_MAXBUNDLES]; - int32_t numremain,numpendings,zcount,recvcount,bcount,pcount,lastbundle; - uint32_t recvtime,hdrstime,backstoptime,lastbundletime,numreqsent,numbundlesQ,lastbundleitime; - double backstopmillis; bits256 backstophash2; - int32_t initialheight,mapflags,minconfirms,numrecv,bindsock,isRT,backstop,blocksrecv,merging,polltimeout,numreqtxids; bits256 reqtxids[64]; - void *launched,*started; - uint64_t bloomsearches,bloomhits,bloomfalse,collisions; uint8_t blockspace[IGUANA_MAXPACKETSIZE + 8192]; struct OS_memspace blockMEM; + //portable_mutex_t scripts_mutex[2]; FILE *scriptsfp[2]; void *scriptsptr[2]; long scriptsfilesize[2]; + //struct scriptinfo *scriptstable[2]; + struct iguana_bundle *bundles[IGUANA_MAXBUNDLES],*current,*lastpending; + struct iguana_ramchain RTramchain; struct OS_memspace RTmem,RThashmem; bits256 RThash1; + int32_t numremain,numpendings,zcount,recvcount,bcount,pcount,lastbundle,numsaved,pendbalances,numverified,blockdepth; + uint32_t recvtime,hdrstime,backstoptime,lastbundletime,numreqsent,numbundlesQ,lastbundleitime,lastdisp,RTgenesis,RTstarti,idletime,stucktime,stuckmonitor,maxstuck,lastreqtime,RThdrstime; + double bandwidth,maxbandwidth,backstopmillis; bits256 backstophash2; int64_t spaceused; + int32_t initialheight,mapflags,minconfirms,numrecv,bindsock,isRT,backstop,blocksrecv,merging,polltimeout,numreqtxids,allhashes,balanceflush; bits256 reqtxids[64]; + void *launched,*started,*rpcloop; + uint64_t bloomsearches,bloomhits,bloomfalse,collisions,txfee_perkb; + uint8_t blockspace[IGUANA_MAXPACKETSIZE + 8192]; struct OS_memspace blockMEM; struct iguana_blocks blocks; bits256 APIblockhash,APItxid; char *APIblockstr; - struct iguana_waccount *wallet; + struct iguana_hhutxo *utxotable; struct iguana_hhaccount *accountstable; char lastdispstr[2048]; + double txidfind_totalmillis,txidfind_num,spendtxid_totalmillis,spendtxid_num; }; struct vin_signer { bits256 privkey; char coinaddr[64]; uint8_t siglen,sig[80],rmd160[20],pubkey[66]; }; struct vin_info { - struct iguana_msgvin vin; - int32_t M,N,validmask,spendlen,type,p2shlen; - struct vin_signer signers[16]; - char coinaddr[65]; + struct iguana_msgvin vin; uint64_t amount; cJSON *extras; bits256 sigtxid; + int32_t M,N,validmask,spendlen,type,p2shlen,suffixlen,numpubkeys,numsigs,height,hashtype; + uint32_t sequence,unspentind; struct vin_signer signers[16]; char coinaddr[65]; uint8_t rmd160[20],spendscript[IGUANA_MAXSCRIPTSIZE],p2shscript[IGUANA_MAXSCRIPTSIZE]; }; +struct bitcoin_unspent +{ + bits256 txid,privkeys[16]; uint64_t value; int32_t vout,spendlen,p2shlen,numpubkeys; uint32_t sequence; + uint8_t addrtype,rmd160[20],pubkeys[16][65],spendscript[IGUANA_MAXSCRIPTSIZE],p2shscript[IGUANA_MAXSCRIPTSIZE]; +}; + +struct bitcoin_spend +{ + char changeaddr[64]; uint8_t change160[20]; + int32_t numinputs; + int64_t txfee,input_satoshis,satoshis,change; + struct bitcoin_unspent inputs[]; +}; + // peers int32_t iguana_verifypeer(struct iguana_info *coin,void *key,void *value,int32_t itemind,int32_t itemsize); int32_t iguana_peermetrics(struct iguana_info *coin); @@ -514,14 +581,17 @@ int32_t iguana_sethdr(struct iguana_msghdr *H,const uint8_t netmagic[4],char *co int32_t iguana_send_version(struct iguana_info *coin,struct iguana_peer *addr,uint64_t myservices); int32_t iguana_gentxarray(struct iguana_info *coin,struct OS_memspace *mem,struct iguana_txblock *txblock,int32_t *lenp,uint8_t *data,int32_t datalen); int32_t iguana_gethdrs(struct iguana_info *coin,uint8_t *serialized,char *cmd,char *hashstr); -int32_t iguana_getdata(struct iguana_info *coin,uint8_t *serialized,int32_t type,char *hashstr); +int32_t iguana_getdata(struct iguana_info *coin,uint8_t *serialized,int32_t type,bits256 *hashes,int32_t n); +void iguana_blockunconv(struct iguana_msgblock *msg,struct iguana_block *src,int32_t cleartxn_count); +int32_t iguana_peerblockrequest(struct iguana_info *coin,uint8_t *blockspace,int32_t max,struct iguana_peer *addr,bits256 hash2,int32_t validatesigs); +int32_t iguana_validatesigs(struct iguana_info *coin,struct iguana_msgvin *vin); // ramchain int64_t iguana_verifyaccount(struct iguana_info *coin,struct iguana_account *acct,uint32_t pkind); int32_t iguana_initramchain(struct iguana_info *coin,int32_t initialheight,int32_t mapflags,int32_t fullverify); void iguana_syncramchain(struct iguana_info *coin); //int32_t iguana_validateramchain(struct iguana_info *coin,int64_t *netp,uint64_t *creditsp,uint64_t *debitsp,int32_t height,struct iguana_block *block,int32_t hwmheight,struct iguana_prevdep *lp); -int32_t iguana_calcrmd160(struct iguana_info *coin,struct vin_info *vp,uint8_t *pk_script,int32_t pk_scriptlen,bits256 debugtxid,int32_t vout,uint32_t sequence); +int32_t iguana_calcrmd160(struct iguana_info *coin,char *asmstr,struct vin_info *vp,uint8_t *pk_script,int32_t pk_scriptlen,bits256 debugtxid,int32_t vout,uint32_t sequence); uint32_t iguana_updatescript(struct iguana_info *coin,uint32_t blocknum,uint32_t txidind,uint32_t spendind,uint32_t unspentind,uint64_t value,uint8_t *script,int32_t scriptlen,uint32_t sequence); void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_txblock *txdata,struct iguana_msgtx *txarray,struct iguana_msghdr *H,uint8_t *data,int32_t datalen); int32_t iguana_parseblock(struct iguana_info *coin,struct iguana_block *block,struct iguana_msgtx *tx,int32_t numtx); @@ -532,7 +602,7 @@ int32_t iguana_updateramchain(struct iguana_info *coin); // blockchain int32_t iguana_needhdrs(struct iguana_info *coin); -struct iguana_chain *iguana_chainfind(char *name); +struct iguana_chain *iguana_chainfind(char *name,cJSON *argjson,int32_t createflag); int32_t iguana_chainextend(struct iguana_info *coin,struct iguana_block *newblock); uint64_t iguana_miningreward(struct iguana_info *coin,uint32_t blocknum); @@ -544,12 +614,12 @@ void iguana_gotblockhashesM(struct iguana_info *coin,struct iguana_peer *addr,bi // blocks bits256 iguana_blockhash(struct iguana_info *coin,int32_t height); -#define iguana_blockfind(coin,hash2) iguana_blockhashset(coin,-1,hash2,0) -struct iguana_block *iguana_blockhashset(struct iguana_info *coin,int32_t height,bits256 hash2,int32_t createflag); +#define iguana_blockfind(str,coin,hash2) iguana_blockhashset(str,coin,-1,hash2,0) +struct iguana_block *iguana_blockhashset(char *debugstr,struct iguana_info *coin,int32_t height,bits256 hash2,int32_t createflag); uint32_t iguana_syncs(struct iguana_info *coin); void iguana_gotdata(struct iguana_info *coin,struct iguana_peer *addr,int32_t height); -int64_t iguana_balance(struct iguana_info *coin,uint64_t *creditsp,uint64_t *debitsp,int32_t *nump,uint32_t *unspents,long max,struct iguana_pkhash *P,uint32_t pkind); +//int64_t iguana_getbalance(struct iguana_info *coin,uint64_t *creditsp,uint64_t *debitsp,int32_t *nump,uint32_t *unspents,long max,struct iguana_pkhash *P,uint32_t pkind); int32_t iguana_queueblock(struct iguana_info *coin,int32_t height,bits256 hash2,int32_t priority); int32_t iguana_updatewaiting(struct iguana_info *coin,int32_t starti,int32_t max); @@ -558,7 +628,7 @@ int32_t iguana_recvinit(struct iguana_info *coin,int32_t initialheight); int32_t ramcoder_decompress(uint8_t *data,int32_t maxlen,uint8_t *bits,uint32_t numbits,bits256 seed); 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); -struct iguana_block *iguana_blockptr(struct iguana_info *coin,int32_t height); +struct iguana_block *iguana_blockptr(char *debugstr,struct iguana_info *coin,int32_t height); int32_t iguana_processrecv(struct iguana_info *coin); // single threaded void iguana_recvalloc(struct iguana_info *coin,int32_t numitems); void iguana_coins(void *arg); @@ -573,11 +643,11 @@ void iguana_emittxdata(struct iguana_info *coin,struct iguana_bundle *bp); int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr); int32_t iguana_avail(struct iguana_info *coin,int32_t height,int32_t n); int32_t iguana_updatebundles(struct iguana_info *coin); -void iguana_bundlestats(struct iguana_info *coin,char *str); +void iguana_bundlestats(struct iguana_info *coin,char *str,int32_t lag); // init struct iguana_info *iguana_coinstart(struct iguana_info *coin,int32_t initialheight,int32_t mapflags); -void iguana_initcoin(struct iguana_info *coin); +void iguana_initcoin(struct iguana_info *coin,cJSON *argjson); void iguana_coinloop(void *arg); // utils @@ -588,7 +658,7 @@ double dxblend(double *destp,double val,double decay); // json int32_t iguana_processjsonQ(struct iguana_info *coin); // reentrant, can be called during any idletime -char *iguana_JSON(char *); +char *iguana_JSON(char *,uint16_t port); char *SuperNET_p2p(struct iguana_info *coin,struct iguana_peer *addr,int32_t *delaymillisp,char *ipaddr,uint8_t *data,int32_t datalen,int32_t compressed); char *mbstr(char *str,double); @@ -620,7 +690,7 @@ void iguana_flushQ(struct iguana_info *coin,struct iguana_peer *addr); //struct iguana_txdatabits iguana_peerfilePT(struct iguana_info *coin,struct iguana_peer *addr,bits256 hash2,struct iguana_txdatabits txdatabits,int32_t recvlen); struct iguana_txdatabits iguana_calctxidbits(uint32_t addrind,uint32_t filecount,uint32_t fpos,uint32_t datalen); int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_bundle *bp,uint32_t starttime); // helper thread -int32_t iguana_bundlemergeHT(struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_bundle *bp,struct iguana_bundle *nextbp,uint32_t starttime); // helper thread +int32_t iguana_bundlemergeHT(char *fname,struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_bundle *bp,struct iguana_bundle *nextbp,uint32_t starttime); // helper thread void iguana_peerfilename(struct iguana_info *coin,char *fname,uint32_t addrind,uint32_t filecount); @@ -631,14 +701,14 @@ int32_t iguana_ramchainfree(struct iguana_info *coin,struct OS_memspace *mem,str struct iguana_ramchain *iguana_ramchainmergeHT(struct iguana_info *coin,struct OS_memspace *mem,struct iguana_ramchain *ramchains[],int32_t n,struct iguana_bundle *bp); void iguana_ramchainmerge(struct iguana_info *coin); -int32_t iguana_blockQ(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t priority); +int32_t iguana_blockQ(char *argstr,struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t priority); void iguana_blockcopy(struct iguana_info *coin,struct iguana_block *block,struct iguana_block *origblock); int32_t iguana_rpctest(struct iguana_info *coin); extern queue_t helperQ; extern const char *Hardcoded_coins[][3]; void iguana_main(void *arg); extern struct iguana_info *Coins[64]; -int32_t iguana_peerfname(struct iguana_info *coin,int32_t *hdrsip,char *dirname,char *fname,uint32_t ipbits,bits256 hash2,bits256 prevhash2,int32_t numblocks); +int32_t iguana_peerfname(struct iguana_info *coin,int32_t *hdrsip,char *dirname,char *fname,uint32_t ipbits,bits256 hash2,bits256 prevhash2,int32_t numblocks,int32_t dispflag); struct iguana_txblock *iguana_peertxdata(struct iguana_info *coin,int32_t *bundleip,char *fname,struct OS_memspace *mem,uint32_t ipbits,bits256 hash2); int32_t iguana_peerfile_exists(struct iguana_info *coin,struct iguana_peer *addr,char *dirname,char *fname,bits256 hash2,bits256 prevhash2,int32_t numblocks); struct iguana_ramchain *iguana_ramchainset(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct iguana_txblock *txdata); @@ -663,7 +733,7 @@ int32_t iguana_socket(int32_t bindflag,char *hostname,uint16_t port); void iguana_mergeQ(struct iguana_info *coin,struct iguana_bundle *bp,struct iguana_bundle *nextbp); #define bits256_nonz(a) (((a).ulongs[0] | (a).ulongs[1] | (a).ulongs[2] | (a).ulongs[3]) != 0) -int32_t btc_addr2univ(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr); +//int32_t btc_addr2univ(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr); struct iguana_agent { @@ -673,17 +743,16 @@ struct iguana_agent }; int32_t iguana_txbytes(struct iguana_info *coin,uint8_t *serialized,int32_t maxlen,bits256 *txidp,struct iguana_txid *tx,int32_t height,struct iguana_msgvin *vins,struct iguana_msgvout *vouts); -void iguana_vinset(struct iguana_info *coin,int32_t height,struct iguana_msgvin *vin,struct iguana_txid *tx,int32_t i); +int32_t iguana_vinset(struct iguana_info *coin,uint8_t *scriptspace,int32_t height,struct iguana_msgvin *vin,struct iguana_txid *tx,int32_t i); int32_t iguana_voutset(struct iguana_info *coin,uint8_t *scriptspace,char *asmstr,int32_t height,struct iguana_msgvout *vout,struct iguana_txid *tx,int32_t i); -int32_t btc_convrmd160(char *coinaddr,uint8_t addrtype,uint8_t rmd160[20]); +//int32_t btc_convrmd160(char *coinaddr,uint8_t addrtype,uint8_t rmd160[20]); struct iguana_txid *iguana_bundletx(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei,struct iguana_txid *tx,int32_t txidind); int32_t iguana_txidreq(struct iguana_info *coin,char **retstrp,bits256 txid); void iguana_bundleiclear(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei); int32_t hcalc_bitsize(uint64_t x); -struct iguana_pkhash *iguana_pkhashfind(struct iguana_info *coin,struct iguana_pkhash *p,uint8_t rmd160[20]); -struct iguana_txid *iguana_txidfind(struct iguana_info *coin,int32_t *heightp,struct iguana_txid *tx,bits256 txid); +struct iguana_txid *iguana_txidfind(struct iguana_info *coin,int32_t *heightp,struct iguana_txid *tx,bits256 txid,int32_t lasthdrsi); int32_t iguana_scriptgen(struct iguana_info *coin,int32_t *Mp,int32_t *nump,char *coinaddr,uint8_t *script,char *asmstr,uint8_t rmd160[20],uint8_t type,const struct vin_info *vp,int32_t txi); -int32_t iguana_ramchain_spendtxid(struct iguana_info *coin,bits256 *txidp,struct iguana_txid *T,int32_t numtxids,bits256 *X,int32_t numexternaltxids,struct iguana_spend *s); +int32_t iguana_ramchain_spendtxid(struct iguana_info *coin,uint32_t *unspentindp,bits256 *txidp,struct iguana_txid *T,int32_t numtxids,bits256 *X,int32_t numexternaltxids,struct iguana_spend *s); struct iguana_info *iguana_coinselect(); void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr); struct iguana_peer *iguana_peerslot(struct iguana_info *coin,uint64_t ipbits,int32_t forceflag); @@ -696,37 +765,39 @@ char *busdata_sync(uint32_t *noncep,char *jsonstr,char *broadcastmode,char *dest void peggy(); int32_t opreturns_init(uint32_t blocknum,uint32_t blocktimestamp,char *path); struct iguana_info *iguana_coinfind(const char *symbol); -struct iguana_info *iguana_coinadd(const char *symbol); -struct iguana_ramchain *iguana_bundleload(struct iguana_info *coin,struct iguana_bundle *bp); +struct iguana_info *iguana_coinadd(const char *symbol,cJSON *json); +struct iguana_ramchain *iguana_bundleload(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct iguana_bundle *bp,int32_t extraflag); int32_t iguana_sendblockreq(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t iamthreadsafe); int32_t iguana_send_supernet(struct iguana_info *coin,struct iguana_peer *addr,char *jsonstr,int32_t delay); -struct iguana_waccount *iguana_waccountfind(struct iguana_info *coin,char *account); -struct iguana_waccount *iguana_waccountadd(struct iguana_info *coin,char *walletaccount,struct iguana_waddress *waddr); -int32_t iguana_waccountswitch(struct iguana_info *coin,char *account,struct iguana_waccount *oldwaddr,int32_t oldind,char *coinaddr); -struct iguana_waddress *iguana_waddresscalc(uint8_t pubval,uint8_t wiftype,struct iguana_waddress *addr,bits256 privkey); -struct iguana_waccount *iguana_waddressfind(struct iguana_info *coin,int32_t *indp,char *coinaddr); +struct iguana_waccount *iguana_waccountfind(struct supernet_info *myinfo,struct iguana_info *coin,char *account); +struct iguana_waddress *iguana_waccountadd(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waccount **wacctp,char *walletaccount,char *coinaddr); +struct iguana_waddress *iguana_waccountswitch(struct supernet_info *myinfo,struct iguana_info *coin,char *account,char *coinaddr,char *redeemScript); +struct iguana_waddress *iguana_waddresscalc(struct supernet_info *myinfo,uint8_t pubval,uint8_t wiftype,struct iguana_waddress *addr,bits256 privkey); +struct iguana_waddress *iguana_waddressfind(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waccount *wacct,char *coinaddr); char *iguana_coinjson(struct iguana_info *coin,char *method,cJSON *json); cJSON *iguana_peersjson(struct iguana_info *coin,int32_t addronly); -int32_t btc_priv2wif(char *wifstr,uint8_t privkey[32],uint8_t addrtype); -int32_t btc_pub2rmd(uint8_t rmd160[20],uint8_t pubkey[33]); -int32_t iguana_launchcoin(char *symbol,cJSON *json); +//int32_t btc_priv2wif(char *wifstr,uint8_t privkey[32],uint8_t addrtype); +//int32_t btc_pub2rmd(uint8_t rmd160[20],uint8_t pubkey[33]); +int32_t iguana_launchcoin(struct supernet_info *myinfo,char *symbol,cJSON *json); +int32_t iguana_bundleinitmap(struct iguana_info *coin,struct iguana_bundle *bp,int32_t height,bits256 hash2,bits256 hash1); int32_t iguana_jsonQ(); -int32_t is_bitcoinrpc(char *method,char *remoteaddr); -char *iguana_bitcoinRPC(struct supernet_info *myinfo,char *method,cJSON *json,char *remoteaddr); +int32_t is_bitcoinrpc(struct supernet_info *myinfo,char *method,char *remoteaddr); +char *iguana_bitcoinRPC(struct supernet_info *myinfo,char *method,cJSON *json,char *remoteaddr,uint16_t port); cJSON *iguana_pubkeyjson(struct iguana_info *coin,char *pubkeystr); void iguana_bundleQ(struct iguana_info *coin,struct iguana_bundle *bp,int32_t timelimit); -int32_t iguana_bundleiters(struct iguana_info *coin,struct iguana_bundle *bp,int32_t timelimit); +int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_bundle *bp,int32_t timelimit,int32_t lag); void ramcoder_test(void *data,int64_t len); void iguana_exit(); int32_t iguana_pendingaccept(struct iguana_info *coin); -char *iguana_blockingjsonstr(struct supernet_info *myinfo,char *jsonstr,uint64_t tag,int32_t maxmillis,char *remoteaddr); +char *iguana_blockingjsonstr(struct supernet_info *myinfo,char *jsonstr,uint64_t tag,int32_t maxmillis,char *remoteaddr,uint16_t port); void iguana_iAkill(struct iguana_info *coin,struct iguana_peer *addr,int32_t markflag); cJSON *SuperNET_bits2json(uint8_t *serialized,int32_t datalen); int32_t SuperNET_sendmsg(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,bits256 destpub,bits256 mypriv,bits256 mypub,uint8_t *msg,int32_t len,uint8_t *data,int32_t delaymillis); int32_t category_peer(struct supernet_info *myinfo,struct iguana_peer *addr,bits256 category,bits256 subhash); -int32_t btc_wif2priv(uint8_t *addrtypep,uint8_t privkey[32],char *wifstr); -bits256 iguana_chaingenesis(int32_t version,uint32_t timestamp,uint32_t nBits,uint32_t nonce,bits256 merkle_root); +int32_t bitcoin_wif2priv(uint8_t *addrtypep,bits256 *privkeyp,char *wifstr); +int32_t bitcoin_priv2wif(char *wifstr,bits256 privkey,uint8_t addrtype); +bits256 iguana_chaingenesis(bits256 genesishash,char *genesisblock,char *hashalgostr,int32_t version,uint32_t timestamp,uint32_t bits,uint32_t nonce,bits256 merkle_root); int32_t iguana_send_ConnectTo(struct iguana_info *coin,struct iguana_peer *addr); cJSON *iguana_txjson(struct iguana_info *coin,struct iguana_txid *tx,int32_t height,struct vin_info *V); char *iguana_txscan(struct iguana_info *coin,cJSON *json,uint8_t *data,int32_t recvlen,bits256 txid); @@ -736,14 +807,158 @@ void exchanges777_init(struct supernet_info *myinfo,cJSON *exchanges,int32_t sle int32_t iguana_rwvout(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized,struct iguana_msgvout *msg); int32_t iguana_rwvin(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized,struct iguana_msgvin *msg); int32_t iguana_rwmsgtx(struct iguana_info *coin,int32_t rwflag,cJSON *json,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,bits256 *txidp,char *vpnstr); -int32_t iguana_ramtxbytes(struct iguana_info *coin,uint8_t *serialized,int32_t maxlen,bits256 *txidp,struct iguana_txid *tx,int32_t height,struct iguana_msgvin *vins,struct iguana_msgvout *vouts); +int32_t iguana_ramtxbytes(struct iguana_info *coin,uint8_t *serialized,int32_t maxlen,bits256 *txidp,struct iguana_txid *tx,int32_t height,struct iguana_msgvin *vins,struct iguana_msgvout *vouts,int32_t validatesigs); cJSON *bitcoin_txtest(struct iguana_info *coin,char *rawtxstr,bits256 txid); cJSON *iguana_blockjson(struct iguana_info *coin,struct iguana_block *block,int32_t txidsflag); //int32_t iguana_sig(uint8_t *sig,int32_t maxsize,uint8_t *data,int32_t datalen,bits256 privkey); //int32_t iguana_ver(uint8_t *sig,int32_t siglen,uint8_t *data,int32_t datalen,bits256 pubkey); //int32_t iguana_ver(uint8_t *sig,int32_t siglen,uint8_t *data,int32_t datalen,uint8_t *pubkey); +void calc_rmd160_sha256(uint8_t rmd160[20],uint8_t *data,int32_t datalen); +int32_t bitcoin_checklocktimeverify(uint8_t *script,int32_t n,uint32_t locktime); +struct bitcoin_spend *iguana_spendset(struct supernet_info *myinfo,struct iguana_info *coin,int64_t satoshis,int64_t insurance,char *account); +cJSON *bitcoin_hex2json(struct iguana_info *coin,bits256 *txidp,struct iguana_msgtx *msgtx,char *txbytes); +cJSON *iguana_signtx(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,char **signedtxp,struct bitcoin_spend *spend,cJSON *txobj,cJSON *vins); +void iguana_addscript(struct iguana_info *coin,cJSON *dest,uint8_t *script,int32_t scriptlen,char *fieldname); + +cJSON *bitcoin_txcreate(struct iguana_info *coin,int64_t locktime); +cJSON *bitcoin_txoutput(struct iguana_info *coin,cJSON *txobj,uint8_t *paymentscript,int32_t len,uint64_t satoshis); +cJSON *bitcoin_txinput(struct iguana_info *coin,cJSON *txobj,bits256 txid,int32_t vout,uint32_t sequenceid,uint8_t *spendscript,int32_t spendlen,uint8_t *redeemscript,int32_t p2shlen,uint8_t *pubkeys[],int32_t numpubkeys); + +int32_t bitcoin_changescript(struct iguana_info *coin,uint8_t *changescript,int32_t n,uint64_t *changep,char *changeaddr,uint64_t inputsatoshis,uint64_t satoshis,uint64_t txfee); +//cJSON *bitcoin_addinput(struct iguana_info *coin,cJSON *txobj,bits256 txid,int32_t vout,uint32_t sequenceid,uint8_t *spendscript,int32_t spendlen,uint8_t *redeemscript,int32_t p2shlen,uint8_t *pubkeys[],int32_t numpubkeys); +int32_t bitcoin_verifytx(struct iguana_info *coin,bits256 *signedtxidp,char **signedtx,char *rawtxstr,struct vin_info *V,int32_t numinputs); +int32_t bitcoin_verify(void *ctx,uint8_t *sig,int32_t siglen,bits256 txhash2,uint8_t *pubkey,int32_t plen); +char *bitcoin_json2hex(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,cJSON *txjson,struct vin_info *V); +int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr); +char *issue_startForging(struct supernet_info *myinfo,char *secret); +struct bitcoin_unspent *iguana_unspentsget(struct supernet_info *myinfo,struct iguana_info *coin,char **retstrp,double *balancep,int32_t *numunspentsp,double minconfirms,char *account); +void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson); +int32_t iguana_pkhasharray(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *array,int32_t minconf,int32_t maxconf,int64_t *totalp,struct iguana_pkhash *P,int32_t max,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33,int32_t lastheight,uint64_t *unspents,int32_t *numunspentsp,int32_t maxunspents); +long iguana_spentsfile(struct iguana_info *coin,int32_t n); +uint8_t *iguana_rmdarray(struct iguana_info *coin,int32_t *numrmdsp,cJSON *array,int32_t firsti); +int64_t iguana_unspents(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *array,int32_t minconf,int32_t maxconf,uint8_t *rmdarray,int32_t numrmds,int32_t lastheight,uint64_t *unspents,int32_t *numunspentsp); +uint8_t *iguana_walletrmds(struct supernet_info *myinfo,struct iguana_info *coin,int32_t *numrmdsp); +char *iguana_bundleaddrs(struct iguana_info *coin,int32_t hdrsi); +uint32_t iguana_sparseaddpk(uint8_t *bits,int32_t width,uint32_t tablesize,uint8_t rmd160[20],struct iguana_pkhash *P,uint32_t pkind,struct iguana_ramchain *ramchain); +int32_t iguana_vinscriptparse(struct iguana_info *coin,struct vin_info *vp,uint32_t *sigsizep,uint32_t *pubkeysizep,uint32_t *p2shsizep,uint32_t *suffixp,uint8_t *vinscript,int32_t scriptlen); +void iguana_parsebuf(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msghdr *H,uint8_t *buf,int32_t len); +int32_t _iguana_calcrmd160(struct iguana_info *coin,struct vin_info *vp); +int32_t iguana_spendvectors(struct iguana_info *coin,struct iguana_bundle *bp,struct iguana_ramchain *ramchain,int32_t starti,int32_t numblocks,int32_t convertflag,int32_t iterate); +int32_t iguana_balancegen(struct iguana_info *coin,int32_t incremental,struct iguana_bundle *bp,int32_t startheight,int32_t endheight,int32_t startemit); +int32_t iguana_bundlevalidate(struct iguana_info *coin,struct iguana_bundle *bp,int32_t forceflag); +void iguana_validateQ(struct iguana_info *coin,struct iguana_bundle *bp); +struct iguana_bloominds iguana_calcbloom(bits256 hash2); +int32_t iguana_bloomfind(struct iguana_info *coin,struct iguana_bloom16 *bloom,int32_t incr,struct iguana_bloominds bit); +struct iguana_bloominds iguana_bloomset(struct iguana_info *coin,struct iguana_bloom16 *bloom,int32_t incr,struct iguana_bloominds bit); +int32_t iguana_Xspendmap(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct iguana_bundle *bp); +//void iguana_balancesQ(struct iguana_info *coin,struct iguana_bundle *bp); +int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi); +int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int32_t starti,int32_t max); +int32_t iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp,int32_t startheight,int32_t endheight); +int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t iamthreadsafe); +int32_t iguana_blockreq(struct iguana_info *coin,int32_t height,int32_t priority); +int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp,int32_t lag); +int32_t iguana_ramchain_prefetch(struct iguana_info *coin,struct iguana_ramchain *ramchain,int32_t txonly); +int32_t iguana_realtime_update(struct iguana_info *coin); +int32_t iguana_volatilesmap(struct iguana_info *coin,struct iguana_ramchain *ramchain); +void iguana_volatilespurge(struct iguana_info *coin,struct iguana_ramchain *ramchain); +int32_t iguana_volatilesinit(struct iguana_info *coin); +void iguana_initfinal(struct iguana_info *coin,bits256 lastbundle); +int64_t iguana_ramchainopen(char *fname,struct iguana_info *coin,struct iguana_ramchain *ramchain,struct OS_memspace *mem,struct OS_memspace *hashmem,int32_t bundleheight,bits256 hash2); +int32_t iguana_ramchain_free(struct iguana_info *coin,struct iguana_ramchain *ramchain,int32_t deleteflag); +void iguana_blocksetcounters(struct iguana_info *coin,struct iguana_block *block,struct iguana_ramchain * ramchain); +int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain *dest,struct iguana_ramchain *ramchain,struct iguana_bundle *bp,int16_t bundlei); +void *iguana_bundlefile(struct iguana_info *coin,char *fname,long *filesizep,struct iguana_bundle *bp,int32_t bundlei); +int32_t iguana_mapchaininit(char *fname,struct iguana_info *coin,struct iguana_ramchain *mapchain,struct iguana_bundle *bp,int32_t bundlei,struct iguana_block *block,void *ptr,long filesize); +void iguana_autoextend(struct iguana_info *coin,struct iguana_bundle *bp); +void iguana_RTramchainfree(struct iguana_info *coin,struct iguana_bundle *bp); +void iguana_coinpurge(struct iguana_info *coin); +int32_t iguana_setmaxbundles(struct iguana_info *coin); +void iguana_bundlepurgefiles(struct iguana_info *coin,struct iguana_bundle *bp); +uint32_t iguana_sparseaddtx(uint8_t *bits,int32_t width,uint32_t tablesize,bits256 txid,struct iguana_txid *T,uint32_t txidind,struct iguana_ramchain *ramchain); +void iguana_launchpeer(struct iguana_info *coin,char *ipaddr); +//void iguana_spendvectorsQ(struct iguana_info *coin,struct iguana_bundle *bp); +int8_t iguana_blockstatus(struct iguana_info *coin,struct iguana_block *block); +int32_t iguana_peerslotinit(struct iguana_info *coin,struct iguana_peer *addr,int32_t slotid,uint64_t ipbits); +void iguana_blockunmark(struct iguana_info *coin,struct iguana_block *block,struct iguana_bundle *bp,int32_t i,int32_t deletefile); +int32_t iguana_reqblocks(struct iguana_info *coin); +void iguana_walletlock(struct supernet_info *myinfo,struct iguana_info *coin); +int32_t _SuperNET_encryptjson(char *destfname,char *passphrase,int32_t passsize,char *fname2fa,int32_t fnamesize,cJSON *argjson); +int32_t bitcoin_pubkeylen(const uint8_t *pubkey); +struct iguana_block *iguana_bundleblock(struct iguana_info *coin,bits256 *hash2p,struct iguana_bundle *bp,int32_t i); +void *iguana_ramchainfile(struct iguana_info *coin,struct iguana_ramchain *dest,struct iguana_ramchain *R,struct iguana_bundle *bp,int32_t bundlei,struct iguana_block *block); +int32_t iguana_bundlehashadd(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei,struct iguana_block *block); +int32_t iguana_convert(struct iguana_info *coin,int32_t helperid,struct iguana_bundle *bp,int32_t RTflag,int32_t starti); +int32_t iguana_bundleissuemissing(struct iguana_info *coin,struct iguana_bundle *bp,int32_t priority,double mult); +FILE *myfopen(char *fname,char *mode); +int32_t myfclose(FILE *fp); +int32_t iguana_walkchain(struct iguana_info *coin,int32_t skipflag); +struct iguana_block *iguana_fastlink(struct iguana_info *coin,int32_t hwmheight); +int32_t iguana_balancenormal(struct iguana_info *coin,struct iguana_bundle *bp,int32_t startheight,int32_t endheight); +int32_t iguana_spendvectorsaves(struct iguana_info *coin); +int32_t iguana_convertfinished(struct iguana_info *coin); +int32_t iguana_emitfinished(struct iguana_info *coin,int32_t queueincomplete); +int32_t iguana_utxofinished(struct iguana_info *coin); +int32_t iguana_balancefinished(struct iguana_info *coin); +int32_t iguana_alloctxbits(struct iguana_info *coin,struct iguana_ramchain *ramchain); +void iguana_allocvolatile(struct iguana_info *coin,struct iguana_ramchain *ramchain); +int32_t iguana_rwaddr(int32_t rwflag,uint8_t *serialized,struct iguana_msgaddress *addr,int32_t protover); +struct iguana_waddress *iguana_waddresscreate(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waccount *wacct,char *coinaddr,char *redeemScript); + +int32_t iguana_peerhdrrequest(struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_peer *addr,bits256 hash2); +int32_t iguana_peeraddrrequest(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *space,int32_t max); +int32_t iguana_peerdatarequest(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *space,int32_t max); +int32_t iguana_peergetrequest(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *data,int32_t recvlen,int32_t getblock); +int32_t iguana_bundlefname(struct iguana_info *coin,struct iguana_bundle *bp,char *fname); +int32_t iguana_bundleremove(struct iguana_info *coin,int32_t hdrsi,int32_t tmpfiles); +int32_t iguana_voutsfname(struct iguana_info *coin,int32_t roflag,char *fname,int32_t slotid); +int32_t iguana_vinsfname(struct iguana_info *coin,int32_t roflag,char *fname,int32_t slotid); +bits256 iguana_merkle(struct iguana_info *coin,bits256 *tree,int32_t txn_count); +int32_t iguana_bundleready(struct iguana_info *coin,struct iguana_bundle *bp,int32_t requiredflag); +int32_t iguana_blast(struct iguana_info *coin,struct iguana_peer *addr); +int32_t iguana_validated(struct iguana_info *coin); +void iguana_volatilesalloc(struct iguana_info *coin,struct iguana_ramchain *ramchain,int32_t copyflag); +int32_t iguana_send_ping(struct iguana_info *coin,struct iguana_peer *addr); +int32_t iguana_process_msgrequestQ(struct iguana_info *coin); +uint32_t iguana_fastfindinit(struct iguana_info *coin); +int32_t iguana_unspentindfind(struct iguana_info *coin,char *coinaddr,uint8_t *spendscript,int32_t *scriptlenp,uint64_t *valuep,int32_t *heightp,bits256 txid,int32_t vout,int32_t lasthdrsi); +int32_t iguana_addressvalidate(struct iguana_info *coin,uint8_t *addrtypep,uint8_t rmd160[20],char *address); +int32_t bitcoin_sign(void *ctx,char *symbol,uint8_t *sig,bits256 txhash2,bits256 privkey,int32_t recoverflag); +bits256 iguana_str2priv(struct supernet_info *myinfo,struct iguana_info *coin,char *str); +int32_t iguana_spentflag(struct iguana_info *coin,int64_t *RTspendp,int32_t *spentheightp,struct iguana_ramchain *ramchain,int16_t spent_hdrsi,uint32_t spent_unspentind,int32_t height,int32_t minconf,int32_t maxconf,uint64_t amount); +int32_t iguana_voutscript(struct iguana_info *coin,struct iguana_bundle *bp,uint8_t *scriptspace,char *asmstr,struct iguana_unspent *u,struct iguana_pkhash *p,int32_t txi); +cJSON *iguana_unspentjson(struct supernet_info *myinfo,struct iguana_info *coin,int32_t hdrsi,uint32_t unspentind,struct iguana_txid *T,struct iguana_unspent *up,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33); +int32_t bitcoin_standardspend(uint8_t *script,int32_t n,uint8_t rmd160[20]); +struct iguana_waddress *iguana_waddresssearch(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waccount **wacctp,char *coinaddr); +int64_t iguana_addressreceived(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *json,char *remoteaddr,cJSON *txids,cJSON *vouts,char *coinaddr,int32_t minconf); +cJSON *iguana_walletjson(struct supernet_info *myinfo); +int32_t iguana_payloadupdate(struct supernet_info *myinfo,struct iguana_info *coin,char *retstr,struct iguana_waddress *waddr,char *account); +int32_t bitcoin_MofNspendscript(uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,const struct vin_info *vp); +cJSON *iguana_p2shjson(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *retjson,struct iguana_waddress *waddr); +char *setaccount(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waddress **waddrp,char *account,char *coinaddr,char *redeemScript); +char *iguana_APIrequest(struct iguana_info *coin,bits256 blockhash,bits256 txid,int32_t seconds); +int32_t bitcoin_verifyvins(struct iguana_info *coin,bits256 *signedtxidp,char **signedtx,struct iguana_msgtx *msgtx,uint8_t *serialized,int32_t maxsize,struct vin_info *V,int32_t sighash); +int64_t iguana_fastfindcreate(struct iguana_info *coin); +int32_t bitcoin_validaddress(struct iguana_info *coin,char *coinaddr); +int32_t iguana_volatileupdate(struct iguana_info *coin,int32_t incremental,struct iguana_ramchain *spentchain,int16_t spent_hdrsi,uint32_t spent_unspentind,uint32_t spent_pkind,uint64_t spent_value,uint32_t spendind,uint32_t fromheight); +int32_t iguana_utxoupdate(struct iguana_info *coin,int16_t spent_hdrsi,uint32_t spent_unspentind,uint32_t spent_pkind,uint64_t spent_value,uint32_t spendind,uint32_t fromheight); +int32_t iguana_unspentslists(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waddress **waddrs,int32_t maxwaddrs,int64_t required,int32_t minconf,char *account); +int64_t iguana_unspentset(struct supernet_info *myinfo,struct iguana_info *coin); +int32_t iguana_txidfastfind(struct iguana_info *coin,int32_t *heightp,bits256 txid,int32_t lasthdrsi); +uint8_t iguana_addrtype(struct iguana_info *coin,uint8_t script_type); +struct iguana_waddress *iguana_waddressadd(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waccount *wacct,struct iguana_waddress *addwaddr,char *redeemScript); +cJSON *iguana_createvins(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *txobj,cJSON *vins); +bits256 bitcoin_pubkey33(void *ctx,uint8_t *data,bits256 privkey); +bits256 bitcoin_randkey(void *ctx); +int32_t bitcoin_recoververify(void *ctx,char *symbol,uint8_t *sig64,bits256 messagehash2,uint8_t *pubkey); +int32_t bitcoin_assembler(struct iguana_info *coin,uint8_t script[IGUANA_MAXSCRIPTSIZE],cJSON *scriptobj,int32_t interpret,int64_t nLockTime,struct vin_info *V); +cJSON *iguana_spendasm(struct iguana_info *coin,uint8_t *spendscript,int32_t spendlen); + +extern int32_t HDRnet,netBLOCKS; + +extern queue_t bundlesQ,emitQ,TerminateQ; +extern char GLOBAL_TMPDIR[],GLOBAL_VALIDATEDIR[],GLOBAL_HELPDIR[],GLOBAL_DBDIR[],GLOBAL_CONFSDIR[]; -extern queue_t bundlesQ; #include "../includes/iguana_api.h" diff --git a/iguana/iguana_accept.c b/iguana/iguana_accept.c index 7b9d9b8b1..6a5f15ea8 100755 --- a/iguana/iguana_accept.c +++ b/iguana/iguana_accept.c @@ -66,8 +66,17 @@ void iguana_acceptloop(void *args) struct pollfd pfd; int32_t sock; struct iguana_accept *ptr; uint16_t port = coin->chain->portp2p; socklen_t clilen; struct sockaddr_in cli_addr; char ipaddr[64]; uint32_t i,ipbits; while ( (coin->bindsock= iguana_socket(1,"0.0.0.0",port)) < 0 ) + { + if ( coin->peers.localaddr != 0 ) + { + printf("another daemon running, no need to have iguana accept connections\n"); + return; + } + if ( port != IGUANA_RPCPORT ) + return; sleep(5); - printf(">>>>>>>>>>>>>>>> iguana_bindloop 127.0.0.1:%d bind sock.%d\n",coin->chain->portp2p,coin->bindsock); + } + printf(">>>>>>>>>>>>>>>> iguana_bindloop 127.0.0.1:%d bind sock.%d\n",port,coin->bindsock); printf("START ACCEPTING\n"); while ( coin->bindsock >= 0 ) { @@ -77,7 +86,7 @@ void iguana_acceptloop(void *args) if ( poll(&pfd,1,100) <= 0 ) continue; clilen = sizeof(cli_addr); - printf("ACCEPT (%s:%d) on sock.%d\n","127.0.0.1",coin->chain->portp2p,coin->bindsock); + //printf("ACCEPT (%s:%d) on sock.%d\n","127.0.0.1",coin->chain->portp2p,coin->bindsock); sock = accept(coin->bindsock,(struct sockaddr *)&cli_addr,&clilen); if ( sock < 0 ) { @@ -86,16 +95,21 @@ void iguana_acceptloop(void *args) } memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); expand_ipbits(ipaddr,ipbits); - printf("NEWSOCK.%d for %x (%s)\n",sock,ipbits,ipaddr); for (i=0; ipeers.active[i].ipbits == (uint32_t)ipbits && coin->peers.active[i].usock >= 0 ) { printf("found existing peer.(%s) in slot[%d]\n",ipaddr,i); - iguana_iAkill(coin,&coin->peers.active[i],0); - sleep(1); + close(sock); + sock = -1; + //iguana_iAkill(coin,&coin->peers.active[i],0); + //sleep(1); + break; } } + if ( sock < 0 ) + continue; + printf("NEWSOCK.%d for %x (%s)\n",sock,ipbits,ipaddr); /*if ( (uint32_t)ipbits == myinfo->myaddr.myipbits ) { @@ -114,6 +128,7 @@ void iguana_acceptloop(void *args) { printf("LAUNCH DEDICATED THREAD for %s\n",ipaddr); addr->usock = sock; + addr->dead = 0; strcpy(addr->symbol,coin->symbol); iguana_launch(coin,"accept",iguana_dedicatedglue,addr,IGUANA_CONNTHREAD); //iguana_dedicatedloop(coin,addr); @@ -139,6 +154,7 @@ int32_t iguana_pendingaccept(struct iguana_info *coin) } return(0); } + /*int32_t iguana_acceptport(struct iguana_info *coin,uint16_t port) { if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)iguana_acceptloop,(void *)coin) != 0 ) @@ -148,3 +164,172 @@ int32_t iguana_pendingaccept(struct iguana_info *coin) } return(0); }*/ + +void iguana_msgrequestQ(struct iguana_info *coin,struct iguana_peer *addr,int32_t type,bits256 hash2) +{ + struct iguana_peermsgrequest *msg; + msg = calloc(1,sizeof(*msg)); + msg->addr = addr; + msg->hash2 = hash2; + msg->type = type; + queue_enqueue("msgrequest",&coin->msgrequestQ,&msg->DL,0); +} + +int32_t iguana_process_msgrequestQ(struct iguana_info *coin) +{ + struct iguana_peermsgrequest *msg; int32_t height,len,flag = 0; bits256 checktxid; struct iguana_txid *tx,T; + if ( (msg= queue_dequeue(&coin->msgrequestQ,0)) != 0 ) + { + flag = 1; + if ( msg->addr != 0 ) + { + char str[65]; printf("send type.%d %s -> (%s)\n",msg->type,bits256_str(str,msg->hash2),msg->addr->ipaddr); + if ( msg->type == MSG_BLOCK ) + { + if ( coin->RELAYNODE != 0 || coin->VALIDATENODE ) + { + if ( (len= iguana_peerblockrequest(coin,&coin->blockspace[sizeof(struct iguana_msghdr)],sizeof(coin->blockspace),0,msg->hash2,0)) > 0 ) + { + iguana_queue_send(coin,msg->addr,0,coin->blockspace,"block",len,0,0); + } + } + } + else if ( msg->type == MSG_TX ) + { + if ( coin->RELAYNODE != 0 || coin->VALIDATENODE ) + { + if ( (tx= iguana_txidfind(coin,&height,&T,msg->hash2,coin->bundlescount-1)) != 0 ) + { + if ( (len= iguana_ramtxbytes(coin,&coin->blockspace[sizeof(struct iguana_msghdr)],sizeof(coin->blockspace),&checktxid,tx,height,0,0,0)) > 0 ) + { + char str[65],str2[65]; + if ( bits256_cmp(msg->hash2,checktxid) == 0 ) + iguana_queue_send(coin,msg->addr,0,coin->blockspace,"block",len,0,0); + else printf("checktxid mismatch (%s) != (%s)\n",bits256_str(str,msg->hash2),bits256_str(str2,checktxid)); + } + } + } + } + else if ( msg->type == MSG_FILTERED_BLOCK ) + { + + } + else if ( msg->type == MSG_BUNDLE_HEADERS ) + { + + } + else if ( msg->type == MSG_BUNDLE ) + { + + } + } + free(msg); + } + return(flag); +} + +int32_t iguana_peerdatarequest(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *data,int32_t recvlen) +{ + int32_t i,type,len = 0; uint64_t x; bits256 hash2; + len += iguana_rwvarint(0,data,&x); + //for (i=0; i<10; i++) + // printf("%02x ",data[i]); + //printf("x.%d recvlen.%d\n",(int32_t)x,recvlen); + if ( x < IGUANA_MAXINV ) + { + for (i=0; ibundlescount-1)) != 0 ) + { + bundlesize = coin->chain->bundlesize; + hdrsi = (height / bundlesize); + bundlei = height - (hdrsi * bundlesize); + if ( hdrsi >= 0 && hdrsi < bundlesize && bundlei >= 0 && bundlei < bundlesize && (bp= coin->bundles[hdrsi]) != 0 ) + { + for (i=0; ichain->bundlesize; i++) + { + if ( (block= bp->blocks[i]) != 0 ) + { + iguana_blockunconv(&msgB,block,1); + len += iguana_rwblock(1,&checkhash2,&serialized[sizeof(struct iguana_msghdr) + len],&msgB); + if ( bits256_cmp(checkhash2,block->RO.hash2) != 0 ) + { + char str[65],str2[65]; + printf("iguana_peerhdrrequest blockhash.%d error (%s) vs (%s)\n",height+i,bits256_str(str,checkhash2),bits256_str(str2,block->RO.hash2)); + return(-1); + } + } else printf("cant find block at ht.%d\n",height+i); + } + } + retval = iguana_queue_send(coin,addr,0,serialized,"headers",len,0,0); + printf("hdrs request retval.%d len.%d\n",retval,len); + } //else printf("couldnt find header\n"); + return(retval); +} + +int32_t iguana_peergetrequest(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *data,int32_t recvlen,int32_t getblock) +{ + int32_t i,reqvers,len,n,flag = 0; bits256 hash2; + if ( getblock != 0 ) + addr->msgcounts.getblocks++; + else addr->msgcounts.getheaders++; + len = iguana_rwnum(0,&data[0],sizeof(uint32_t),&reqvers); + len += iguana_rwvarint32(0,&data[len],(uint32_t *)&n); + for (i=0; iblockspace,sizeof(addr->blockspace),addr,hash2,0) > 0 ) + flag = 1; + else if ( getblock == 0 && iguana_peerhdrrequest(coin,addr->blockspace,sizeof(addr->blockspace),addr,hash2) > 0 ) + flag = 1; + } + } + len += iguana_rwbignum(0,&data[len],sizeof(bits256),hash2.bytes); + //for (i=0; i<69; i++) + // printf("%02x ",data[i]); + //printf("version.%d num blocks.%d recvlen.%d len.%d\n",reqvers,n,recvlen,len); + return(len); +} + +int32_t iguana_peeraddrrequest(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *space,int32_t spacesize) +{ + int32_t i,iter,n,max,sendlen; uint64_t x; struct iguana_msghdr H; struct iguana_peer *tmpaddr; + sendlen = 0; + max = (IGUANA_MINPEERS + IGUANA_MAXPEERS) / 2; + if ( max > coin->peers.numranked ) + max = coin->peers.numranked; + x = 0; + sendlen = iguana_rwvarint(1,&space[sizeof(H)],&x); + for (iter=0; iter<2; iter++) + { + for (i=n=0; ipeers.ranked[i]) != 0 && ((iter == 0 && tmpaddr->supernet != 0) || (iter == 1 && tmpaddr->supernet == 0)) && tmpaddr->ipaddr[0] != 0 ) + { + sendlen += iguana_rwaddr(1,&space[sizeof(H) + sendlen],&tmpaddr->A,(int32_t)tmpaddr->protover); + printf("(%s) ",tmpaddr->ipaddr); + x++; + } + } + } + iguana_rwvarint(1,&space[sizeof(H)],&x); + printf("addrrequest: sendlen.%d x.%d\n",sendlen,(int32_t)x); + if ( x == 0 ) + return(-1); + return(sendlen); +} \ No newline at end of file diff --git a/iguana/iguana_blocks.c b/iguana/iguana_blocks.c index 13f1390e8..18e1fdb56 100755 --- a/iguana/iguana_blocks.c +++ b/iguana/iguana_blocks.c @@ -15,7 +15,30 @@ #include "iguana777.h" -#define iguana_blockfind(coin,hash2) iguana_blockhashset(coin,-1,hash2,0) +bits256 iguana_merkle(struct iguana_info *coin,bits256 *tree,int32_t txn_count) +{ + int32_t i,n=0,prev; uint8_t serialized[sizeof(bits256) * 2]; + if ( txn_count == 1 ) + return(tree[0]); + prev = 0; + while ( txn_count > 1 ) + { + if ( (txn_count & 1) != 0 ) + tree[prev + txn_count] = tree[prev + txn_count-1], txn_count++; + n += txn_count; + for (i=0; i> 1)] = bits256_doublesha256(0,serialized,sizeof(serialized)); + } + prev = n; + txn_count >>= 1; + } + return(tree[n]); +} + +#define iguana_blockfind(str,coin,hash2) iguana_blockhashset(str,coin,-1,hash2,0) void _iguana_blocklink(struct iguana_info *coin,struct iguana_block *prev,struct iguana_block *block) { @@ -45,28 +68,41 @@ void _iguana_blocklink(struct iguana_info *coin,struct iguana_block *prev,struct printf("link.(%s) -> (%s)\n",bits256_str(str,prev->RO.hash2),bits256_str(str,block->RO.hash2)); } -struct iguana_block *iguana_blockhashset(struct iguana_info *coin,int32_t height,bits256 hash2,int32_t createflag) +struct iguana_block *iguana_blockhashset(char *debugstr,struct iguana_info *coin,int32_t height,bits256 hash2,int32_t createflag) { - static int depth; struct iguana_block *block,*prev; - if ( height > 0 && (height > coin->blocks.maxbits || depth != 0) ) + if ( height > 0 && height > coin->blocks.maxbits ) { - printf("illegal height.%d when max.%d, depth.%d\n",height,coin->blocks.maxbits,depth); + printf("%s: illegal height.%d when max.%d, or nonz depth.%d\n",debugstr,height,coin->blocks.maxbits,coin->blockdepth); //getchar(); return(0); } - depth++; - //portable_mutex_lock(&coin->blocks_mutex); + while ( coin->blockdepth > 0 ) + { + sleep(1); + printf("%s >>>>>>>>>> OK only if rare %s blockhashset.%d depth.%d\n",coin->symbol,debugstr,height,coin->blockdepth); + //fprintf(stderr,">>>>>>>>>> OK only if rare %s blockhashset.%d depth.%d\n",debugstr,height,depth); + //printf("%d\n",1/(1 - depth/depth)); + } + coin->blockdepth++; HASH_FIND(hh,coin->blocks.hash,&hash2,sizeof(hash2),block); if ( block != 0 ) { - // portable_mutex_unlock(&coin->blocks_mutex); - depth--; + if ( coin->blockdepth > 0 ) + coin->blockdepth--; + while ( coin->blockdepth > 0 ) + { + sleep(1); + printf(" %s >>>>>>>>>> OK only if rare %s match blockhashset.%d depth.%d\n",coin->symbol,debugstr,height,coin->blockdepth); + //fprintf(stderr,">>>>>>>>>> OK only if rare%s match blockhashset.%d depth.%d\n",debugstr,height,depth); + //printf("%d\n",1/(1 - depth/depth)); + } return(block); } if ( createflag > 0 ) { - block = mycalloc('x',1,sizeof(*block)); + portable_mutex_lock(&coin->blocks_mutex); + block = calloc(1,sizeof(*block)); block->RO.hash2 = hash2; block->hh.itemind = height, block->height = -1; HASH_ADD(hh,coin->blocks.hash,RO.hash2,sizeof(hash2),block); @@ -87,18 +123,32 @@ struct iguana_block *iguana_blockhashset(struct iguana_info *coin,int32_t height if ( tmp != block ) printf("%s height.%d search error %p != %p\n",str,height,block,tmp); } + portable_mutex_unlock(&coin->blocks_mutex); + } + if ( coin->blockdepth > 0 ) + coin->blockdepth--; + while ( coin->blockdepth > 0 ) + { + sleep(1); + printf("%s >>>>>>>>>> OK only if rare %s create blockhashset.%d depth.%d\n",coin->symbol,debugstr,height,coin->blockdepth); + //fprintf(stderr,">>>>>>>>>> OK only if rare%s create blockhashset.%d depth.%d\n",debugstr,height,depth); + //printf("%d\n",1/(1 - depth/depth)); } - //portable_mutex_unlock(&coin->blocks_mutex); - depth--; return(block); } bits256 *iguana_blockhashptr(struct iguana_info *coin,int32_t height) { - int32_t i; struct iguana_bundle *bp; bits256 *hashptr; - if ( height >= 0 ) + int32_t hdrsi,bundlei,bundlesize; struct iguana_bundle *bp; //bits256 *hashptr; + if ( height >= 0 && (bundlesize= coin->chain->bundlesize) != 0 ) { - for (i=0; ibundlescount; i++) + hdrsi = (height / bundlesize); + bundlei = height - (hdrsi * bundlesize); + if ( hdrsi >= 0 && hdrsi < bundlesize && bundlei >= 0 && bundlei < bundlesize && (bp= coin->bundles[hdrsi]) != 0 ) + { + return(&bp->hashes[bundlei]); + } + /*for (i=0; ibundlescount; i++) { if ( (bp= coin->bundles[i]) != 0 ) { @@ -109,7 +159,7 @@ bits256 *iguana_blockhashptr(struct iguana_info *coin,int32_t height) return(hashptr); } } - } + }*/ } return(0); } @@ -122,11 +172,11 @@ bits256 iguana_blockhash(struct iguana_info *coin,int32_t height) return(zero); } -struct iguana_block *iguana_blockptr(struct iguana_info *coin,int32_t height) +struct iguana_block *iguana_blockptr(char *debugstr,struct iguana_info *coin,int32_t height) { static const bits256 zero; bits256 hash2 = iguana_blockhash(coin,height); if ( memcmp(zero.bytes,hash2.bytes,sizeof(zero)) != 0 ) - return(iguana_blockfind(coin,hash2)); + return(iguana_blockfind(debugstr,coin,hash2)); return(0); } @@ -141,7 +191,10 @@ int32_t iguana_blockvalidate(struct iguana_info *coin,int32_t *validp,struct igu if ( *validp == 0 ) { if ( dispflag != 0 ) + { printf("iguana_blockvalidate: miscompare (%s) vs (%s)\n",bits256_str(str,hash2),bits256_str(str2,block->RO.hash2)); + //getchar(); + } return(-1); } return(0); @@ -188,12 +241,29 @@ void iguana_blockconv(struct iguana_block *dest,struct iguana_msgblock *msg,bits dest->RO.hash2 = hash2; } +void iguana_blockunconv(struct iguana_msgblock *msg,struct iguana_block *src,int32_t cleartxn_count) +{ + memset(msg,0,sizeof(*msg)); + msg->H.version = src->RO.version; + msg->H.prev_block = src->RO.prev_block; + msg->H.merkle_root = src->RO.merkle_root; + msg->H.timestamp = src->RO.timestamp; + msg->H.bits = src->RO.bits; + msg->H.nonce = src->RO.nonce; + if ( cleartxn_count == 0 ) + msg->txn_count = src->RO.txn_count; +} + void iguana_blockcopy(struct iguana_info *coin,struct iguana_block *block,struct iguana_block *origblock) { block->RO.hash2 = origblock->RO.hash2; - block->RO.prev_block = origblock->RO.prev_block; block->RO.merkle_root = origblock->RO.merkle_root; - block->mainchain = origblock->mainchain; + if ( bits256_nonz(block->RO.prev_block) == 0 ) + block->RO.prev_block = origblock->RO.prev_block; + if ( block->mainchain == 0 ) + block->mainchain = origblock->mainchain; + if ( block->fpos < 0 ) + block->fpos = origblock->fpos; if ( block->fpipbits == 0 ) block->fpipbits = origblock->fpipbits; if ( block->RO.timestamp == 0 ) @@ -260,18 +330,129 @@ int32_t iguana_blockunmain(struct iguana_info *coin,struct iguana_block *block) return(n); } +int32_t iguana_walkchain(struct iguana_info *coin,int32_t skipflag) +{ + char str[65]; int32_t height,hdrsi,bundlei,n = 0; struct iguana_bundle *bp; struct iguana_block *block; + height = coin->blocks.hwmchain.height; + while ( 1 ) //(block= iguana_blockfind("main",coin,iguana_blockhash(coin,height))) != 0 ) + { + hdrsi = (height / coin->chain->bundlesize); + bundlei = (height % coin->chain->bundlesize); + if ( (bp= coin->bundles[hdrsi]) == 0 || (block= bp->blocks[bundlei]) == 0 ) + { + printf("walk error [%d:%d] %p vs %p\n",hdrsi,bundlei,block,bp->blocks[bundlei]); + break; + } + else if ( block->height >= 0 && block->height != height ) + printf("walkchain height mismatch %d vs %d\n",block->height,height); + if ( bits256_nonz(iguana_blockhash(coin,height)) != 0 && bits256_cmp(iguana_blockhash(coin,height),block->RO.hash2) != 0 ) + { + printf("walk error blockhash error at %d %s\n",height,bits256_str(str,iguana_blockhash(coin,height))); + break; + } + else if ( bits256_cmp(bp->hashes[bundlei],block->RO.hash2) != 0 ) + { + printf("walk error [%d:%d] %s vs %s\n",hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei]),bits256_str(str,block->RO.hash2)); + break; + } + else if ( block->hdrsi != hdrsi || block->bundlei != bundlei ) + { + printf("walk error [%d:%d] vs [%d:%d]\n",hdrsi,bundlei,block->hdrsi,block->bundlei); + break; + } + if ( height == 0 ) + break; + else if ( skipflag != 0 && (height % coin->chain->bundlesize) == 0 ) + { + n += coin->chain->bundlesize; + height -= coin->chain->bundlesize; + } + else + { + n++; + height--; + } + } + //printf("walk skip.%d n.%d hwm.%d %s\n",skipflag,n,coin->blocks.hwmchain.height,bits256_str(str,coin->blocks.hwmchain.RO.hash2)); + return(n); +} + +struct iguana_block *iguana_fastlink(struct iguana_info *coin,int32_t hwmheight) +{ + int32_t hdrsi,bundlei,height; struct iguana_block *block = 0,*prev=0; double prevPoW = 0.; struct iguana_bundle *bp; + for (height=0; height<=hwmheight; height++) + { + hdrsi = (height / coin->chain->bundlesize); + bundlei = (height % coin->chain->bundlesize); +/*#ifndef __PNACL__ + if ( (height % 10000) == 0 ) + fprintf(stderr,"."); +#endif*/ + if ( (bp= coin->bundles[hdrsi]) == 0 ) + { + printf("iguana_fastlink null bundle.[%d]\n",hdrsi); + break; + } + block = iguana_blockhashset("fastlink",coin,height,bp->hashes[bundlei],1); + if ( bp->blocks[bundlei] != 0 && block != bp->blocks[bundlei] ) + { + printf("iguana_fastlink null block.[%d:%d]\n",hdrsi,bundlei); + break; + } + if ( prev != 0 && bits256_nonz(block->RO.prev_block) == 0 ) + { + block->RO.prev_block = prev->RO.hash2; + printf("PATCH.[%d:%d] prev is null\n",bp->hdrsi,bundlei); + break; + } + bp->blocks[bundlei] = block; + coin->blocks.maxblocks = (block->height + 1); + if ( coin->blocks.maxblocks > coin->longestchain ) + coin->longestchain = coin->blocks.maxblocks; + coin->blocks.hwmchain = *block; + block->valid = block->mainchain = 1; + block->hdrsi = hdrsi, block->bundlei = bundlei; + block->height = height; + block->PoW = PoW_from_compact(block->RO.bits,coin->chain->unitval) + prevPoW; + block->hh.prev = prev; + if ( prev != 0 ) + prev->hh.next = block; + iguana_hash2set(coin,"fastlink",bp,bundlei,block->RO.hash2); + //iguana_bundlehash2add(coin,0,bp,bundlei,block->RO.hash2); + prev = block; + prevPoW = block->PoW; + } + return(block); +} + +int32_t process_iguanablock(void *pblock,void *chainparams); + +void *CHAINPARMS; +void iguana_setchain(void *chainparms) +{ + extern int32_t MAIN_initflag; + MAIN_initflag = 1; + OS_init(); + CHAINPARMS = chainparms; + printf("iguana_setchain chainparms.%p\n",chainparms); + iguana_launch(0,"iguana_main",iguana_main,0,0); + printf("RETURN iguana_setchain chainparms.%p\n",chainparms); +} + struct iguana_block *_iguana_chainlink(struct iguana_info *coin,struct iguana_block *newblock) { int32_t valid,bundlei,height=-1; struct iguana_block *hwmchain,*block = 0,*prev=0,*next; - bits256 *hash2p=0; double prevPoW = 0.; + bits256 *hash2p=0; double prevPoW = 0.; struct iguana_bundle *bp; if ( newblock == 0 ) return(0); hwmchain = &coin->blocks.hwmchain; - if ( (block= iguana_blockfind(coin,newblock->RO.hash2)) != 0 ) + if ( 0 && hwmchain->height > 0 && ((bp= coin->current) == 0 || hwmchain->height/coin->chain->bundlesize > bp->hdrsi+0*bp->isRT) ) + return(0); + if ( (block= iguana_blockfind("chainlink",coin,newblock->RO.hash2)) != 0 ) { if ( memcmp(coin->chain->genesis_hashdata,block->RO.hash2.bytes,sizeof(bits256)) == 0 ) block->PoW = PoW_from_compact(block->RO.bits,coin->chain->unitval), height = 0; - else if ( (prev= iguana_blockfind(coin,block->RO.prev_block)) != 0 ) + else if ( (prev= iguana_blockfind("chainprev",coin,block->RO.prev_block)) != 0 ) { if ( memcmp(prev->RO.hash2.bytes,coin->blocks.hwmchain.RO.hash2.bytes,sizeof(bits256)) == 0 ) prev->mainchain = 1; @@ -289,18 +470,22 @@ struct iguana_block *_iguana_chainlink(struct iguana_info *coin,struct iguana_bl } else { - char str[65]; printf("(%s) notready v.%d m.%d h.%d\n",bits256_str(str,prev->RO.hash2),prev->valid,prev->mainchain,prev->height); + //char str[65]; printf("(%s) notready v.%d m.%d h.%d\n",bits256_str(str,prev->RO.hash2),prev->valid,prev->mainchain,prev->height); return(0); } } else { - char str[65]; printf("chainlink error: cant find prev.(%s)\n",bits256_str(str,block->RO.prev_block)); + char str[65]; + if ( 0 && bits256_nonz(block->RO.prev_block) != 0 ) + printf("chainlink error: cant find prev.(%s)\n",bits256_str(str,block->RO.prev_block)); + iguana_blockunmark(coin,block,0,-1,0); + //memset(&block->RO.prev_block.bytes,0,sizeof(block->RO.prev_block)); //getchar(); return(0); } //char str[65]; printf("extend? %s.h%d: %.15f vs %.15f ht.%d vs %d\n",bits256_str(str,block->RO.hash2),height,block->PoW,coin->blocks.hwmchain.PoW,height,coin->blocks.hwmchain.height); - if ( iguana_blockvalidate(coin,&valid,newblock,1) < 0 || valid == 0 ) + if ( iguana_blockvalidate(coin,&valid,newblock,0) < 0 || valid == 0 ) return(0); block->height = height; block->valid = 1; @@ -324,38 +509,64 @@ struct iguana_block *_iguana_chainlink(struct iguana_info *coin,struct iguana_bl if ( hash2p != 0 ) bits256_str(str2,*hash2p); else str2[0] = 0; - if ( block->height+1 > coin->longestchain ) - coin->longestchain = block->height+1; - if ( 0 && (block->height % 1000) == 0 ) - printf("EXTENDMAIN %s %d <- (%s) n.%u max.%u PoW %f numtx.%d valid.%d\n",str,block->height,str2,hwmchain->height+1,coin->blocks.maxblocks,block->PoW,block->RO.txn_count,block->valid); - struct iguana_bundle *bp; + if ( coin->blocks.maxblocks > coin->longestchain ) + coin->longestchain = coin->blocks.maxblocks; + if ( 1 && (block->height % 1000) == 0 ) + { + //printf("EXTENDMAIN %s %d <- (%s) n.%u max.%u PoW %f numtx.%d valid.%d\n",str,block->height,str2,hwmchain->height+1,coin->blocks.maxblocks,block->PoW,block->RO.txn_count,block->valid); + //iguana_walkchain(coin); + } + struct iguana_bundle *bp; int32_t hdrsi; if ( (block->height % coin->chain->bundlesize) == 0 ) + { + if ( (hdrsi= block->height/coin->chain->bundlesize) < coin->bundlescount ) + { + if ( (bp= coin->bundles[hdrsi]) != 0 && bits256_cmp(block->RO.hash2,bp->hashes[0]) != 0 ) + { + printf(">>>>>>>>>>>>>> interloper bundle.[%d] ht.%d %s != %s\n",hdrsi,block->height,bits256_str(str,bp->hashes[0]),bits256_str(str2,block->RO.hash2)); + coin->bundles[hdrsi] = 0; + } + } bp = iguana_bundlecreate(coin,&bundlei,block->height,block->RO.hash2,zero,0); + if ( bp != 0 && bp->hdrsi == coin->bundlescount-1 ) + { + //printf("created last bundle ht.%d\n",bp->bundleheight); + iguana_blockreq(coin,block->height,1); + } + } else { if ( (bp= coin->bundles[block->height / coin->chain->bundlesize]) != 0 ) { - if ( memcmp(bp->hashes[block->height % coin->chain->bundlesize].bytes,block->RO.hash2.bytes,sizeof(bits256)) != 0 ) + if ( memcmp(bp->hashes[block->height % coin->chain->bundlesize].bytes,block->RO.hash2.bytes,sizeof(bits256)) != 0 || block != bp->blocks[block->height % coin->chain->bundlesize] ) { - if ( bits256_nonz(bp->hashes[block->height % coin->chain->bundlesize]) > 0 ) + if ( bits256_nonz(bp->hashes[block->height % coin->chain->bundlesize]) != 0 ) { - printf("ERROR: need to fix up bundle for height.%d\n",block->height); + char str[65],str2[65]; + printf("ERROR: need to fix up bundle for height.%d (%p %p) (%s %s)\n",block->height,block,bp->blocks[block->height % coin->chain->bundlesize],bits256_str(str,block->RO.hash2),bits256_str(str2,bp->hashes[block->height % coin->chain->bundlesize])); + if ( bp == coin->current && coin->RTheight > 0 ) + coin->RTdatabad = 1; + //iguana_bundleremove(coin,bp->hdrsi,0); + //exit(-1); //getchar(); } - bp->hashes[block->height % coin->chain->bundlesize] = block->RO.hash2; - bp->blocks[block->height % coin->chain->bundlesize] = block; + iguana_blockunmark(coin,block,bp,block->height % coin->chain->bundlesize,0); + iguana_bundlehash2add(coin,0,bp,block->height % coin->chain->bundlesize,block->RO.hash2); } - if ( coin->started != 0 && (block->height % coin->chain->bundlesize) == 10 ) + if ( coin->started != 0 && (block->height % coin->chain->bundlesize) == coin->minconfirms )//&& (block->height > coin->longestchain-coin->chain->bundlesize*2 || ((block->height / coin->chain->bundlesize) % 10) == 9) ) { - printf("savehdrs\n"); + //printf("savehdrs.[%d] ht.%d\n",bp->hdrsi,block->height); iguana_savehdrs(coin); - printf("done savehdrs\n"); + //printf("done savehdrs.%d\n",bp->hdrsi); } } } - //if ( block->fpipbits == 0 ) - // iguana_blockQ(coin,bp,block->height % coin->chain->bundlesize,block->RO.hash2,1); block->mainchain = 1; + /*if ( block->serdata != 0 ) + { + printf(" call process_iguanablock2.%p ht.%d nbits.%08x\n",block->serdata,block->height,*(uint32_t *)&block->serdata[72]); + process_iguanablock(block->serdata,CHAINPARMS); + }*/ return(block); } } @@ -379,25 +590,25 @@ void iguana_blocksetheights(struct iguana_info *coin,struct iguana_block *block) int32_t iguana_chainextend(struct iguana_info *coin,struct iguana_block *newblock) { struct iguana_block *block,*prev; int32_t valid,oldhwm; char str[65]; - if ( iguana_blockvalidate(coin,&valid,newblock,1) < 0 || valid == 0 ) + if ( iguana_blockvalidate(coin,&valid,newblock,0) < 0 || valid == 0 ) { printf("chainextend: newblock.%s didnt validate\n",bits256_str(str,newblock->RO.hash2)); return(-1); } else { - block = iguana_blockhashset(coin,-1,newblock->RO.hash2,1); + block = iguana_blockhashset("chainextend",coin,-1,newblock->RO.hash2,1); if ( block != newblock ) iguana_blockcopy(coin,block,newblock); block->valid = 1; - if ( block->hh.prev == 0 && (prev= iguana_blockfind(coin,block->RO.prev_block)) != 0 ) + if ( block->hh.prev == 0 && (prev= iguana_blockfind("extendprev",coin,block->RO.prev_block)) != 0 ) { if ( prev->hh.next == 0 && block->hh.prev == 0 ) prev->hh.next = block, block->hh.prev = prev; //printf("extend newblock.%s prevm.%d\n",bits256_str(str,block->prev_block),prev->mainchain); if ( prev->mainchain == 0 ) { - if ( (block= iguana_blockfind(coin,coin->blocks.hwmchain.RO.hash2)) != 0 && block->mainchain == 0 ) + if ( (block= iguana_blockfind("extendmain",coin,coin->blocks.hwmchain.RO.hash2)) != 0 && block->mainchain == 0 ) { //printf("c hwmchain is not mainchain anymore?\n"); prev->mainchain = 1; @@ -423,7 +634,7 @@ int32_t iguana_chainextend(struct iguana_info *coin,struct iguana_block *newbloc } } } - if ( (block= iguana_blockfind(coin,coin->blocks.hwmchain.RO.hash2)) != 0 && block->mainchain == 0 ) + if ( (block= iguana_blockfind("extendcheck",coin,coin->blocks.hwmchain.RO.hash2)) != 0 && block->mainchain == 0 ) { printf("hwmchain is not mainchain anymore?\n"); block->mainchain = 1; diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 984d4e47c..faf31f72c 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -17,7 +17,6 @@ static uint16_t iguana_primes[] = { 65353, 65357, 65371, 65381, 65393, 65407, 65413, 65419, 65423, 65437, 65447, 65449, 65479, 65497, 65519, 65521 }; -struct iguana_bloominds { uint16_t inds[8]; }; struct iguana_bloominds iguana_calcbloom(bits256 hash2) { @@ -76,6 +75,7 @@ struct iguana_bundle *iguana_bundlefind(struct iguana_info *coin,struct iguana_b if ( bp == 0 ) { for (i=coin->bundlescount-1; i>=0; i--) + //for (i=0; ibundlescount; i++) { if ( (bp= coin->bundles[i]) != 0 ) { @@ -86,8 +86,7 @@ struct iguana_bundle *iguana_bundlefind(struct iguana_info *coin,struct iguana_b { //printf("bloom miss\n"); coin->bloomfalse++; - } - else return(bp); + } else return(bp); } //else printf("no bloom\n"); } } @@ -136,7 +135,7 @@ int32_t iguana_hash2set(struct iguana_info *coin,char *debugstr,struct iguana_bu if ( bits256_nonz(newhash2) == 0 || (orighash2p= iguana_bundleihash2p(coin,&isinside,bp,bundlei)) == 0 ) { printf("iguana_hash2set warning: bundlei.%d newhash2.%s orighash2p.%p\n",bundlei,bits256_str(str,newhash2),orighash2p); - *orighash2p = newhash2; + //*orighash2p = newhash2; //getchar(); return(-1); } @@ -144,17 +143,17 @@ int32_t iguana_hash2set(struct iguana_info *coin,char *debugstr,struct iguana_bu { char str2[65],str3[65]; bits256_str(str2,*orighash2p), bits256_str(str3,newhash2); - printf("ERRRO iguana_hash2set overwrite [%s] %s with %s [%d:%d]\n",debugstr,str2,str3,bp->hdrsi,bundlei); + printf("WARNING iguana_hash2set overwrite [%s] %s with %s [%d:%d]\n",debugstr,str2,str3,bp->hdrsi,bundlei); *orighash2p = newhash2; - getchar(); - return(-1); + // getchar(); + // return(-1); } if ( isinside != 0 ) { bit = iguana_calcbloom(newhash2); if ( iguana_bloomfind(coin,&bp->bloom,0,bit) < 0 ) { - //printf("bloomset (%s)\n",bits256_str(str,newhash2)); + // printf("bloomset (%s) -> [%d:%d]\n",bits256_str(str,newhash2),bp->hdrsi,bundlei); iguana_bloomset(coin,&bp->bloom,0,bit); if ( 0 ) { @@ -181,20 +180,49 @@ int32_t iguana_hash2set(struct iguana_info *coin,char *debugstr,struct iguana_bu retval = 0; } else retval = (bundlei >= 0 && bundlei < coin->chain->bundlesize) ? 0 : 1; //printf("set [%d] <- %s\n",bundlei,bits256_str(str,newhash2)); - *orighash2p = newhash2; + if ( bits256_cmp(*orighash2p,newhash2) != 0 ) + { + if ( bits256_nonz(*orighash2p) != 0 && bp->bundleheight+bundlei <= coin->blocks.hwmchain.height ) + { + printf("changing [%d:%d] -> %d < hwmheight %d\n",bp->hdrsi,bundlei,bp->bundleheight+bundlei,coin->blocks.hwmchain.height); + if ( bp->bundleheight+bundlei > 0 ) + { + printf("REORG %d blocks\n",coin->blocks.hwmchain.height - (bp->bundleheight+bundlei)); + } + } + *orighash2p = newhash2; + } return(retval); } int32_t iguana_bundlehash2add(struct iguana_info *coin,struct iguana_block **blockp,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2) { - struct iguana_block *block =0; struct iguana_bundle *otherbp; // + struct iguana_block *block =0; struct iguana_bundle *otherbp; int32_t otherbundlei,setval,bundlesize,err = 0; if ( blockp != 0 ) *blockp = 0; - if ( bp == 0 ) + if ( bp == 0 || bits256_nonz(hash2) == 0 ) return(-1111); - if ( bits256_nonz(hash2) > 0 && (block= iguana_blockhashset(coin,-1,hash2,1)) != 0 ) + if ( bits256_nonz(hash2) != 0 && (block= iguana_blockhashset("bundlehash2add",coin,-1,hash2,1)) != 0 ) { + if ( bp->blocks[bundlei] != 0 && bp->blocks[bundlei] != block ) + { + //printf("bp.[%d]->blocks[%d] mismatch %p != %p\n",bp->hdrsi,bundlei,bp->blocks[bundlei],block); + iguana_blockunmark(coin,block,bp,bundlei,1); + bp->blocks[bundlei] = 0; + return(-1); + } + if ( bits256_nonz(bp->hashes[bundlei]) != 0 && bits256_cmp(bp->hashes[bundlei],block->RO.hash2) != 0 ) + { + //char str[65],str2[65]; + //printf("bp.[%d]->hashes[%d] mismatch %s != %s%s\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei]),bits256_str(str2,block->RO.hash2),block->mainchain?".main":""); + iguana_blockunmark(coin,block,bp,bundlei,1); + bp->blocks[bundlei] = 0; + //if ( block->mainchain != 0 ) + // bp->hashes[bundlei] = block->RO.hash2; + + return(-1); + } /*if ( (block->hdrsi != bp->hdrsi || block->bundlei != bundlei) && (block->hdrsi != 0 || block->bundlei != 0) ) { return(-2); @@ -211,17 +239,25 @@ int32_t iguana_bundlehash2add(struct iguana_info *coin,struct iguana_block **blo { if ( (block->hdrsi != bp->hdrsi || block->bundlei != bundlei) && (block->hdrsi != 0 || block->bundlei != 0) ) { - printf("blockadd warning: %d[%d] <- %d[%d]\n",block->hdrsi,block->bundlei,bp->hdrsi,bundlei); + char str[65]; printf("blockadd warning: %d[%d] main.%d <- %d[%d] %s\n",block->hdrsi,block->bundlei,block->mainchain,bp->hdrsi,bundlei,bits256_str(str,hash2)); + iguana_blockunmark(coin,block,bp,bundlei,block->mainchain != 0); err |= 2; - exit(-1); + return(-1); + //exit(-1); } else { -//char str[65]; printf(">>>>>>>>>>>>>> bundlehash2.(%s) ht.(%d %d)\n",bits256_str(str,hash2),bp->bundleheight,bundlei); + char str[65]; block->hdrsi = bp->hdrsi; block->bundlei = bundlei; - bp->blocks[bundlei] = block; - otherbp = 0; + bp->hashes[bundlei] = block->RO.hash2; + if ( bp->speculative != 0 && bundlei < bp->numspec ) + bp->speculative[bundlei] = bp->hashes[bundlei]; + if ( bp->blocks[bundlei] == 0 ) + bp->blocks[bundlei] = block; + else if ( bp->blocks[bundlei] != block ) + printf(">>>>>>>>>>>>>> bundlehash2.(%s) ht.(%d %d) block.%p there\n",bits256_str(str,hash2),bp->bundleheight,bundlei,bp->blocks[bundlei]); + otherbp = 0, otherbundlei = -2; if ( (otherbp= iguana_bundlefind(coin,&otherbp,&otherbundlei,hash2)) != 0 || (bundlei % (bundlesize-1)) == 0) { if ( bundlei == 0 && (otherbundlei == -2 || otherbundlei == bundlesize-1) ) @@ -260,30 +296,35 @@ int32_t iguana_bundlehash2add(struct iguana_info *coin,struct iguana_block **blo if ( err != 0 ) { printf("bundlehash2add err.%d\n",err); - while ( 1 ) - sleep(1); - exit(-1); + return(0); + //while ( 1 ) + // sleep(1); + //exit(-1); } return(-err); } struct iguana_bundle *iguana_bundlecreate(struct iguana_info *coin,int32_t *bundleip,int32_t bundleheight,bits256 bundlehash2,bits256 allhash,int32_t issueflag) { - char str[65]; struct iguana_bundle *bp = 0; + char str[65]; struct iguana_bundle *prevbp,*bp = 0; if ( bits256_nonz(bundlehash2) > 0 ) { bits256_str(str,bundlehash2); + bp = 0, *bundleip = -2; if ( iguana_bundlefind(coin,&bp,bundleip,bundlehash2) != 0 ) { if ( bp->bundleheight >= 0 && bp->bundleheight != (bundleheight - *bundleip) ) + { printf("bundlecreate warning: bp->bundleheight %d != %d (bundleheight %d - %d bundlei)\n",bp->bundleheight,(bundleheight - *bundleip),bundleheight,*bundleip); + return(0); + } else if ( bits256_nonz(bp->allhash) == 0 ) bp->allhash = allhash; return(bp); } bp = mycalloc('b',1,sizeof(*bp)); bp->n = coin->chain->bundlesize; - bp->hdrsi = coin->bundlescount; + bp->hdrsi = bundleheight / coin->chain->bundlesize; bp->bundleheight = bundleheight; bp->allhash = allhash; iguana_hash2set(coin,"create",bp,0,bundlehash2); @@ -291,20 +332,31 @@ struct iguana_bundle *iguana_bundlecreate(struct iguana_info *coin,int32_t *bund { bp->coin = coin; bp->avetime = coin->avetime * 2.; - coin->bundles[coin->bundlescount] = bp; - if ( coin->bundlescount > 0 ) - coin->bundles[coin->bundlescount-1]->nextbp = bp; + coin->bundles[bp->hdrsi] = bp; + if ( bp->hdrsi > 0 ) + { + if ( (prevbp= coin->bundles[bp->hdrsi-1]) != 0 ) + { + prevbp->nextbp = bp; + prevbp->nextbundlehash2 = bundlehash2; + } + } *bundleip = 0; bits256_str(str,bundlehash2); - fprintf(stderr,"{%d} ",bp->bundleheight); - //printf("ht.%d alloc.[%d] new hdrs.%s %s\n",bp->bundleheight,coin->bundlescount,str,bits256_str(str2,allhash)); + char dirname[1024]; int32_t subdir; + subdir = bp->bundleheight / IGUANA_SUBDIRDIVISOR; + sprintf(dirname,"%s/%s/%d",GLOBAL_TMPDIR,coin->symbol,subdir), OS_ensure_directory(dirname); + sprintf(dirname,"%s/%s/%d/%d",GLOBAL_TMPDIR,coin->symbol,subdir,bp->bundleheight), OS_ensure_directory(dirname); + //sprintf(dirname,"DB/%s/%d",coin->symbol,bp->bundleheight), OS_ensure_directory(dirname); + //printf("%s ht.%d alloc.[%d] new hdrs.%s\n",coin->symbol,bp->bundleheight,coin->bundlescount,bits256_str(str,bp->hashes[0])); iguana_bundlehash2add(coin,0,bp,0,bundlehash2); if ( issueflag != 0 ) { - iguana_blockQ(coin,bp,0,bundlehash2,1); + iguana_blockQ("bundlecreate",coin,bp,0,bundlehash2,1); queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(str),1); } - coin->bundlescount++; + if ( bp->hdrsi >= coin->bundlescount ) + coin->bundlescount = (bp->hdrsi + 1); } else { @@ -318,115 +370,942 @@ struct iguana_bundle *iguana_bundlecreate(struct iguana_info *coin,int32_t *bund return(0); } +int32_t iguana_bundlefname(struct iguana_info *coin,struct iguana_bundle *bp,char *fname) +{ + int32_t hdrsi; static bits256 zero; + iguana_peerfname(coin,&hdrsi,"DB",fname,0,bp->hashes[0],zero,bp->n,1); + if ( hdrsi == bp->hdrsi ) + return(0); + else + { + fname[0] = 0; + return(-1); + } +} + struct iguana_txid *iguana_bundletx(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei,struct iguana_txid *tx,int32_t txidind) { - static bits256 zero; - int32_t hdrsi; int64_t Toffset; char fname[1024]; FILE *fp; struct iguana_ramchaindata rdata; - iguana_peerfname(coin,&hdrsi,"DB",fname,0,bp->hashes[0],zero,bp->n); - if ( (fp= fopen(fname,"rb")) != 0 ) - { - fseek(fp,(long)&rdata.Toffset - (long)&rdata,SEEK_SET); - if ( fread(&Toffset,1,sizeof(Toffset),fp) == sizeof(Toffset) ) - { - fseek(fp,Toffset + sizeof(struct iguana_txid) * txidind,SEEK_SET); - if ( fread(tx,1,sizeof(*tx),fp) == sizeof(*tx) ) - { - fclose(fp); - return(tx); - } else printf("bundletx read error\n"); - } else printf("bundletx Toffset read error\n"); - fclose(fp); - } else printf("bundletx couldnt open.(%s)\n",fname); + static const bits256 zero; + int32_t hdrsi,iter; struct iguana_txid *T; int64_t Toffset; char fname[1024]; FILE *fp; struct iguana_ramchaindata rdata,*rptr; + if ( (rptr= bp->ramchain.H.data) != 0 ) + { + //T = (void *)(long)((long)rptr + (long)rptr->Toffset); + T = RAMCHAIN_PTR(rptr,Toffset); + *tx = T[txidind]; + return(tx); + } + printf("bundletx without ramchain\n"); + for (iter=0; iter<2; iter++) + { + iguana_peerfname(coin,&hdrsi,iter==0?"DB/ro":"DB",fname,0,bp->hashes[0],zero,bp->n,1); + if ( (fp= fopen(fname,"rb")) != 0 ) + { + fseek(fp,(long)&rdata.Toffset - (long)&rdata,SEEK_SET); + if ( fread(&Toffset,1,sizeof(Toffset),fp) == sizeof(Toffset) ) + { + fseek(fp,Toffset + sizeof(struct iguana_txid) * txidind,SEEK_SET); + if ( fread(tx,1,sizeof(*tx),fp) == sizeof(*tx) ) + { + fclose(fp); + return(tx); + } else printf("bundletx read error\n"); + } else printf("bundletx Toffset read error\n"); + fclose(fp); + } + } + printf("bundletx couldnt open.(%s)\n",fname); return(0); } -void iguana_bundlepurge(struct iguana_info *coin,struct iguana_bundle *bp) +char *iguana_bundleaddrs(struct iguana_info *coin,int32_t hdrsi) { - static bits256 zero; - char fname[1024]; int32_t hdrsi,m,j; uint32_t ipbits; - if ( bp->emitfinish > coin->startutc && bp->purgetime == 0 && time(NULL) > bp->emitfinish+30 ) + uint8_t *PKbits; struct iguana_pkhash *P; uint32_t pkind,numpkinds; struct iguana_bundle *bp; struct iguana_ramchain *ramchain; cJSON *retjson; char rmdstr[41]; + if ( (bp= coin->bundles[hdrsi]) != 0 ) { - for (j=m=0; jpeers.active)/sizeof(*coin->peers.active); j++) + if ( 0 && coin->RTramchain_busy != 0 ) { - if ( (ipbits= (uint32_t)coin->peers.active[j].ipbits) != 0 ) + printf("iguana_bundleaddrs: unexpected access when RTramchain_busy\n"); + return(0); + } + ramchain = &bp->ramchain;//(bp->isRT != 0) ? &bp->ramchain : &coin->RTramchain; + if ( ramchain->H.data != 0 ) + { + numpkinds = ramchain->H.data->numpkinds;//(bp->isRT != 0) ? ramchain->H.data->numpkinds : ramchain->pkind; + retjson = cJSON_CreateArray(); + PKbits = RAMCHAIN_PTR(ramchain->H.data,PKoffset); + P = RAMCHAIN_PTR(ramchain->H.data,Poffset); + //PKbits = (void *)(long)((long)ramchain->H.data + ramchain->H.data->PKoffset); + //P = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Poffset); + for (pkind=0; pkindrmd160,20); + jaddistr(retjson,rmdstr); + } + return(jprint(retjson,1)); + } + //iguana_bundleQ(coin,bp,bp->n); + return(clonestr("{\"error\":\"no bundle data\"}")); + } return(clonestr("{\"error\":\"no bundle\"}")); +} + +void iguana_bundlepurgefiles(struct iguana_info *coin,struct iguana_bundle *bp) +{ + static const bits256 zero; + char fname[1024]; FILE *fp; int32_t subdir,hdrsi,j,lasti,i,m = 0; uint32_t ipbits = 0; + if ( coin->current != 0 ) + lasti = coin->current->hdrsi; + else lasti = 0; + if ( bp->purgetime == 0 && time(NULL) > bp->emitfinish+600 && bp->hdrsi < lasti-2 ) + { + for (j=m=0; jn; j++) + { + if ( iguana_peerfname(coin,&hdrsi,GLOBAL_TMPDIR,fname,ipbits,bp->hashes[j],zero,1,1) >= 0 ) { - if ( iguana_peerfname(coin,&hdrsi,"tmp",fname,ipbits,bp->hashes[0],zero,1) >= 0 ) + if ( (fp= fopen(fname,"rb")) != 0 ) { + printf("purge.(%s)\n",fname); + fclose(fp); if ( OS_removefile(fname,0) > 0 ) coin->peers.numfiles--, m++; } - else printf("error removing.(%s)\n",fname); } + else printf("error removing.(%s)\n",fname); } - //printf("purged hdrsi.%d m.%d\n",bp->hdrsi,m); + subdir = bp->bundleheight / IGUANA_SUBDIRDIVISOR; + sprintf(fname,"%s/%s/%d/%d",GLOBAL_TMPDIR,coin->symbol,subdir,bp->bundleheight), OS_remove_directory(fname); + //printf("purged hdrsi.[%d] subdir.%d lag.%ld\n",bp->hdrsi,subdir,time(NULL) - bp->emitfinish); bp->purgetime = (uint32_t)time(NULL); + if ( 0 ) + { + for (i=subdir*IGUANA_SUBDIRDIVISOR; i<(subdir+1)*IGUANA_SUBDIRDIVISOR; i++) + { + if ( (bp= coin->bundles[i]) != 0 && time(NULL) < bp->emitfinish+10 ) + { + printf("subdir.%d [%d] emit not confirmed\n",subdir,i); + return; + } + } + printf("remove subdir.%d\n",subdir); + sprintf(fname,"%s/%s/%d",GLOBAL_TMPDIR,coin->symbol,subdir), OS_remove_directory(fname); + } + } +} + +uint8_t iguana_recentpeers(struct iguana_info *coin,int32_t *capacityp,struct iguana_peer *peers[]) +{ + struct iguana_peer *addr; uint8_t m; int32_t capacity,i,n = coin->peers.numranked; + for (i=m=capacity=0; ipeers.ranked[i]) != 0 && addr->dead == 0 && addr->usock >= 0 && addr->msgcounts.verack != 0 && addr->pendblocks < coin->MAXPENDINGREQUESTS ) + { + if ( peers != 0 ) + peers[m] = addr; + m++; + capacity += (coin->MAXPENDINGREQUESTS - addr->pendblocks); + } + } + *capacityp = capacity; + return(m); +} + +struct iguana_block *iguana_bundleblock(struct iguana_info *coin,bits256 *hash2p,struct iguana_bundle *bp,int32_t i) +{ + struct iguana_bundle *nextbp; struct iguana_block *block = 0; + memset(hash2p,0,sizeof(*hash2p)); + if ( bp == 0 ) + return(0); + if ( i == bp->n ) + { + if ( bits256_nonz(bp->nextbundlehash2) != 0 ) + { + if ( bp->hdrsi < coin->bundlescount && (nextbp= coin->bundles[bp->hdrsi+1]) != 0 ) + { + *hash2p = nextbp->hashes[0]; + return(nextbp->blocks[0]); + } + } else return(0); + } + if ( block != 0 || (block= bp->blocks[i]) != 0 )//|| bits256_nonz(bp->hashes[i]) != 0 )//&& (block= iguana_blockfind("bundleblock2",coin,bp->hashes[i])) != 0) ) + { + *hash2p = block->RO.hash2; + return(block); + } + else if ( bp->speculative != 0 && bits256_nonz(bp->speculative[i]) != 0 ) + { + *hash2p = bp->speculative[i]; + block = bp->blocks[i];//iguana_blockfind("speculative",coin,bp->speculative[i]); + //char str[65]; printf("[%d:%d] %s\n",bp->hdrsi,i,bits256_str(str,*hash2p)); + } + return(block); +} + +/*int32_t iguana_sendhashes(struct iguana_info *coin,struct iguana_peer *addr,int32_t msgtype,bits256 hashes[],int32_t n,int32_t priority) +{ + int32_t len; uint8_t *serialized; + if ( addr->usock >= 0 && addr->dead == 0 && priority > 1 ) + { + serialized = malloc((sizeof(int32_t) + sizeof(*hashes))*n + 1024); + if ( (len= iguana_getdata(coin,serialized,MSG_BLOCK,hashes,n)) > 0 ) + { + if ( len > (sizeof(int32_t) + sizeof(*hashes))*n + 1024 ) + { + printf("FATAL ERROR iguana_sendhashes: len.%d size.%ld\n",len,(sizeof(int32_t) + sizeof(*hashes))*n + 1024); + exit(-1); + } + iguana_send(coin,addr,serialized,len); + coin->numreqsent += n; + addr->pendblocks += n; + addr->pendtime = (uint32_t)time(NULL); + printf("sendhashes[%d] -> %s\n",n,addr->ipaddr); + } else n = 0; + free(serialized); + } + else + { + int32_t i; + for (i=0; icurrent == 0 ? 0 : coin->current->hdrsi; + lasti = coin->lastpending == 0 ? starti+coin->MAXBUNDLES : coin->lastpending->hdrsi; + if ( bp->hdrsi < starti || bp->hdrsi > lasti || bp->emitfinish != 0 || ((priority > 0 || bp == coin->current) && time(NULL) < bp->missingstime+3) || time(NULL) < bp->missingstime+30 ) + return(0); + bp->missingstime = (uint32_t)time(NULL); + if ( bp->durationscount != 0 ) + { + aveduration = (double)bp->totaldurations / bp->durationscount; + if ( (rand() % 10000) == 0 ) + printf("priority.%d [%d] durations %.2f counts[%d %d] \n",priority,bp->hdrsi,aveduration,(int32_t)bp->durationscount,bp->duplicatescount); + } else aveduration = IGUANA_DEFAULTLAG; + lag = aveduration * mult; + if ( coin->PREFETCHLAG < 0 ) + { + if ( bp != coin->current && lag < 60 ) + lag = 60; + else if ( lag < 30 ) + lag = 30; + } + else if ( lag < 120 && coin->enableCACHE == 0 ) + { + if ( bp != coin->current ) + lag = 120; + else if ( lag < 60 ) + lag = 60; + } + if ( (num= coin->peers.numranked) != 0 ) + { + if ( num > 64 ) + max = log2(num * num) + 1; + else max = num; + if ( max < IGUANA_MINPEERS ) + max = IGUANA_MINPEERS; + if ( max > num ) + max = num; + now = (uint32_t)time(NULL); + lasti = firsti = -1; + for (i=nonz=0; in; i++) + { + if ( GETBIT(bp->haveblock,i) != 0 ) + continue; + nonz++; + if ( firsti < 0 ) + firsti = i; + lasti = i; + if ( priority > 2 || bp->numsaved > bp->n-10 || ((bp->issued[i] == 0 || bp->issued[i] > 1) && now > bp->issued[i]+lag) ) + { + iguana_bundleblock(coin,&hash2,bp,i); + if ( bits256_nonz(hash2) != 0 ) + { + if ( (addr= coin->peers.ranked[rand() % max]) != 0 && addr->usock >= 0 && addr->dead == 0 ) + { + struct iguana_blockreq *req = 0; + //if ( bp == coin->current ) + // printf("iguana_bundleissuemissing.[%d:%d]\n",bp->hdrsi,i); + if ( priority > 2 || bp->numsaved > bp->n-10 ) + iguana_sendblockreqPT(coin,addr,bp,i,hash2,0); + else + { + req = mycalloc('y',1,sizeof(*req)); + req->hash2 = hash2; + req->bp = bp; + req->height = bp->bundleheight + i; + req->bundlei = i; + queue_enqueue("missing",&coin->priorityQ,&req->DL,0); + } + bp->issued[i] = 1; + n++; + } + } + } + } + if ( priority <= 2 && firsti >= 0 && bp->issued[firsti] != 1 && (strcmp("BTC",coin->symbol) != 0 || bp == coin->current) ) + { + //printf("[%d] first missing.%d of %d\n",bp->hdrsi,firsti,nonz); + iguana_bundleblock(coin,&hash2,bp,firsti); + if ( bits256_nonz(hash2) != 0 ) + { + if ( (addr= coin->peers.ranked[rand() % max]) != 0 && addr->usock >= 0 && addr->dead == 0 ) + { + //if ( bp == coin->current ) + // printf("iguana_bundleissuemissing.[%d:%d]\n",bp->hdrsi,i); + n++; + iguana_sendblockreqPT(coin,addr,bp,firsti,hash2,0); + } + } + } + } + //if ( n > 0 || bp == coin->current ) + // printf("issue.[%d] %d priority.%d\n",bp->hdrsi,n,priority); + return(n); +} + +int32_t iguana_blast(struct iguana_info *coin,struct iguana_peer *addr) +{ + struct iguana_bundle *bp,*lastbp; double aveduration; bits256 hash2; uint32_t now; int32_t i,m,ind,range,n = 0; struct iguana_blockreq *req = 0; + m = 0; + if ( (bp= coin->current) != 0 && (lastbp= coin->lastpending) != 0 && (range= (lastbp->hdrsi - bp->hdrsi + 1)) > 0 ) + { + ind = bp->hdrsi + (addr->addrind % range); + while ( ind < coin->bundlescount && n < IGUANA_PENDINGREQUESTS ) + { + now = (uint32_t)time(NULL); + if ( (bp= coin->bundles[ind++]) != 0 ) + { + if ( bp == coin->current ) + aveduration = 1; + else + { + if ( bp->durationscount != 0 ) + aveduration = (double)bp->totaldurations / bp->durationscount; + else aveduration = IGUANA_DEFAULTLAG; + } + for (i=0; in && nhaveblock,i) == 0 && now > bp->issued[i]+aveduration ) + { + iguana_bundleblock(coin,&hash2,bp,i); + if ( bits256_nonz(hash2) != 0 ) + { + n++; + bp->issued[i] = 0; + req = mycalloc('y',1,sizeof(*req)); + req->hash2 = hash2; + req->bp = bp; + req->height = bp->bundleheight + i; + req->bundlei = i; + queue_enqueue("blast",&coin->priorityQ,&req->DL,0); + } + } + if ( n > m ) + { + //printf("%s blasted.%d -> [%d]\n",addr->ipaddr,n-m,bp->hdrsi); + m = n; + } + } + } + } + return(n); +} + +int32_t iguana_bundleready(struct iguana_info *coin,struct iguana_bundle *bp,int32_t requiredflag) +{ + static bits256 zero; + int32_t i,ready,valid; char fname[1024]; struct iguana_block *block; int32_t sum[0x100],counts[0x100]; struct iguana_blockRO *B; struct iguana_bundle *nextbp; void *ptr; long filesize; struct iguana_ramchain R; bits256 prevhash2; + memset(sum,0,sizeof(sum)); + memset(counts,0,sizeof(counts)); + if ( 0 && bp->queued == 0 ) + { + for (i=ready=0; in; i++) + if ( (block= bp->blocks[i]) == 0 ) + break; + if ( i < bp->n ) + { + if ( (nextbp= coin->bundles[bp->hdrsi+1]) != 0 && (block= nextbp->blocks[0]) != 0 ) + { + prevhash2 = block->RO.prev_block; + for (i=bp->n-1; i>=0; i--) + { + char str[65]; printf("[%d:%d] %s\n",bp->hdrsi,i,bits256_str(str,prevhash2)); + if ( bp->blocks[i] == 0 && bits256_nonz(prevhash2) != 0 ) + { + bp->hashes[i] = prevhash2; + bp->blocks[i] = iguana_blockhashset("ready",coin,bp->bundleheight+i,prevhash2,1); + iguana_hash2set(coin,"ready",bp,i,prevhash2); + prevhash2 = zero; + if ( (ptr= iguana_bundlefile(coin,fname,&filesize,bp,i)) != 0 ) + { + if ( iguana_mapchaininit(fname,coin,&R,bp,i,block,ptr,filesize) >= 0 ) + { + B = RAMCHAIN_PTR(R.H.data,Boffset); + //B = (void *)(long)((long)R.H.data + R.H.data->Boffset); + prevhash2 = B[0].prev_block; + } + munmap(ptr,filesize); + } + } + if ( bits256_nonz(prevhash2) == 0 ) + break; + } + printf("reverse linked to [%d:%d]\n",bp->hdrsi,i); + } + } + } + for (i=ready=0; in; i++) + { + if ( (block= bp->blocks[i]) != 0 ) + { + if ( block->lag != 0 && block->peerid != 0 ) + { + sum[block->peerid] += block->lag; + counts[block->peerid]++; + } + //printf("(%x:%x) ",(uint32_t)block->RO.hash2.ulongs[3],(uint32_t)bp->hashes[i].ulongs[3]); + if ( block->txvalid == 0 || block->fpipbits == 0 || block->fpos < 0 || (bp->bundleheight+i > 0 && bits256_nonz(block->RO.prev_block) == 0) || iguana_blockvalidate(coin,&valid,block,1) < 0 ) + { + if ( requiredflag != 0 ) + printf(">>>>>>> block contents error at ht.%d [%d:%d]\n",bp->bundleheight+i,bp->hdrsi,i); + //char str[65]; patch.(%s) and reissue %s checki.%d vs %d\n",block->fpipbits,bp->bundleheight+i,bits256_str(str,block->RO.prev_block),fname,checki,i); + iguana_blockunmark(coin,block,bp,i,1); + } + else + { +//#ifndef __PNACL__ + int32_t checki,hdrsi; FILE *fp; + fname[0] = 0; + checki = iguana_peerfname(coin,&hdrsi,GLOBAL_TMPDIR,fname,0,block->RO.hash2,zero,1,0); + if ( hdrsi == bp->hdrsi && checki == i && (fp= fopen(fname,"rb")) != 0 ) + { + fseek(fp,0,SEEK_END); + if ( ftell(fp) > sizeof(struct iguana_ramchaindata) ) + { + //printf("[%d:%d] %s %ld\n",bp->hdrsi,i,fname,ftell(fp)); + ready++; + } + fclose(fp); + } + else +//#endif + { + iguana_blockunmark(coin,block,bp,i,1); + if ( 0 && requiredflag != 0 ) + printf("not ready altpath.(%d %d %d %d %d) [%d:%d]\n",block->txvalid == 0,block->fpipbits == 0 ,block->fpos < 0,(bp->bundleheight+i > 0 && bits256_nonz(block->RO.prev_block) == 0),iguana_blockvalidate(coin,&valid,block,1) < 0,bp->hdrsi,i); + } + } + } + else + { + if ( requiredflag != 0 ) + printf("no block at [%d:%d]\n",bp->hdrsi,i); + iguana_blockunmark(coin,block,bp,i,0); + if ( bp->queued != 0 ) + { + printf("error getting block (%d:%d) %p\n",bp->hdrsi,i,block); + return(-1); + } + } + } + return(ready); +} + +int32_t iguana_bundlehdr(struct iguana_info *coin,struct iguana_bundle *bp,int32_t starti) +{ + int32_t i,dist,counter=0; char str[64]; + if ( 0 && bp->isRT == 0 && (bp->hdrsi == coin->bundlescount-1 || bp == coin->current) ) + printf("hdr ITERATE.%d bundle.%d vs %d: h.%d n.%d r.%d s.%d c.%d finished.%d spec.%p[%d]\n",bp->hdrsi,bp->bundleheight,coin->longestchain-coin->chain->bundlesize,bp->numhashes,bp->n,bp->numrecv,bp->numsaved,bp->numcached,bp->emitfinish,bp->speculative,bp->numspec); + dist = 30 + (coin->current != 0 ? bp->hdrsi - coin->current->hdrsi : 0); + if ( bp == coin->current ) + dist = 3; + if ( time(NULL) > bp->hdrtime+dist && (bp == coin->current || bp->hdrsi >= coin->bundlescount-2 || (strcmp("BTC",coin->symbol) != 0 && bp->numhashes < bp->n && (bp->speculative == 0 || bp->hdrsi >= coin->longestchain/bp->n))) ) + { + bp->hdrtime = (uint32_t)time(NULL); + queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); + } + if ( strcmp("BTC",coin->symbol) != 0 && (bp == coin->current || bp->hdrsi == coin->bundlescount-1) && bits256_nonz(bp->nextbundlehash2) == 0 ) + { + if ( bp->numhashes < bp->n && bp->numcached < bp->n ) + { + //printf("issue current hdr.[%d]\n",bp->hdrsi); + for (i=0; in; i++) + if ( GETBIT(bp->haveblock,i) == 0 ) + bp->issued[i] = 0; + //queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); + } + iguana_bundleissuemissing(coin,bp,3,1.); + /*if ( bp == coin->current ) + { + mult = 1.; + printf("iguana_bundlehdr.[%d] %d %s\n",bp->hdrsi,bp->numspec,bits256_str(str,bp->hashes[0])); + }*/ + } + return(counter); +} + +int32_t iguana_setmaxbundles(struct iguana_info *coin) +{ + double completed; + if ( coin->current != 0 && coin->bundlescount != 0 ) + { + completed = sqrt(((double)coin->current->hdrsi + 1) / coin->bundlescount); + coin->MAXBUNDLES = (double)(coin->endPEND - coin->startPEND)*completed + coin->startPEND; + //printf("MAXBUNDLES %d (%d -> %d) completed %.3f\n",coin->MAXBUNDLES,coin->startPEND,coin->endPEND,completed); + } + return(coin->MAXBUNDLES); +} + +int32_t iguana_bundletweak(struct iguana_info *coin,struct iguana_bundle *bp) +{ + struct iguana_bundle *lastbp; int32_t i,pending; + if ( coin->current == bp ) + coin->current = coin->bundles[bp->hdrsi+1]; + if ( (lastbp= coin->current) != 0 ) + { + for (pending=0,i=lastbp->hdrsi+1; ibundlescount; i++) + { + if ( (lastbp= coin->bundles[i]) != 0 && lastbp->emitfinish == 0 ) + { + if ( ++pending == coin->MAXBUNDLES ) + break; + } + } + coin->lastpending = lastbp; } + iguana_setmaxbundles(coin); + return(coin->MAXBUNDLES); } -int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) +int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp,int32_t lag) { - int32_t bundlei; struct iguana_block *block; - if ( bp->emitfinish > coin->startutc ) + int32_t bundlei,numhashes,numsaved,numrecv,numcached,minrequests; int64_t datasize; struct iguana_block *block; + if ( bp->emitfinish > 0 && (bp->ramchain.H.data != 0 || iguana_bundleready(coin,bp,0) == bp->n) ) { + memset(bp->haveblock,0xff,sizeof(bp->haveblock)); bp->numhashes = bp->numsaved = bp->numcached = bp->numrecv = bp->n; return(bp->datasize); } - bp->datasize = bp->numhashes = bp->numsaved = bp->numcached = bp->numrecv = bp->minrequests = 0; + memset(bp->haveblock,0,sizeof(bp->haveblock)); + datasize = numhashes = numsaved = numrecv = numcached = minrequests = 0; for (bundlei=0; bundlein; bundlei++) { if ( bits256_nonz(bp->hashes[bundlei]) > 0 ) { - if ( (block= bp->blocks[bundlei]) != 0 || (block= iguana_blockfind(coin,bp->hashes[bundlei])) != 0 ) + numhashes++; + if ( bp->speculativecache[bundlei] != 0 ) + numcached++; + if ( (block= bp->blocks[bundlei]) != 0 ) { - bp->blocks[bundlei] = block; - if ( bp->minrequests == 0 || (block->numrequests > 0 && block->numrequests < bp->minrequests) ) - bp->minrequests = block->numrequests; - if ( block->fpipbits != 0 ) - bp->numsaved++; - if ( block->RO.recvlen != 0 ) + if ( bits256_cmp(block->RO.hash2,bp->hashes[bundlei]) == 0 ) { - bp->numrecv++; - bp->datasize += block->RO.recvlen; - if ( block->queued != 0 ) - bp->numcached++; - } - } - bp->numhashes++; + //if ( bp->minrequests == 0 || (block->numrequests > 0 && block->numrequests < bp->minrequests) ) + // bp->minrequests = block->numrequests; + if ( block->fpipbits != 0 && block->txvalid != 0 && block->fpos >= 0 && (bp->bundleheight+bundlei == 0 || bits256_nonz(block->RO.prev_block) != 0) ) + { + SETBIT(bp->haveblock,bundlei); + numsaved++; + } + if ( block->RO.recvlen != 0 ) + { + numrecv++; + datasize += block->RO.recvlen; + } + } else printf("hash mismatch [%d:%d]\n",bp->hdrsi,bundlei); + } //else printf("[null %d:%d] ",bp->hdrsi,bundlei); } } - bp->metric = bp->numhashes; + bp->numcached = numcached; + if ( 0 && bp->numcached != numsaved ) + printf("[%d] emit.%u ramchain.%p numcached.%d vs numsaved.%d numhashes.%d\n",bp->hdrsi,bp->emitfinish,bp->ramchain.H.data,bp->numcached,numsaved,numhashes); + bp->datasize = datasize; + bp->numhashes = numhashes; + bp->numsaved = numsaved; + bp->numrecv = numrecv; + bp->minrequests = minrequests; + bp->estsize = ((int64_t)bp->datasize * bp->n) / (bp->numrecv+1); return(bp->estsize); } -void iguana_bundlestats(struct iguana_info *coin,char *str) +/*int32_t iguana_bundlefinish(struct iguana_info *coin,struct iguana_bundle *bp) + { + struct iguana_bundle *prevbp; int32_t i; + #ifdef IGUANA_SERIALIZE_SPENDVECTORGEN + if ( ((prevbp= coin->current) != 0 && prevbp->hdrsi < (coin->longestchain / coin->chain->bundlesize)) || coin->numemit < prevbp->hdrsi ) + return(0); + #endif + for (i=0; ihdrsi; i++) + if ( (prevbp= coin->bundles[i]) == 0 || prevbp->emitfinish <= 1 || (prevbp->utxofinish == 0 && prevbp->tmpspends == 0) ) + break; + if ( bp->hdrsi < coin->blocks.hwmchain.height/coin->chain->bundlesize && i >= bp->hdrsi-(IGUANA_NUMHELPERS>>1) && time(NULL) > bp->emitfinish+3 ) + { + //printf("[%d] vs %d i.%d vs %d emitted.%ld (%d %d %d) s.%u f.%u\n",bp->hdrsi,coin->blocks.hwmchain.height/coin->chain->bundlesize,i,bp->hdrsi-IGUANA_NUMHELPERS/2,time(NULL) - bp->emitfinish,bp->hdrsi < coin->blocks.hwmchain.height/coin->chain->bundlesize,i >= bp->hdrsi-IGUANA_NUMHELPERS, time(NULL) > bp->emitfinish,bp->startutxo,bp->utxofinish); + if ( bp->startutxo == 0 ) + { + bp->startutxo = (uint32_t)time(NULL); + //printf("spendvectorsQ.%d\n",bp->hdrsi); + iguana_spendvectorsQ(coin,bp); + } + else if ( bp->utxofinish != 0 ) + { + if ( bp->balancefinish == 0 ) + iguana_balancesQ(coin,bp); + } + return(1); + } + //else printf("%u notready.%d postfinish.%d startutxo.%u prevbp.%d %u current.%d\n",(uint32_t)time(NULL),bp->hdrsi,i,bp->startutxo,prevbp!=0?prevbp->hdrsi:-1,prevbp!=0?prevbp->emitfinish:0,coin->current!=0?coin->current->hdrsi:-1); + return(0); +}*/ + +int32_t iguana_bundlefinalize(struct iguana_info *coin,struct iguana_bundle *bp,struct OS_memspace *mem,struct OS_memspace *memB) +{ + int32_t i; struct iguana_bundle *tmpbp; + if ( iguana_bundleready(coin,bp,0) == bp->n ) + { + printf(">>>>>>>>>>>>>> EMIT.[%3d] %s | 1st.%-3d h.%-3d c.%-3d s.[%3d] maxB.%d NET.(h%d b%d) %ld:%02ld\n",bp->hdrsi,coin->symbol,coin->current!=0?coin->current->hdrsi:-1,coin->current!=0?coin->current->numhashes:-1,coin->current!=0?coin->current->numcached:-1,coin->current!=0?coin->current->numsaved:-1,coin->MAXBUNDLES,HDRnet,netBLOCKS,(time(NULL)-coin->startutc)/60,(time(NULL)-coin->startutc)%60); + if ( bp->emitfinish != 0 ) + { + printf("already EMIT for bundle.%d\n",bp->hdrsi); + return(0); + } + bp->emitfinish = 1; + sleep(1); // make sure new incoming packet didnt overwrite + if ( iguana_bundleready(coin,bp,1) == bp->n ) + { + sleep(1); // make sure new incoming packet didnt overwrite + coin->emitbusy++; + if ( iguana_bundlesaveHT(coin,mem,memB,bp,(uint32_t)time(NULL)) == 0 ) + { + //fprintf(stderr,"emitQ done coin.%p bp.[%d] ht.%d\n",coin,bp->hdrsi,bp->bundleheight); + bp->emitfinish = (uint32_t)time(NULL) + 1; + iguana_bundletweak(coin,bp); + coin->numemitted++; + for (i=0; in; i++) + iguana_hash2set(coin,"bundlefinalize",bp,i,bp->hashes[i]); + /*if ( bp->hdrsi == 0 && iguana_peerblockrequest(coin,coin->blockspace,sizeof(coin->blockspace),0,bp->hashes[0],1) > 0 ) + printf("GENESIS block validated\n"); + else printf("GENESIS didnt validate bp.%p\n",bp);*/ + //if ( strcmp("BTC",coin->symbol) != 0 ) + coin->spendvectorsaved = 0; + for (i=bp->hdrsi; ibundlescount; i++) + if ( (tmpbp= coin->bundles[i]) != 0 ) + tmpbp->converted = tmpbp->balancefinish = tmpbp->validated = 0; +#ifdef __PNACL__ + iguana_bundlevalidate(coin,bp,1); +#endif + } + else + { + //fprintf(stderr,"emitQ done coin.%p bp.[%d] ht.%d error\n",coin,bp->hdrsi,bp->bundleheight); + bp->emitfinish = 0; + } + coin->emitbusy--; + } + else + { + bp->emitfinish = 0; + printf("interloper! [%d] save interupted, will retry next iteration\n",bp->hdrsi); + } + return(1); + } + else + { + //printf("bundlefinalize.[%d] not ready\n",bp->hdrsi); + //iguana_bundleremove(coin,bp->hdrsi,1); + } + return(0); +} + +int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_bundle *bp,int32_t timelimit,int32_t lag) +{ + int32_t range,starti,lasti,retval=0,max,counter = 0; struct iguana_bundle *currentbp,*lastbp; + if ( coin->started == 0 || coin->active == 0 ) + { + printf("%s not ready yet\n",coin->symbol); + bp->nexttime = (uint32_t)time(NULL) + 3; + iguana_bundleQ(coin,bp,1000); + return(retval); + } + if ( coin->current == 0 ) + coin->current = coin->bundles[0]; + range = coin->MAXBUNDLES; + currentbp = coin->current; + lastbp = coin->lastpending; + starti = currentbp == 0 ? 0 : currentbp->hdrsi; + lasti = lastbp == 0 ? coin->bundlescount-1 : lastbp->hdrsi; + iguana_bundlecalcs(coin,bp,lag); + if ( bp->hdrsi == coin->bundlescount-1 ) + iguana_autoextend(coin,bp); + if ( 0 && bp->hdrsi == 0 ) + printf("ITER utxo.%u now.%u spec.%-4d bundle.%-4d h.%-4d r.%-4d s.%-4d F.%d T.%d issued.%d mb.%d/%d\n",bp->utxofinish,(uint32_t)time(NULL),bp->numspec,bp->bundleheight/coin->chain->bundlesize,bp->numhashes,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit,counter,coin->MAXBUNDLES,coin->bundlescount); + bp->nexttime = (uint32_t)time(NULL) + ((bp->hdrsi > starti) ? cbrt(bp->hdrsi - starti)/10 : 0); + if ( bp->hdrsi == coin->bundlescount-1 || (bp->numhashes < bp->n && bp->bundleheight < coin->longestchain-coin->chain->bundlesize) ) + iguana_bundlehdr(coin,bp,starti); + else if ( bp->emitfinish == 0 && bp->numsaved >= bp->n ) + { + if ( iguana_bundlefinalize(coin,bp,mem,memB) > 0 ) + return(0); + //else printf("bundlefinalize not done.[%d]\n",bp->hdrsi); + retval = 1; + } + else if ( bp->hdrsi == starti || (bp->hdrsi >= starti && bp->hdrsi <= starti+range) ) + { + max = bp->n; + counter = iguana_bundleissuemissing(coin,bp,1,3.); + if ( 0 && counter > 0 ) + printf("ITER.rt%d now.%u spec.%-4d bundle.%-4d h.%-4d r.%-4d s.%-4d F.%d T.%d issued.%d mb.%d/%d\n",bp->isRT,(uint32_t)time(NULL),bp->numspec,bp->bundleheight/coin->chain->bundlesize,bp->numhashes,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit,counter,coin->MAXBUNDLES,coin->bundlescount); + } else bp->nexttime += 3; + if ( bp->emitfinish <= 1 ) + iguana_bundleQ(coin,bp,1000); + else bp->queued = 0; + return(retval); +} + +/*static int _decreasing_double(const void *a,const void *b) +{ +#define double_a (*(double *)a) +#define double_b (*(double *)b) + if ( double_b > double_a ) + return(1); + else if ( double_b < double_a ) + return(-1); + return(0); +#undef double_a +#undef double_b +} + +static int32_t revsortds(double *buf,uint32_t num,int32_t size) +{ + qsort(buf,num,size,_decreasing_double); + return(0); +}*/ + +int32_t iguana_cacheprocess(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei) +{ + int32_t recvlen; struct iguana_msghdr H; uint8_t *data; struct iguana_block *block; + if ( (data= bp->speculativecache[bundlei]) != 0 && bp->speculative != 0 && (block= iguana_blockfind("cacheprocess",coin,bp->speculative[bundlei])) != 0 && block->processed == 0 ) + { + block->processed = 1; + bp->speculativecache[bundlei] = 0; + iguana_bundlehash2add(coin,0,bp,bundlei,block->RO.hash2); + recvlen = *(int32_t *)data; + //char str[65]; printf("iguana_cacheprocess [%d:%d] %s fp.%x len.%d:%d\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei]),block->fpipbits,block->RO.recvlen,recvlen); + memset(&H,0,sizeof(H)); + if ( iguana_sethdr(&H,coin->chain->netmagic,"block",&data[sizeof(recvlen)],recvlen) > 0 ) + { + if ( coin->internaladdr.RAWMEM.ptr == 0 ) + iguana_meminit(&coin->internaladdr.RAWMEM,"cache",0,IGUANA_MAXPACKETSIZE + 65536*3,0); + if ( coin->TXMEM.ptr == 0 ) + iguana_meminit(&coin->internaladdr.TXDATA,"txdata",0,IGUANA_MAXPACKETSIZE*1.5,0); + if ( coin->internaladdr.HASHMEM.ptr == 0 ) + iguana_meminit(&coin->internaladdr.HASHMEM,"HASHPTRS",0,256,0); + if ( iguana_msgparser(coin,&coin->internaladdr,&coin->internaladdr.RAWMEM,&coin->internaladdr.TXDATA,&coin->internaladdr.HASHMEM,&H,&data[sizeof(recvlen)],recvlen) < 0 ) + printf("error parsing speculativecache.[%d:%d]\n",bp->hdrsi,bundlei); + } + free(data); + return(recvlen); + } + return(-1); +} + +void iguana_unstickhdr(struct iguana_info *coin,struct iguana_bundle *bp,int32_t lag) +{ + int32_t datalen,m,i; uint8_t serialized[512]; char str[65]; struct iguana_peer *addr; + if ( (m= coin->peers.numranked) > 0 && bp->numhashes < bp->n && bp->hdrsi < coin->longestchain/coin->chain->bundlesize && time(NULL) > bp->unsticktime+lag ) + { + for (i=0; i<10; i++) + if ( (addr= coin->peers.ranked[rand() % m]) != 0 && addr->usock >= 0 && addr->dead == 0 && (datalen= iguana_gethdrs(coin,serialized,coin->chain->gethdrsmsg,bits256_str(str,bp->hashes[0]))) > 0 ) + { + //printf("UNSTICK HDR.[%d]\n",bp->hdrsi); + iguana_send(coin,addr,serialized,datalen); + addr->pendhdrs++; + bp->unsticktime = (uint32_t)time(NULL); + break; + } + } +} + +void iguana_bundlemissings(struct iguana_info *coin,struct iguana_bundle *bp,uint32_t now) +{ + int32_t mult = 7,n=0,priority = 1; + if ( now > bp->missingstime+10 ) + { + if ( coin->current != 0 ) + mult = bp->hdrsi - coin->current->hdrsi; + else if ( strcmp("BTC",coin->symbol) != 0 ) + mult = 1; + else mult = 3; + if ( mult < 4 ) + mult = 4; + else if ( mult > 7 ) + mult = 7; + if ( coin->bandwidth < .7*coin->maxbandwidth ) + { + mult--; + if ( coin->bandwidth < .6*coin->maxbandwidth ) + { + if ( coin->bandwidth < .5*coin->maxbandwidth ) + { + mult--; + if ( coin->bandwidth < .4*coin->maxbandwidth ) + { + mult--; + if ( coin->bandwidth < .3*coin->maxbandwidth ) + { + mult--; + if ( coin->bandwidth < 0.25*coin->maxbandwidth ) + priority = 3; + } + } + } + } + if ( mult < 1 ) + mult = 1; + } + if ( (n= iguana_bundleissuemissing(coin,bp,priority,mult)) > 0 ) + { + //printf("bundle.[%d] n.%d issued.%d lag.%d\n",bp->hdrsi,n,bp->numissued,now-bp->missingstime); + bp->numissued += n; + bp->missingstime = (uint32_t)time(NULL); + } + } +} + +void iguana_bundlestats(struct iguana_info *coin,char *str,int32_t lag) { - static uint32_t lastdisp; - int32_t i,n,dispflag,numrecv,done,numhashes,numcached,numsaved,numemit; int64_t estsize = 0; - struct iguana_bundle *bp,*firstgap = 0; - dispflag = (rand() % 1000) == 0; - numrecv = numhashes = numcached = numsaved = numemit = done = 0; - for (i=n=0; ibundlescount; i++) + int32_t i,n,m,j,numv,numconverted,count,starti,lasti,pending,capacity,displag,numutxo,numbalances,numrecv,done,numhashes,numcached,numsaved,numemit; struct iguana_block *block; bits256 hash2; + int64_t spaceused=0,estsize = 0; struct iguana_bundle *currentbp,*lastbp,*bp,*lastpending = 0,*firstgap = 0; uint32_t now; + now = (uint32_t)time(NULL); + displag = (now - coin->lastdisp); + numrecv = numhashes = numcached = numconverted = numsaved = numemit = done = numutxo = numbalances = 0; + count = coin->bundlescount; + currentbp = coin->current; + lastbp = coin->lastpending; + starti = currentbp == 0 ? 0 : currentbp->hdrsi; + lasti = lastbp == 0 ? coin->bundlescount-1 : lastbp->hdrsi; + iguana_recentpeers(coin,&capacity,0); + //sortbuf = calloc(count,sizeof(*sortbuf)*2); + for (i=n=m=numv=pending=0; ibundles[i]) != 0 ) { - estsize += iguana_bundlecalcs(coin,bp); + if ( bp->converted != 0 ) + numconverted++; + if ( bp == coin->current && coin->blocks.hwmchain.height >= bp->bundleheight && coin->blocks.hwmchain.height < bp->bundleheight+bp->n ) + { + for (j=coin->blocks.hwmchain.height-bp->bundleheight+1; j<=bp->n; j++) + { + if ( (block= iguana_bundleblock(coin,&hash2,bp,j)) == 0 && bits256_nonz(hash2) != 0 ) + block = iguana_blockfind("bundlestats",coin,hash2); + if ( block == 0 || bits256_nonz(block->RO.prev_block) == 0 || _iguana_chainlink(coin,block) == 0 ) + break; + } + } + if ( bp->emitfinish > 1 ) + { + for (j=0; jn; j++) + { + if ( bp->blocks[j] == 0 && bits256_nonz(bp->hashes[j]) != 0 ) + bp->blocks[j] = iguana_blockfind("bundlestats2",coin,bp->hashes[j]); + } + } + else + { + if ( bp->hdrsi >= starti && bp->hdrsi < lasti ) + iguana_bundlemissings(coin,bp,now); + if ( coin->enableCACHE != 0 ) + { + for (j=0; jn; j++) + { + if ( ((block= bp->blocks[j]) == 0 || bp == coin->current) && bp->speculativecache[j] != 0 ) + { + if ( (block != 0 || (block= iguana_blockhashset("bundlestats3",coin,-1,bp->speculative[j],1)) != 0) && block->processed == 0 ) + iguana_cacheprocess(coin,bp,j); + numcached++; + } + } + } + } + bp->metric = coin->bundlescount - bp->hdrsi; + if ( done > coin->bundlescount*IGUANA_HEADPERCENTAGE && bp->hdrsi > coin->bundlescount*IGUANA_TAILPERCENTAGE ) + bp->metric *= 1000; + iguana_bundlecalcs(coin,bp,lag); + estsize += bp->estsize; numhashes += bp->numhashes; numcached += bp->numcached; numrecv += bp->numrecv; numsaved += bp->numsaved; - if ( bp->emitfinish != 0 ) + if ( bp->utxofinish > 1 ) + numutxo++; + if ( bp->balancefinish > 1 ) + numbalances++; + if ( bp->validated > 1 ) + numv++; + if ( bp->emitfinish >= 1 ) { - done++; - if ( bp->emitfinish > 1 ) + if ( bp->emitfinish == 1 ) + done++; + else + { numemit++; - iguana_bundlepurge(coin,bp); - } else if ( firstgap == 0 ) - firstgap = bp; + //printf("finished.[%d]\n",bp->hdrsi); + iguana_bundlepurgefiles(coin,bp); + } + } + else + { + if ( firstgap == 0 && bp->numsaved < bp->n && bp->numcached < bp->n && (bp->ramchain.H.data == 0 || bp->hdrsi == coin->longestchain/coin->chain->bundlesize || iguana_bundleready(coin,bp,bp->numsaved == bp->n) != bp->n) ) + { + //printf("firstgap <- [%d] emit.%u bp->n.%d numsaved.%d numcached.%d numhashes.%d\n",bp->hdrsi,bp->emitfinish,bp->n,bp->numsaved,bp->numcached,bp->numhashes); + firstgap = bp; + if ( bp->queued == 0 ) + iguana_bundleQ(coin,bp,1000); + } + //else printf("[%d] emit.%u bp->n.%d numsaved.%d numcached.%d numhashes.%d\n",bp->hdrsi,bp->emitfinish,bp->n,bp->numsaved,bp->numcached,bp->numhashes); + + if ( bp->emitfinish == 0 ) + { + if ( lastpending == 0 && bp->queued == 0 ) + iguana_bundleQ(coin,bp,1000); + if ( firstgap != 0 && ++pending == coin->MAXBUNDLES ) + { + lastpending = bp; + //printf("SET MAXBUNDLES.%d pend.%d\n",bp->hdrsi,pending); + } + spaceused += bp->estsize; + //sortbuf[m*2] = bp->metric; + //sortbuf[m*2 + 1] = i; + m++; + if ( 0 && lastpending == 0 ) + printf("%d ",bp->numsaved); + } + } } } + //printf("lastbp.[%d]\n",lastpending!=0?lastpending->hdrsi:-1); + /*if ( m > 0 ) + { + revsortds(sortbuf,m,sizeof(*sortbuf)*2); + for (i=0; ibundles[(int32_t)sortbuf[i*2 + 1]]) != 0 ) + { + bp->rank = i + 1; + if ( coin->peers.numranked > 0 && i < coin->peers.numranked && (addr= coin->peers.ranked[i]) != 0 ) + addr->bp = bp; + } + } + } + free(sortbuf);*/ coin->numremain = n; coin->blocksrecv = numrecv; - char str2[65]; uint64_t tmp; int32_t diff,p = 0; struct tai difft,t = tai_now(); + uint64_t tmp; int32_t diff,p = 0; struct tai difft,t = tai_now(); for (i=0; ipeers.active[i].usock >= 0 ) p++; @@ -435,17 +1314,105 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) tmp = (difft.millis * 1000000); tmp %= 1000000000; difft.millis = ((double)tmp / 1000000.); - sprintf(str,"N[%d] Q.%d h.%d r.%d c.%d:%d:%d s.%d d.%d E.%d:%d M.%d L.%d est.%d %s %d:%02d:%02d %03.3f peers.%d/%d Q.(%d %d)",coin->bundlescount,coin->numbundlesQ,numhashes,coin->blocksrecv,coin->numcached,numcached,coin->cachefreed,numsaved,done,numemit,coin->numreqsent,coin->blocks.hwmchain.height,coin->longestchain,coin->MAXBUNDLES,mbstr(str2,estsize),(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,difft.millis,p,coin->MAXPEERS,queue_size(&coin->priorityQ),queue_size(&coin->blocksQ)); + if ( (bp= firstgap) != coin->current && bp != 0 )//&& coin->PREFETCHLAG < 0 ) + { + printf("new 1st.%d\n",bp->hdrsi); + for (i=0; in; i++) + if ( GETBIT(bp->haveblock,i) == 0 ) + bp->issued[i] = 0; + iguana_bundleissuemissing(coin,bp,3,1.); + } + if ( (coin->current= firstgap) == 0 ) + { + firstgap = coin->current = (coin->bundlescount > 0) ? coin->bundles[coin->bundlescount-1] : coin->bundles[0]; + //printf("bundlescount.%d %p[%d]\n",coin->bundlescount,coin->current,coin->current->hdrsi); + } + if ( lastpending != 0 ) + { + if ( lastpending->hdrsi+done > coin->bundlescount-1 ) + lastpending = coin->bundles[coin->bundlescount-1]; + else lastpending = coin->bundles[lastpending->hdrsi+done]; + coin->lastpending = lastpending; + } else coin->lastpending = coin->bundles[coin->bundlescount - 1]; + coin->numsaved = numsaved; + coin->numemit = numemit; + coin->spaceused = spaceused; + coin->numverified = numv; + char str5[65]; int32_t smetric; + if ( (bp= firstgap) != 0 && bp->hdrsi < coin->bundlescount-1 ) // coin->isRT + { + smetric = (bp->hdrsi * 10000) + bp->numsaved + bp->numhashes + bp->numcached; + if ( coin->stuckmonitor != smetric ) + { + coin->stuckmonitor = smetric; + coin->stucktime = (uint32_t)time(NULL); + coin->stuckiters = 0; + } + else if ( coin->stucktime != 0 ) + { + struct iguana_blockreq *breq; int32_t n,lag; //priority=3, + lag = (int32_t)time(NULL) - coin->stucktime; + //printf("NONZ stucktime.%u lag.%d iters.%d vs %d metric.%d\n",coin->stucktime,lag,coin->stuckiters,lag/coin->MAXSTUCKTIME,smetric); + if ( (lag/coin->MAXSTUCKTIME) > coin->stuckiters ) + { + //printf("UNSTICK\n"); + iguana_unstickhdr(coin,bp,6); + coin->stuckiters = (int32_t)(lag/coin->MAXSTUCKTIME); + if ( coin->stuckiters > 2 ) + { + while ( (breq= queue_dequeue(&coin->blocksQ,0)) != 0 ) + myfree(breq,sizeof(*breq)); + while ( (breq= queue_dequeue(&coin->priorityQ,0)) != 0 ) + myfree(breq,sizeof(*breq)); + for (i=0; in; i++) + { + if ( (block= bp->blocks[i]) != 0 && block->txvalid == 0 ) + iguana_blockQ("stuck",coin,bp,i,block->RO.hash2,1); + } + } + for (i=0; in; i++) + if ( GETBIT(bp->haveblock,i) == 0 ) + bp->issued[i] = 0; + if ( (n= iguana_bundleissuemissing(coin,bp,3,1.)) > 0 ) + printf("issued %d priority requests [%d] to unstick stuckiters.%d lag.%d\n",n,bp->hdrsi,coin->stuckiters,lag); + //else printf("no bundlerequests issued\n"); + } + } //else printf("stuck metric.%d\n",smetric); + } + if ( coin->isRT != 0 || (firstgap != 0 && firstgap->hdrsi == coin->bundlescount-1) ) + coin->stucktime = coin->stuckiters = 0; + if ( coin->stucktime != 0 && time(NULL)-coin->stucktime > coin->maxstuck ) + coin->maxstuck = (uint32_t)time(NULL) - coin->stucktime; + sprintf(str,"%s.RT%d u.%d+c.%d b.%d v.%d (%d+%d/%d 1st.%d).s%d to %d N[%d] h.%d r.%d c.%d s.%d d.%d E.%d maxB.%d peers.%d/%d Q.(%d %d) (L.%d %d:%d) M.%d %s",coin->symbol,coin->RTheight,numutxo,numconverted,numbalances,iguana_validated(coin),firstgap!=0?firstgap->numcached:-1,firstgap!=0?firstgap->numsaved:-1,firstgap!=0?firstgap->numhashes:-1,firstgap!=0?firstgap->hdrsi:-1,firstgap!=0?firstgap->numspec:-1,coin->lastpending!=0?coin->lastpending->hdrsi:0,count,numhashes,coin->blocksrecv,numcached,numsaved,done,numemit,coin->MAXBUNDLES,p,coin->MAXPEERS,queue_size(&coin->priorityQ),queue_size(&coin->blocksQ),coin->longestchain,coin->longestchain/coin->chain->bundlesize,coin->longestchain%coin->chain->bundlesize,coin->blocks.hwmchain.height,bits256_str(str5,coin->blocks.hwmchain.RO.hash2)); + if ( coin->current != 0 && coin->current->hdrsi == coin->longestchain/coin->chain->bundlesize && numemit == coin->current->hdrsi && numutxo == coin->bundlescount-1 ) + { + //printf("have all utxo, generate balances\n"); + } + // u.202 b.0/202 v.202/202 + if ( coin->current != 0 && numutxo == coin->bundlescount-1 && numutxo == coin->current->hdrsi && numbalances == 0 && numconverted == numutxo ) + { + for (j=0; jbundles[j]) != 0 ) + { + //printf("bundleQ.[%d]\n",j); + bp->balancefinish = bp->startutxo = 0; + bp->utxofinish = 1; + iguana_bundleQ(coin,bp,1000); + } + } + } //sprintf(str+strlen(str),"%s.%-2d %s time %.2f files.%d Q.%d %d\n",coin->symbol,flag,str,(double)(time(NULL)-coin->starttime)/60.,coin->peers.numfiles,queue_size(&coin->priorityQ),queue_size(&coin->blocksQ)); - if ( time(NULL) > lastdisp+1000 ) + if ( time(NULL) > coin->lastdisp+7 && (strcmp(str,coin->lastdispstr) != 0 || time(NULL) > coin->lastdisp+60) ) { - printf("%s\n",str); - myallocated(0,0); - lastdisp = (uint32_t)time(NULL); + printf("%s bQ.%d %d:%02d:%02d stuck.%d max.%d\n",str,queue_size(&bundlesQ),(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,coin->stucktime!=0?(uint32_t)time(NULL) - coin->stucktime:0,coin->maxstuck); + strcpy(coin->lastdispstr,str); + if ( (rand() % 100) == 0 ) + myallocated(0,0); + coin->lastdisp = (uint32_t)time(NULL); } + iguana_setmaxbundles(coin); strcpy(coin->statusstr,str); coin->estsize = estsize; - if ( firstgap != 0 && firstgap->queued == 0 ) - iguana_bundleQ(coin,firstgap,10000); } diff --git a/iguana/iguana_chains.c b/iguana/iguana_chains.c index fa86e5c51..38d63d499 100755 --- a/iguana/iguana_chains.c +++ b/iguana/iguana_chains.c @@ -29,7 +29,7 @@ static struct iguana_chain Chains[] = //[CHAIN_TESTNET3] = { //CHAIN_TESTNET3, - "testnet3", "tBTC", + "testnet3", "tBTC", "Bitcoin Signed Message:\n", // strMessageMagic PUBKEY_ADDRESS_TEST, SCRIPT_ADDRESS_TEST, PRIVKEY_ADDRESS_TEST, "\x0b\x11\x09\x07", "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943", @@ -39,7 +39,7 @@ static struct iguana_chain Chains[] = //[CHAIN_BITCOIN] = { //CHAIN_BITCOIN, - "bitcoin", "BTC", + "bitcoin", "BTC", "Bitcoin Signed Message:\n", // strMessageMagic 0, 5, 0x80, "\xf9\xbe\xb4\xd9", "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f", @@ -51,7 +51,7 @@ static struct iguana_chain Chains[] = //[CHAIN_BTCD] = { //CHAIN_BTCD, - "btcd", "BTCD", + "btcd", "BTCD", "BitcoinDark Signed Message:\n", // strMessageMagic PUBKEY_ADDRESS_BTCD, SCRIPT_ADDRESS_BTCD, PRIVKEY_ADDRESS_BTCD, "\xe4\xc2\xd8\xe6", "0000044966f40703b516c5af180582d53f783bfd319bb045e2dc3e05ea695d46", @@ -62,7 +62,7 @@ static struct iguana_chain Chains[] = }, //[CHAIN_VPN] = { - "vpncoin", "VPN", + "vpncoin", "VPN", "VPNcoin Signed Message:\n", // strMessageMagic 71, 5, 199, // PUBKEY_ADDRESS + SCRIPT_ADDRESS addrman.h, use wif2priv API on any valid wif "\xfb\xc0\xb6\xdb", // pchMessageStart main.cpp //"aaea16b9b820180153d9cd069dbfd54764f07cb49c71987163132a72d568cb14", @@ -72,13 +72,13 @@ static struct iguana_chain Chains[] = }, //[CHAIN_LTC] = { - "litecoin", "LTC", + "litecoin", "LTC", "Litecoin Signed Message:\n", 0, 5, 176, // PUBKEY_ADDRESS + SCRIPT_ADDRESS addrman.h, use wif2priv API on any valid wif "\xfb\xc0\xb6\xdb", // pchMessageStart main.cpp //"12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2", "12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2", "010000000000000000000000000000000000000000000000000000000000000000000000d9ced4ed1130f7b7faad9be25323ffafa33232a17c3edf6cfd97bee6bafbdd97b9aa8e4ef0ff0f1ecd513f7c0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4804ffff001d0104404e592054696d65732030352f4f63742f32303131205374657665204a6f62732c204170706c65e280997320566973696f6e6172792c2044696573206174203536ffffffff0100f2052a010000004341040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9ac00000000", - 9333,9334,0,0x1e // port and rpcport vpncoin.conf + 9333,9334,0,0x1e // port and rpcport litecoin.conf }, }; @@ -94,33 +94,276 @@ static struct iguana_chain Chains[] = "genesis":{"version":1,"timestamp":1403138561,"nBits":"1e0fffff","nonce":8359109,"hash":"0000044966f40703b516c5af180582d53f783bfd319bb045e2dc3e05ea695d46","merkle":"fd1751cc6963d88feca94c0d01da8883852647a37a0a67ce254d62dd8c9d5b2b"} }*/ -bits256 iguana_chaingenesis(int32_t version,uint32_t timestamp,uint32_t bits,uint32_t nonce,bits256 merkle_root) + +int32_t blockhash_sha256(uint8_t *blockhashp,uint8_t *serialized,int32_t len) +{ + bits256 hash; + vcalc_sha256(0,hash.bytes,serialized,len); + vcalc_sha256(0,blockhashp,hash.bytes,sizeof(hash)); + return(sizeof(bits256)); +} + +int32_t blockhash_scrypt(uint8_t *blockhashp,uint8_t *serialized,int32_t len) +{ + bits256 hash; + vcalc_sha256(0,hash.bytes,serialized,len); + printf("need to implement scrypt hash here\n"); + exit(-1); + return(sizeof(bits256)); +} + +blockhashfunc iguana_hashalgo(char *hashalgostr) { - struct iguana_msgblock msg; int32_t len; bits256 hash2; uint8_t serialized[1024]; char hexstr[2049]; + if ( hashalgostr == 0 || hashalgostr[0] == 0 || strcmp(hashalgostr,"sha256") == 0 ) + return(blockhash_sha256); + else if ( strcmp(hashalgostr,"scrypt") == 0 ) + return(blockhash_scrypt); + else printf("unsupported blockhash algo.(%s)\n",hashalgostr); + return(0); +} + +bits256 iguana_chaingenesis(bits256 genesishash,char *genesisblock,char *hashalgostr,int32_t version,uint32_t timestamp,uint32_t nBits,uint32_t nonce,bits256 merkle_root) +{ + struct iguana_msgblock msg; int32_t len,blockhashlen; bits256 hash2; + char blockhashstr[256],str3[65]; uint8_t serialized[1024],blockhash[256]; + int32_t (*hashalgo)(uint8_t *blockhashp,uint8_t *serialized,int32_t len); memset(&msg,0,sizeof(msg)); msg.H.version = version; msg.H.merkle_root = merkle_root; msg.H.timestamp = timestamp; - msg.H.bits = bits; + msg.H.bits = nBits; msg.H.nonce = nonce; len = iguana_rwblock(1,&hash2,serialized,&msg); - init_hexbytes_noT(hexstr,serialized,len); - char str[65],str2[65]; printf("v.%d t.%u bits.%x nonce.%u merkle.(%s) genesis.(%s) hash.(%s) size.%ld\n",version,timestamp,bits,nonce,bits256_str(str2,merkle_root),hexstr,bits256_str(str,hash2),strlen(hexstr)/2); + blockhashstr[0] = 0; + if ( hashalgostr != 0 && strcmp(hashalgostr,"sha256") != 0 && (hashalgo= iguana_hashalgo(hashalgostr)) != 0 ) + { + if ( (blockhashlen= (*hashalgo)(blockhash,serialized,len)) > 0 ) + init_hexbytes_noT(blockhashstr,blockhash,blockhashlen); + } else init_hexbytes_noT(blockhashstr,hash2.bytes,sizeof(hash2)); + char str[65],str2[65]; + if ( bits256_cmp(genesishash,hash2) != 0 ) + printf("WARNING: genesishash.(%s) mismatch vs calc.(%s)\n",bits256_str(str,genesishash),bits256_str(str2,genesishash)); + init_hexbytes_noT(genesisblock,serialized,len); + printf("v.%d t.%u %s nBits.%08x nonce.%u merkle.(%s) genesis.(%s) hash2.(%s) blockhash.(%s) size.%d\n",version,timestamp,utc_str(str3,timestamp),nBits,nonce,bits256_str(str2,merkle_root),genesisblock,bits256_str(str,hash2),blockhashstr,(int32_t)strlen(genesisblock)/2); return(hash2); } -void iguana_chaininit(struct iguana_chain *chain,int32_t hasheaders) +char *parse_conf_line(char *line,char *field) { - chain->hasheaders = hasheaders; - if ( strcmp(chain->symbol,"bitcoin") == 0 ) + line += strlen(field); + for (; *line!='='&&*line!=0; line++) + break; + if ( *line == 0 ) + return(0); + if ( *line == '=' ) + line++; + _stripwhite(line,0); + if ( Debuglevel > 0 ) + printf("[%s]\n",line); + return(clonestr(line)); +} + +char *default_coindir(char *confname,char *coinstr) +{ + int32_t i; +#ifdef __APPLE__ + char *coindirs[][3] = { {"BTC","Bitcoin","bitcoin"}, {"BTCD","BitcoinDark"}, {"LTC","Litecoin","litecoin"}, {"VRC","Vericoin","vericoin"}, {"OPAL","OpalCoin","opalcoin"}, {"BITS","Bitstar","bitstar"}, {"DOGE","Dogecoin","dogecoin"}, {"DASH","Dash","dash"}, {"BC","Blackcoin","blackcoin"}, {"FIBRE","Fibre","fibre"}, {"VPN","Vpncoin","vpncoin"} }; +#else + char *coindirs[][3] = { {"BTC",".bitcoin"}, {"BTCD",".BitcoinDark"}, {"LTC",".litecoin"}, {"VRC",".vericoin"}, {"OPAL",".opalcoin"}, {"BITS",".Bitstar"}, {"DOGE",".dogecoin"}, {"DASH",".dash"}, {"BC",".blackcoin"}, {"FIBRE",".Fibre"}, {"VPN",".vpncoin"} }; +#endif + for (i=0; i<(int32_t)(sizeof(coindirs)/sizeof(*coindirs)); i++) + if ( strcmp(coindirs[i][0],coinstr) == 0 ) + { + if ( coindirs[i][2] != 0 ) + strcpy(confname,coindirs[i][2]); + else strcpy(confname,coindirs[i][1] + (coindirs[i][1][0] == '.')); + return(coindirs[i][1]); + } + return(coinstr); +} + +void set_coinconfname(char *fname,char *coinstr,char *userhome,char *coindir,char *confname) +{ + char buf[64]; + if ( coindir == 0 || coindir[0] == 0 ) + coindir = default_coindir(buf,coinstr); + if ( confname == 0 || confname[0] == 0 ) { - chain->unitval = 0x1d; + confname = buf; + sprintf(confname,"%s.conf",buf); } - else + printf("userhome.(%s) coindir.(%s) confname.(%s)\n",userhome,coindir,confname); + sprintf(fname,"%s/%s/%s",userhome,coindir,confname); +} + +uint16_t extract_userpass(char *serverport,char *userpass,char *coinstr,char *userhome,char *coindir,char *confname) +{ + FILE *fp; uint16_t port = 0; + char fname[2048],line[1024],*rpcuser,*rpcpassword,*rpcport,*str; + if ( strcmp(coinstr,"NXT") == 0 ) + return(0); + serverport[0] = userpass[0] = 0; + set_coinconfname(fname,coinstr,userhome,coindir,confname); + printf("set_coinconfname.(%s)\n",fname); + if ( (fp= fopen(OS_compatible_path(fname),"r")) != 0 ) + { + if ( Debuglevel > 1 ) + printf("extract_userpass from (%s)\n",fname); + rpcuser = rpcpassword = rpcport = 0; + while ( fgets(line,sizeof(line),fp) != 0 ) + { + if ( line[0] == '#' ) + continue; + //printf("line.(%s) %p %p\n",line,strstr(line,"rpcuser"),strstr(line,"rpcpassword")); + if ( (str= strstr(line,"rpcuser")) != 0 ) + rpcuser = parse_conf_line(str,"rpcuser"); + else if ( (str= strstr(line,"rpcpassword")) != 0 ) + rpcpassword = parse_conf_line(str,"rpcpassword"); + else if ( (str= strstr(line,"rpcport")) != 0 ) + rpcport = parse_conf_line(str,"rpcport"); + } + if ( rpcuser != 0 && rpcpassword != 0 ) + { + if ( userpass[0] == 0 ) + sprintf(userpass,"%s:%s",rpcuser,rpcpassword); + } + if ( rpcport != 0 ) + { + port = atoi(rpcport); + if ( serverport[0] == 0 ) + sprintf(serverport,"127.0.0.1:%s",rpcport); + free(rpcport); + } + if ( Debuglevel > 1 ) + printf("-> (%s):(%s) userpass.(%s) serverport.(%s)\n",rpcuser,rpcpassword,userpass,serverport); + if ( rpcuser != 0 ) + free(rpcuser); + if ( rpcpassword != 0 ) + free(rpcpassword); + fclose(fp); + } else printf("extract_userpass cant open.(%s)\n",fname); + return(port); +} + +void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson) +{ + extern char Userhome[]; + char *path,*conf,*hexstr,genesisblock[1024]; bits256 hash; uint16_t port; cJSON *rpair,*genesis,*rewards,*item; int32_t i,n,m; uint32_t nBits; uint8_t tmp[4]; + if ( strcmp(chain->symbol,"NXT") != 0 ) + { + if ( strcmp(chain->symbol,"BTC") != 0 ) + { + if ( strcmp(chain->symbol,"LTC") == 0 ) + chain->pubtype = 48, chain->p2shtype = 5, chain->minconfirms = 1, chain->txfee = 100000; + else if ( strcmp(chain->symbol,"BTCD") == 0 ) + chain->pubtype = 60, chain->p2shtype = 85; + else if ( strcmp(chain->symbol,"DOGE") == 0 ) + chain->pubtype = 30, chain->p2shtype = 35, chain->txfee = SATOSHIDEN; + else if ( strcmp(chain->symbol,"VRC") == 0 ) + chain->pubtype = 70, chain->p2shtype = 85; + else if ( strcmp(chain->symbol,"OPAL") == 0 ) + chain->pubtype = 115, chain->p2shtype = 28; + else if ( strcmp(chain->symbol,"BITS") == 0 ) + chain->pubtype = 25, chain->p2shtype = 8; + } + chain->minoutput = j64bits(argjson,"minoutput"); + chain->minconfirms = juint(argjson,"minconfirms"); + chain->estblocktime = juint(argjson,"estblocktime"); + path = jstr(argjson,"path"); + conf = jstr(argjson,"conf"); + chain->dust = j64bits(argjson,"dust"); + if ( jobj(argjson,"txfee_satoshis") != 0 ) + chain->txfee = j64bits(argjson,"txfee_satoshis"); + if ( chain->txfee == 0 ) + chain->txfee = (uint64_t)(SATOSHIDEN * jdouble(argjson,"txfee")); + chain->use_addmultisig = juint(argjson,"useaddmultisig"); + chain->do_opreturn = juint(argjson,"do_opreturn"); + if ( jobj(argjson,"hastimestamp") != 0 ) + chain->hastimestamp = juint(argjson,"hastimestamp"); + else if ( jobj(argjson,"oldtx_format") != 0 ) + chain->hastimestamp = !juint(argjson,"oldtx_format"); + if ( jstr(argjson,"userhome") != 0 ) + strcpy(chain->userhome,jstr(argjson,"userhome")); + else strcpy(chain->userhome,Userhome); + if ( (port= extract_userpass(chain->serverport,chain->userpass,chain->symbol,chain->userhome,path,conf)) != 0 ) + chain->rpcport = port; + printf("COIN.%s serverport.(%s) userpass.(%s) port.%u\n",chain->symbol,chain->serverport,chain->userpass,chain->rpcport); + if ( (hexstr= jstr(argjson,"pubval")) != 0 && strlen(hexstr) == 2 ) + decode_hex((uint8_t *)&chain->pubtype,1,hexstr); + if ( (hexstr= jstr(argjson,"scriptval")) != 0 && strlen(hexstr) == 2 ) + decode_hex((uint8_t *)&chain->p2shtype,1,hexstr); + if ( (hexstr= jstr(argjson,"wiftype")) != 0 && strlen(hexstr) == 2 ) + decode_hex((uint8_t *)&chain->wiftype,1,hexstr); + if ( (hexstr= jstr(argjson,"netmagic")) != 0 && strlen(hexstr) == 8 ) + decode_hex((uint8_t *)chain->netmagic,1,hexstr); + if ( (hexstr= jstr(argjson,"unitval")) != 0 && strlen(hexstr) == 2 ) + decode_hex((uint8_t *)&chain->unitval,1,hexstr); + if ( (hexstr= jstr(argjson,"genesishash")) != 0 ) + { + chain->genesis_hash = mycalloc('G',1,strlen(hexstr)+1); + strcpy(chain->genesis_hash,hexstr); + } + if ( (genesis= jobj(argjson,"genesis")) != 0 ) + { + chain->hashalgo = iguana_hashalgo(jstr(genesis,"hashalgo")); + decode_hex(hash.bytes,sizeof(hash),chain->genesis_hash); + if ( jstr(genesis,"nBits") != 0 ) + { + decode_hex((void *)&tmp,sizeof(tmp),jstr(genesis,"nBits")); + ((uint8_t *)&nBits)[0] = tmp[3]; + ((uint8_t *)&nBits)[1] = tmp[2]; + ((uint8_t *)&nBits)[2] = tmp[1]; + ((uint8_t *)&nBits)[3] = tmp[0]; + } + else nBits = 0x1e00ffff; + hash = iguana_chaingenesis(hash,genesisblock,jstr(genesis,"hashalgo"),juint(genesis,"version"),juint(genesis,"timestamp"),nBits,juint(genesis,"nonce"),jbits256(genesis,"merkle_root")); + //chain->genesis_hash = clonestr(bits256_str(str,hash)); + chain->genesis_hex = clonestr(genesisblock); + } + else + { + if ( (hexstr= jstr(argjson,"genesisblock")) != 0 ) + { + chain->genesis_hex = mycalloc('G',1,strlen(hexstr)+1); + strcpy(chain->genesis_hex,hexstr); + } + } + if ( juint(argjson,"p2p") != 0 ) + chain->portp2p = juint(argjson,"p2p"); + if ( (chain->ramchainport= juint(argjson,"ramchain")) == 0 ) + chain->ramchainport = chain->portp2p - 1; + if ( (chain->rpcport= juint(argjson,"rpc")) == 0 ) + chain->rpcport = chain->portp2p + 1; + if ( (rewards= jarray(&n,argjson,"rewards")) != 0 ) + { + for (i=0; irewards[i][0] = j64bits(jitem(rpair,0),0); + chain->rewards[i][1] = j64bits(jitem(rpair,1),0); + } + } + } + } +} + +void iguana_chaininit(struct iguana_chain *chain,int32_t hasheaders,cJSON *argjson) +{ + chain->hasheaders = hasheaders; + chain->minoutput = 10000; + chain->hashalgo = blockhash_sha256; + if ( strcmp(chain->symbol,"BTC") == 0 ) { - if ( chain->unitval == 0 ) - chain->unitval = 0x1e; + chain->unitval = 0x1d; + chain->txfee = 10000; } + else chain->txfee = 1000000; + if ( chain->unitval == 0 ) + chain->unitval = 0x1e; + if ( argjson != 0 ) + iguana_chainparms(chain,argjson); if ( hasheaders != 0 ) { strcpy(chain->gethdrsmsg,"getheaders"); @@ -134,23 +377,29 @@ void iguana_chaininit(struct iguana_chain *chain,int32_t hasheaders) decode_hex((uint8_t *)chain->genesis_hashdata,32,(char *)chain->genesis_hash); if ( chain->ramchainport == 0 ) chain->ramchainport = chain->portp2p - 1; - if ( chain->portrpc == 0 ) - chain->portrpc = chain->portp2p + 1; + if ( chain->rpcport == 0 ) + chain->rpcport = chain->portp2p + 1; } -struct iguana_chain *iguana_chainfind(char *name) +struct iguana_chain *iguana_chainfind(char *name,cJSON *argjson,int32_t createflag) { struct iguana_chain *chain; uint32_t i; - for (i=0; igenesis_hash,chain->name,name,strcmp(name,chain->name)); if ( chain->name[0] == 0 || chain->genesis_hash == 0 ) - continue; + { + if ( createflag != 0 && argjson != 0 ) + { + iguana_chaininit(chain,strcmp(chain->symbol,"BTC") == 0,argjson); + return(chain); + } + continue; + } if ( strcmp(name,chain->symbol) == 0 ) { - printf("found.(%s)\n",name); - iguana_chaininit(chain,strcmp(chain->symbol,"BTC") == 0); + iguana_chaininit(chain,strcmp(chain->symbol,"BTC") == 0,argjson); return(chain); } } @@ -166,7 +415,7 @@ struct iguana_chain *iguana_findmagic(uint8_t netmagic[4]) if ( chain->name[0] == 0 || chain->genesis_hash == 0 ) continue; if ( memcmp(netmagic,chain->netmagic,4) == 0 ) - return(iguana_chainfind((char *)chain->symbol)); + return(iguana_chainfind((char *)chain->symbol,0,0)); } return NULL; } @@ -186,52 +435,14 @@ uint64_t iguana_miningreward(struct iguana_info *coin,uint32_t blocknum) struct iguana_chain *iguana_createchain(cJSON *json) { - char *symbol,*name,*hexstr; cJSON *rewards,*rpair,*item; int32_t i,m,n; struct iguana_chain *chain = 0; - if ( (symbol= jstr(json,"name")) != 0 && strlen(symbol) < 8 ) + char *symbol,*name; struct iguana_chain *chain = 0; + if ( ((symbol= jstr(json,"newcoin")) != 0 || (symbol= jstr(json,"name")) != 0) && strlen(symbol) < 8 ) { chain = mycalloc('C',1,sizeof(*chain)); strcpy(chain->symbol,symbol); if ( (name= jstr(json,"description")) != 0 && strlen(name) < 32 ) strcpy(chain->name,name); - if ( (hexstr= jstr(json,"pubval")) != 0 && strlen(hexstr) == 2 ) - decode_hex((uint8_t *)&chain->pubtype,1,hexstr); - if ( (hexstr= jstr(json,"scriptval")) != 0 && strlen(hexstr) == 2 ) - decode_hex((uint8_t *)&chain->p2shtype,1,hexstr); - if ( (hexstr= jstr(json,"wiftype")) != 0 && strlen(hexstr) == 2 ) - decode_hex((uint8_t *)&chain->wiftype,1,hexstr); - if ( (hexstr= jstr(json,"netmagic")) != 0 && strlen(hexstr) == 8 ) - decode_hex((uint8_t *)chain->netmagic,1,hexstr); - if ( (hexstr= jstr(json,"unitval")) != 0 && strlen(hexstr) == 2 ) - decode_hex((uint8_t *)&chain->unitval,1,hexstr); - if ( (hexstr= jstr(json,"genesishash")) != 0 ) - { - chain->genesis_hash = mycalloc('G',1,strlen(hexstr)+1); - strcpy(chain->genesis_hash,hexstr); - } - if ( (hexstr= jstr(json,"genesisblock")) != 0 ) - { - chain->genesis_hex = mycalloc('G',1,strlen(hexstr)+1); - strcpy(chain->genesis_hex,hexstr); - } - chain->portp2p = juint(json,"p2p"); - if ( (chain->ramchainport= juint(json,"ramchain")) == 0 ) - chain->ramchainport = chain->portp2p - 1; - if ( (chain->portrpc= juint(json,"rpc")) == 0 ) - chain->portrpc = chain->portp2p + 1; - chain->hastimestamp = juint(json,"hastimestamp"); - if ( (rewards= jarray(&n,json,"rewards")) != 0 ) - { - for (i=0; irewards[i][0] = j64bits(jitem(rpair,0),0); - chain->rewards[i][1] = j64bits(jitem(rpair,1),0); - } - } - } - iguana_chaininit(chain,juint(json,"hasheaders")); + iguana_chaininit(chain,juint(json,"hasheaders"),json); } return(chain); } diff --git a/iguana/iguana_exchanges.c b/iguana/iguana_exchanges.c index 3e8c65735..c9484f9a9 100755 --- a/iguana/iguana_exchanges.c +++ b/iguana/iguana_exchanges.c @@ -58,8 +58,8 @@ cJSON *exchanges777_quotejson(struct exchange_quote *quote,int32_t allflag,doubl jaddstr(json,"time",utc_str(str,quote->timestamp)); if ( quote->orderid > 0 ) jadd64bits(json,"orderid",quote->orderid); - if ( quote->offerNXT > 0 ) - jadd64bits(json,"offerNXT",quote->offerNXT); + //if ( quote->offerNXT != 0 ) + jadd64bits(json,"offerer",quote->offerNXT); return(json); } else return(cJSON_CreateNumber(quote->price)); } @@ -245,6 +245,7 @@ void exchanges777_json_quotes(struct exchange_info *exchange,double commission,c volume = jdouble(item,"volume"); timestamp = juint(item,"timestamp"); orderid = j64bits(item,"orderid"); + offerNXT = j64bits(item,"offerer"); } if ( price == 0. || volume == 0. ) continue; @@ -533,11 +534,13 @@ char *exchanges777_process(struct exchange_info *exchange,int32_t *retvalp,struc orderid = (*exchange->issue.trade)(req->dotrade,&retstr,exchange,base,rel,polarity * req->dir,price,volume,req->argjson); if ( retstr == 0 ) { - retjson = cJSON_CreateObject(); + req->orderid = orderid; + retstr = (*exchange->issue.orderstatus)(exchange,req->orderid,req->argjson); + /*retjson = cJSON_CreateObject(); if ( orderid != 0 ) jadd64bits(retjson,"result",orderid); else jaddstr(retjson,"error","no return value from trade call"); - retstr = jprint(retjson,1); + retstr = jprint(retjson,1);*/ } } break; @@ -632,9 +635,10 @@ void exchanges777_loop(void *ptr) { if ( retstr != 0 ) free(retstr); - if ( retval == EXCHANGE777_ISPENDING ) - queue_enqueue("Xpending",&exchange->pendingQ[0],&req->DL,0), flag++; - else if ( retval == EXCHANGE777_REQUEUE ) + //if ( retval == EXCHANGE777_ISPENDING ) + // queue_enqueue("Xpending",&exchange->pendingQ,&req->DL,0), flag++; + //else + if ( retval == EXCHANGE777_REQUEUE ) queue_enqueue("requeue",&exchange->requestQ,&req->DL,0); else { @@ -654,6 +658,11 @@ void exchanges777_loop(void *ptr) tradebot_timeslice(exchange,bot); if ( time(NULL) > exchange->lastpoll+exchange->pollgap ) { + if ( strcmp(exchange->name,"bitcoin") == 0 ) + { + instantdex_update(SuperNET_MYINFO(0)); + //printf("InstantDEX call update\n"); + } if ( (req= queue_dequeue(&exchange->pricesQ,0)) != 0 ) { //printf("check %s pricesQ (%s %s)\n",exchange->name,req->base,req->rel); @@ -881,8 +890,8 @@ struct exchange_info *exchange_create(char *exchangestr,cJSON *argjson) iguana_initQ(&exchange->requestQ,"request"); iguana_initQ(&exchange->acceptableQ,"acceptable"); iguana_initQ(&exchange->tradebotsQ,"tradebots"); - iguana_initQ(&exchange->pendingQ[0],"pending0"); - iguana_initQ(&exchange->pendingQ[1],"pending1"); + iguana_initQ(&exchange->historyQ,"history"); + iguana_initQ(&exchange->statemachineQ,"statemachineQ"); exchange->exchangeid = exchangeid; safecopy(exchange->name,exchangestr,sizeof(exchange->name)); exchange->exchangebits = stringbits(exchange->name); @@ -898,16 +907,16 @@ struct exchange_info *exchange_create(char *exchangestr,cJSON *argjson) safecopy(exchange->tradepassword,tradepassword,sizeof(exchange->tradepassword)); if ( (exchange->commission= jdouble(argjson,"commission")) > 0. ) exchange->commission *= .01; - printf("ADDEXCHANGE.(%s) [%s, %s, %s] commission %.3f%%\n",exchangestr,exchange->apikey,exchange->userid,exchange->apisecret,exchange->commission * 100.); + printf("ADDEXCHANGE.(%s) [%s, %s, %s] commission %.3f%% -> exchangeid.%d\n",exchangestr,exchange->apikey,exchange->userid,exchange->apisecret,exchange->commission * 100.,exchangeid); Exchanges[exchangeid] = exchange; - iguana_launch(iguana_coinadd("BTCD"),"exchangeloop",(void *)exchanges777_loop,exchange,IGUANA_EXCHANGETHREAD); + iguana_launch(0,"exchangeloop",(void *)exchanges777_loop,exchange,IGUANA_EXCHANGETHREAD); return(exchange); } struct exchange_info *exchanges777_info(char *exchangestr,int32_t sleepflag,cJSON *json,char *remoteaddr) { struct exchange_info *exchange; - if ( remoteaddr != 0 ) + if ( remoteaddr != 0 || exchangestr == 0 ) return(0); if ( (exchange= exchanges777_find(exchangestr)) == 0 ) { @@ -941,14 +950,20 @@ void exchanges777_init(struct supernet_info *myinfo,cJSON *exchanges,int32_t sle { argjson = cJSON_CreateObject(); for (i=0; iname)) == 0 && (exchange= exchanges777_info(Exchange_funcs[i]->name,sleepflag,argjson,0)) != 0 ) - myinfo->tradingexchanges[myinfo->numexchanges++] = exchange; + if ( (exchange= exchanges777_find(Exchange_funcs[i]->name)) == 0 ) + { + if ( strcmp(Exchange_funcs[i]->name,"PAX") == 0 || strcmp(Exchange_funcs[i]->name,"truefx") == 0 || strcmp(Exchange_funcs[i]->name,"fxcm") == 0 || strcmp(Exchange_funcs[i]->name,"instaforx") == 0 ) + continue; + if ( (exchange= exchanges777_info(Exchange_funcs[i]->name,sleepflag,argjson,0)) != 0 ) + myinfo->tradingexchanges[myinfo->numexchanges++] = exchange; + } free_json(argjson); } instantdexhash = calc_categoryhashes(0,"InstantDEX",0); printf("InstantDEX:\n"); category_subscribe(myinfo,instantdexhash,GENESIS_PUBKEY); - category_processfunc(instantdexhash,InstantDEX_hexmsg); + category_processfunc(instantdexhash,GENESIS_PUBKEY,InstantDEX_hexmsg); + category_processfunc(instantdexhash,myinfo->myaddr.persistent,InstantDEX_hexmsg); } #include "../includes/iguana_apidefs.h" @@ -956,116 +971,144 @@ void exchanges777_init(struct supernet_info *myinfo,cJSON *exchanges,int32_t sle THREE_STRINGS_AND_THREE_INTS(InstantDEX,orderbook,exchange,base,rel,depth,allfields,ignore) { struct exchange_info *ptr; - if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) - return(exchanges777_Qprices(ptr,base,rel,juint(json,"maxseconds"),allfields,depth,json,0,ptr->commission)); - else return(clonestr("{\"error\":\"cant find or create exchange\"}")); + if ( remoteaddr == 0 ) + { + if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) + return(exchanges777_Qprices(ptr,base,rel,juint(json,"maxseconds"),allfields,depth,json,0,ptr->commission)); + else return(clonestr("{\"error\":\"cant find or create exchange\"}")); + } else return(clonestr("{\"error\":\"no remote for this API\"}")); } THREE_STRINGS_AND_THREE_DOUBLES(InstantDEX,buy,exchange,base,rel,price,volume,dotrade) { struct exchange_info *ptr; - if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) - return(exchanges777_Qtrade(ptr,base,rel,juint(json,"maxseconds"),dotrade,1,price,volume,json)); - else return(clonestr("{\"error\":\"cant find or create exchange\"}")); + if ( remoteaddr == 0 ) + { + if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) + return(exchanges777_Qtrade(ptr,base,rel,juint(json,"maxseconds"),dotrade,1,price,volume,json)); + else return(clonestr("{\"error\":\"cant find or create exchange\"}")); + } else return(clonestr("{\"error\":\"no remote for this API\"}")); } THREE_STRINGS_AND_THREE_DOUBLES(InstantDEX,sell,exchange,base,rel,price,volume,dotrade) { struct exchange_info *ptr; - if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) - return(exchanges777_Qtrade(ptr,base,rel,juint(json,"maxseconds"),dotrade,-1,price,volume,json)); - else return(clonestr("{\"error\":\"cant find or create exchange\"}")); + if ( remoteaddr == 0 ) + { + if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) + return(exchanges777_Qtrade(ptr,base,rel,juint(json,"maxseconds"),dotrade,-1,price,volume,json)); + else return(clonestr("{\"error\":\"cant find or create exchange\"}")); + } else return(clonestr("{\"error\":\"no remote for this API\"}")); } THREE_STRINGS_AND_DOUBLE(InstantDEX,withdraw,exchange,base,destaddr,amount) { struct exchange_info *ptr; - if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) - return(exchanges777_Qrequest(ptr,'W',base,0,juint(json,"maxseconds"),0,destaddr,amount,json)); - else return(clonestr("{\"error\":\"cant find or create exchange\"}")); -} - -THREE_STRINGS(InstantDEX,supports,exchange,base,rel) -{ - struct exchange_info *ptr; - if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) - return(exchanges777_Qrequest(ptr,'S',base,rel,juint(json,"maxseconds"),0,0,0,json)); - else return(clonestr("{\"error\":\"cant find or create exchange\"}")); + if ( remoteaddr == 0 ) + { + if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) + return(exchanges777_Qrequest(ptr,'W',base,0,juint(json,"maxseconds"),0,destaddr,amount,json)); + else return(clonestr("{\"error\":\"cant find or create exchange\"}")); + } else return(clonestr("{\"error\":\"no remote for this API\"}")); } TWO_STRINGS(InstantDEX,balance,exchange,base) { struct exchange_info *ptr; - if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) - return(exchanges777_Qrequest(ptr,'B',base,0,juint(json,"maxseconds"),0,0,0,json)); - else return(clonestr("{\"error\":\"cant find or create exchange\"}")); + if ( remoteaddr == 0 ) + { + if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) + return(exchanges777_Qrequest(ptr,'B',base,0,juint(json,"maxseconds"),0,0,0,json)); + else return(clonestr("{\"error\":\"cant find or create exchange\"}")); + } else return(clonestr("{\"error\":\"no remote for this API\"}")); } TWO_STRINGS(InstantDEX,orderstatus,exchange,orderid) { struct exchange_info *ptr; - if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) - return(exchanges777_Qrequest(ptr,'P',0,0,juint(json,"maxseconds"),calc_nxt64bits(orderid),0,0,json)); - else return(clonestr("{\"error\":\"cant find or create exchange\"}")); + if ( remoteaddr == 0 ) + { + if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) + return(exchanges777_Qrequest(ptr,'P',0,0,juint(json,"maxseconds"),calc_nxt64bits(orderid),0,0,json)); + else return(clonestr("{\"error\":\"cant find or create exchange\"}")); + } else return(clonestr("{\"error\":\"no remote for this API\"}")); } TWO_STRINGS(InstantDEX,cancelorder,exchange,orderid) { struct exchange_info *ptr; - if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) - return(exchanges777_Qrequest(ptr,'C',0,0,juint(json,"maxseconds"),calc_nxt64bits(orderid),0,0,json)); - else return(clonestr("{\"error\":\"cant find or create exchange\"}")); + if ( remoteaddr == 0 ) + { + if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) + return(exchanges777_Qrequest(ptr,'C',0,0,juint(json,"maxseconds"),calc_nxt64bits(orderid),0,0,json)); + else return(clonestr("{\"error\":\"cant find or create exchange\"}")); + } else return(clonestr("{\"error\":\"no remote for this API\"}")); } STRING_ARG(InstantDEX,openorders,exchange) { struct exchange_info *ptr; - if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) - return(exchanges777_Qrequest(ptr,'O',0,0,juint(json,"maxseconds"),0,0,0,json)); - else return(clonestr("{\"error\":\"cant find or create exchange\"}")); + if ( remoteaddr == 0 ) + { + if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) + return(exchanges777_Qrequest(ptr,'O',0,0,juint(json,"maxseconds"),0,0,0,json)); + else return(clonestr("{\"error\":\"cant find or create exchange\"}")); + } else return(clonestr("{\"error\":\"no remote for this API\"}")); } STRING_ARG(InstantDEX,tradehistory,exchange) { struct exchange_info *ptr; - if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) - return(exchanges777_Qrequest(ptr,'H',0,0,juint(json,"maxseconds"),0,0,0,json)); - else return(clonestr("{\"error\":\"cant find or create exchange\"}")); + if ( remoteaddr == 0 ) + { + if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) + return(exchanges777_Qrequest(ptr,'H',0,0,juint(json,"maxseconds"),0,0,0,json)); + else return(clonestr("{\"error\":\"cant find or create exchange\"}")); + } else return(clonestr("{\"error\":\"no remote for this API\"}")); } THREE_STRINGS(InstantDEX,apikeypair,exchange,apikey,apisecret) { struct exchange_info *ptr; - if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) + if ( remoteaddr == 0 ) { - if ( apikey != 0 && apikey[0] != 0 && apisecret != 0 && apisecret[0] != 0 ) + if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) { - safecopy(ptr->apikey,apikey,sizeof(ptr->apikey)); - safecopy(ptr->apisecret,apisecret,sizeof(ptr->apisecret)); - return(clonestr("{\"result\":\"set apikey and apisecret\"}")); - } else return(clonestr("{\"error\":\"need both userid and password\"}")); - } else return(clonestr("{\"error\":\"cant find or create exchange\"}")); + if ( apikey != 0 && apikey[0] != 0 && apisecret != 0 && apisecret[0] != 0 ) + { + safecopy(ptr->apikey,apikey,sizeof(ptr->apikey)); + safecopy(ptr->apisecret,apisecret,sizeof(ptr->apisecret)); + return(clonestr("{\"result\":\"set apikey and apisecret\"}")); + } else return(clonestr("{\"error\":\"need both userid and password\"}")); + } else return(clonestr("{\"error\":\"cant find or create exchange\"}")); + } else return(clonestr("{\"error\":\"no remote for this API\"}")); } THREE_STRINGS(InstantDEX,setuserid,exchange,userid,tradepassword) { struct exchange_info *ptr; - if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) + if ( remoteaddr == 0 ) { - safecopy(ptr->userid,userid,sizeof(ptr->userid)); - safecopy(ptr->tradepassword,tradepassword,sizeof(ptr->tradepassword)); - return(clonestr("{\"result\":\"set userid and/or tradepassword\"}")); - } else return(clonestr("{\"error\":\"cant find or create exchange\"}")); + if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) + { + safecopy(ptr->userid,userid,sizeof(ptr->userid)); + safecopy(ptr->tradepassword,tradepassword,sizeof(ptr->tradepassword)); + return(clonestr("{\"result\":\"set userid and/or tradepassword\"}")); + } else return(clonestr("{\"error\":\"cant find or create exchange\"}")); + } else return(clonestr("{\"error\":\"no remote for this API\"}")); } STRING_AND_INT(InstantDEX,pollgap,exchange,pollgap) { struct exchange_info *ptr; - if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) + if ( remoteaddr == 0 ) { - ptr->pollgap = pollgap; - return(clonestr("{\"result\":\"set pollgap\"}")); - } else return(clonestr("{\"error\":\"cant find or create exchange\"}")); + if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) + { + ptr->pollgap = pollgap; + return(clonestr("{\"result\":\"set pollgap\"}")); + } else return(clonestr("{\"error\":\"cant find or create exchange\"}")); + } else return(clonestr("{\"error\":\"no remote for this API\"}")); } ZERO_ARGS(InstantDEX,allexchanges) @@ -1078,6 +1121,14 @@ ZERO_ARGS(InstantDEX,allexchanges) return(jprint(retjson,1)); } +THREE_STRINGS(InstantDEX,supports,exchange,base,rel) +{ + struct exchange_info *ptr; + if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) + return(exchanges777_Qrequest(ptr,'S',base,rel,juint(json,"maxseconds"),0,0,0,json)); + else return(clonestr("{\"error\":\"cant find or create exchange\"}")); +} + STRING_ARG(InstantDEX,allpairs,exchange) { struct exchange_info *ptr; diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index bfc26cb25..a5b177909 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -18,6 +18,8 @@ void iguana_initQ(queue_t *Q,char *name) { char *tst,*str = "need to init each Q when single threaded"; + memset(Q,0,sizeof(*Q)); + strcpy(Q->name,name); queue_enqueue(name,Q,queueitem(str),1); if ( (tst= queue_dequeue(Q,1)) != 0 ) free_queueitem(tst); @@ -27,13 +29,13 @@ void iguana_initQs(struct iguana_info *coin) { int32_t i; iguana_initQ(&coin->acceptQ,"acceptQ"); - iguana_initQ(&coin->bundlesQ,"bundlesQ"); iguana_initQ(&coin->hdrsQ,"hdrsQ"); iguana_initQ(&coin->blocksQ,"blocksQ"); iguana_initQ(&coin->priorityQ,"priorityQ"); iguana_initQ(&coin->possibleQ,"possibleQ"); + iguana_initQ(&coin->msgrequestQ,"msgrequestQ"); iguana_initQ(&coin->cacheQ,"cacheQ"); - iguana_initQ(&coin->TerminateQ,"TerminateQ"); + iguana_initQ(&coin->recvQ,"recvQ"); for (i=0; ipeers.active[i].sendQ,"addrsendQ"); } @@ -43,16 +45,17 @@ void iguana_initpeer(struct iguana_info *coin,struct iguana_peer *addr,uint64_t memset(addr,0,sizeof(*addr)); addr->ipbits = ipbits; addr->usock = -1; - expand_ipbits(addr->ipaddr,addr->ipbits); + expand_ipbits(addr->ipaddr,(uint32_t)addr->ipbits); //addr->pending = (uint32_t)time(NULL); strcpy(addr->symbol,coin->symbol); strcpy(addr->coinstr,coin->name); iguana_initQ(&addr->sendQ,"addrsendQ"); } -void iguana_initcoin(struct iguana_info *coin) +void iguana_initcoin(struct iguana_info *coin,cJSON *argjson) { - int32_t i; + int32_t i; char dirname[1024]; + sprintf(dirname,"%s/%s",GLOBAL_TMPDIR,coin->symbol), OS_portable_path(dirname); portable_mutex_init(&coin->peers_mutex); portable_mutex_init(&coin->blocks_mutex); iguana_meminit(&coin->blockMEM,"blockMEM",coin->blockspace,sizeof(coin->blockspace),0); @@ -62,28 +65,32 @@ void iguana_initcoin(struct iguana_info *coin) coin->startutc = (uint32_t)time(NULL); while ( time(NULL) == coin->startutc ) usleep(1); - coin->startmillis = OS_milliseconds(), coin->starttime = tai_now(coin->startmillis); + coin->startutc++; + printf("start.%u\n",coin->startutc); + coin->startmillis = OS_milliseconds(), coin->starttime = tai_now(); coin->avetime = 1 * 100; //coin->R.maxrecvbundles = IGUANA_INITIALBUNDLES; for (i=0; ipeers.active[i].usock = -1; - - // validate blocks!! - //for (i=0; ilatest.lhashes[i].bytes,&coin->latest.states[i],0,0); } bits256 iguana_genesis(struct iguana_info *coin,struct iguana_chain *chain) { - struct iguana_block block,*ptr; struct iguana_msgblock msg; bits256 hash2; char str[65]; uint8_t buf[1024]; int32_t height; + struct iguana_block block,*ptr; struct iguana_msgblock msg; bits256 hash2; char str[65],str2[65]; uint8_t buf[1024]; int32_t height; + if ( chain->genesis_hex == 0 ) + { + printf("no genesis_hex for %s\n",coin->symbol); + memset(hash2.bytes,0,sizeof(hash2)); + return(hash2); + } decode_hex(buf,(int32_t)strlen(chain->genesis_hex)/2,(char *)chain->genesis_hex); hash2 = bits256_doublesha256(0,buf,sizeof(struct iguana_msgblockhdr)); iguana_rwblock(0,&hash2,buf,&msg); if ( memcmp(hash2.bytes,chain->genesis_hashdata,sizeof(hash2)) != 0 ) { bits256_str(str,hash2); - printf("genesis mismatch? calculated %s vs %s\n",str,(char *)chain->genesis_hex); - hash2 = bits256_conv("00000ac7d764e7119da60d3c832b1d4458da9bc9ef9d5dd0d91a15f690a46d99"); + printf("genesis mismatch? calculated %s vs %s\n",str,bits256_str(str2,*(bits256 *)chain->genesis_hashdata)); + //hash2 = bits256_conv("00000ac7d764e7119da60d3c832b1d4458da9bc9ef9d5dd0d91a15f690a46d99"); //memset(hash2.bytes,0,sizeof(hash2)); //return(hash2); @@ -91,14 +98,14 @@ bits256 iguana_genesis(struct iguana_info *coin,struct iguana_chain *chain) bits256_str(str,hash2); printf("genesis.(%s) len.%d hash.%s\n",chain->genesis_hex,(int32_t)sizeof(msg.H),str); iguana_blockconv(&block,&msg,hash2,0); - //coin->latest.dep.numtxids = block.RO.txn_count = 1; block.RO.numvouts = 1; iguana_gotdata(coin,0,0); - if ( (ptr= iguana_blockhashset(coin,0,hash2,1)) != 0 ) + if ( (ptr= iguana_blockhashset("genesis0",coin,0,hash2,1)) != 0 ) { - ptr->mainchain = 1; iguana_blockcopy(coin,ptr,&block); + ptr->mainchain = 1; + ptr->height = 0; coin->blocks.RO[0] = block.RO; if ( (height= iguana_chainextend(coin,ptr)) == 0 ) { @@ -113,77 +120,124 @@ bits256 iguana_genesis(struct iguana_info *coin,struct iguana_chain *chain) getchar(); } int32_t bundlei = -2; - static bits256 zero; + static const bits256 zero; iguana_bundlecreate(coin,&bundlei,0,hash2,zero,1); - _iguana_chainlink(coin,iguana_blockfind(coin,hash2)); + _iguana_chainlink(coin,iguana_blockfind("genesis",coin,hash2)); return(hash2); } int32_t iguana_savehdrs(struct iguana_info *coin) { - int32_t height,i,n,retval = 0; char fname[512],shastr[65],tmpfname[512],str[65],oldfname[512]; - bits256 hash2,sha256all,*hashes; FILE *fp; + char fname[512],shastr[65],tmpfname[512],tmpfname2[512],str2[65],str[65],oldfname[512]; + bits256 sha256all; FILE *fp,*fp2; struct iguana_bundle *bp; int32_t hdrsi,n,retval = 0; n = coin->blocks.hwmchain.height + 1; - hashes = mycalloc('h',coin->chain->bundlesize,sizeof(*hashes)); - sprintf(oldfname,"confs/%s_oldhdrs.txt",coin->symbol), OS_compatible_path(oldfname); - sprintf(tmpfname,"tmp/%s/hdrs.txt",coin->symbol), OS_compatible_path(tmpfname); - sprintf(fname,"confs/%s_hdrs.txt",coin->symbol), OS_compatible_path(fname); + sprintf(tmpfname,"%s/%s/hdrs.txt",GLOBAL_TMPDIR,coin->symbol), OS_compatible_path(tmpfname); + sprintf(tmpfname2,"%s/%s/hdrs.h",GLOBAL_TMPDIR,coin->symbol), OS_compatible_path(tmpfname); + sprintf(oldfname,"%s/%s_oldhdrs.txt",GLOBAL_CONFSDIR,coin->symbol), OS_compatible_path(oldfname); + sprintf(fname,"%s/%s_hdrs.txt",GLOBAL_CONFSDIR,coin->symbol), OS_compatible_path(fname); if ( (fp= fopen(tmpfname,"w")) != 0 ) { + if ( (fp2= fopen(tmpfname2,"w")) != 0 ) + fprintf(fp2,"char *%s_hdrs[][4] = {\n",coin->symbol); fprintf(fp,"%d\n",n); - for (height=0; height<=n; height+=coin->chain->bundlesize) + for (hdrsi=0; hdrsibundlescount; hdrsi++) { - for (i=0; ichain->bundlesize; i++) + if ( (bp= coin->bundles[hdrsi]) != 0 && bp->numhashes >= bp->n ) { - hashes[i] = iguana_blockhash(coin,height+i); - if ( bits256_str(str,hashes[i]) == 0 ) - break; + shastr[0] = 0; + if ( bits256_nonz(bp->allhash) == 0 ) + { + vcalc_sha256(shastr,sha256all.bytes,bp->hashes[0].bytes,sizeof(*bp->hashes) * coin->chain->bundlesize); + bp->allhash = sha256all; + } + else + { + sha256all = bp->allhash; + bits256_str(shastr,bp->allhash); + } + fprintf(fp,"%d %s %s %s\n",bp->bundleheight,bits256_str(str,bp->hashes[0]),shastr,bits256_str(str2,bp->hashes[1])); + if ( fp2 != 0 ) + fprintf(fp2,"{ \"%d\", \"%s\", \"%s\", \"%s\"},\n",bp->bundleheight,bits256_str(str,bp->hashes[0]),shastr,bits256_str(str2,bp->hashes[1])); } - if ( i == coin->chain->bundlesize ) + else { - struct iguana_bundle *bp; - if ( (bp= coin->bundles[height/coin->chain->bundlesize]) != 0 ) + if ( bp != 0 && bits256_nonz(bp->hashes[0]) != 0 ) { - if ( bits256_nonz(bp->allhash) == 0 ) - { - vcalc_sha256(shastr,sha256all.bytes,hashes[0].bytes,sizeof(*hashes) * coin->chain->bundlesize); - bp->allhash = sha256all; - } - else - { - sha256all = bp->allhash; - bits256_str(shastr,bp->allhash); - } + fprintf(fp,"%d %s\n",bp->bundleheight,bits256_str(str,bp->hashes[0])); + if ( fp2 != 0 ) + fprintf(fp2,"{ \"%d\", \"%s\", \"%s\", \"%s\"},\n",bp->bundleheight,bits256_str(str,bp->hashes[0]),"",""); } - } else shastr[0] = 0; - hash2 = iguana_blockhash(coin,height); - if ( bits256_nonz(hash2) > 0 ) - { - fprintf(fp,"%d %s %s\n",height,bits256_str(str,hash2),shastr); - retval = height; + break; } } - //printf("new hdrs.txt %ld vs (%s) %ld\n",ftell(fp),fname,(long)iguana_filesize(fname)); - if ( ftell(fp) > OS_filesize(fname) ) + //printf("compare hdrs.txt %ld vs (%s) %ld\n",ftell(fp),fname,(long)OS_filesize(fname)); + if ( (long)ftell(fp) > OS_filesize(fname) ) { printf("new hdrs.txt %ld vs (%s) %ld\n",ftell(fp),fname,(long)OS_filesize(fname)); fclose(fp); OS_renamefile(fname,oldfname); OS_copyfile(tmpfname,fname,1); } else fclose(fp); + if ( fp2 != 0 ) + { + fprintf(fp2,"};\n"); + fclose(fp2); + } + } + else + { + printf("iguana_savehdrs: couldnt create.(%s)\n",tmpfname); + return(-1); } - myfree(hashes,coin->chain->bundlesize * sizeof(*hashes)); return(retval); } +int32_t iguana_bundleinitmap(struct iguana_info *coin,struct iguana_bundle *bp,int32_t height,bits256 hash2,bits256 hash1) +{ + char str[65]; struct iguana_block *block; + bp->bundleheight = height; + if ( bits256_nonz(hash1) != 0 ) + { + if ( (block= iguana_blockhashset("inithash1",coin,height+1,hash1,1)) != 0 ) + { + iguana_bundlehashadd(coin,bp,1,block); + block->mainchain = 1; + } + } + if ( height == 0 && coin->current == 0 ) + coin->current = coin->bundles[0] = bp; + if ( (block= iguana_blockfind("parse",coin,hash2)) != 0 ) + block->mainchain = 1, block->height = height; + if ( iguana_bundleload(coin,&bp->ramchain,bp,2) != 0 ) + { + if ( coin->current != 0 && coin->current->hdrsi+1 == bp->hdrsi ) + coin->current = bp; + bp->emitfinish = (uint32_t)time(NULL) + 1; + //printf("[%d %u] ",bp->hdrsi,bp->emitfinish); + return(0); + } + else + { + init_hexbytes_noT(str,hash2.bytes,sizeof(hash2)); + bp->emitfinish = 0; + iguana_blockQ("init",coin,bp,0,hash2,1); + //printf("init reqhdrs.%d\n",bp->bundleheight); + queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(str),1); + memset(&hash2,0,sizeof(hash2)); + bp->emitfinish = 0; + return(-1); + } +} + void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) { - int32_t j,k,m,c,height,flag,bundlei; char checkstr[1024],line[1024]; - struct iguana_peer *addr; struct iguana_bundle *bp; bits256 allhash,hash2,zero,lastbundle; - struct iguana_block *block; + int32_t j,k,m,c,flag,bundlei,lastheight,height = -1; char checkstr[1024],line[1024]; + struct iguana_peer *addr; struct iguana_bundle *bp; bits256 allhash,hash2,hash1,zero,lastbundle; memset(&zero,0,sizeof(zero)); lastbundle = zero; - if ( iter == 1 ) + if ( coin->MAXPEERS > IGUANA_MAXPEERS ) + coin->MAXPEERS = IGUANA_MAXPEERS; + if ( iter == 1 && 0 ) { int32_t i; FILE *fp; char fname[512]; struct iguana_blockRO blockRO; sprintf(fname,"blocks.%s",coin->symbol), OS_compatible_path(fname); @@ -206,6 +260,7 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) } m = flag = 0; allhash = zero; + memset(line,0,sizeof(line)); while ( fgets(line,sizeof(line),fp) > 0 ) { j = (int32_t)strlen(line) - 1; @@ -213,25 +268,28 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) //printf("parse line.(%s) maxpeers.%d\n",line,coin->MAXPEERS); if ( iter == 0 ) { - if ( m < (2*coin->MAXPEERS)/3 )//&& m < 77.7 ) + if ( m < coin->MAXPEERS-3 )//&& m < 77.7 ) { if ( 0 && m == 0 ) { addr = &coin->peers.active[m++]; iguana_initpeer(coin,addr,(uint32_t)calc_ipbits("127.0.0.1")); - printf("call initpeer.(%s)\n",addr->ipaddr); + //printf("call initpeer.(%s)\n",addr->ipaddr); iguana_launch(coin,"connection",iguana_startconnection,addr,IGUANA_CONNTHREAD); } #ifndef IGUANA_DISABLEPEERS addr = &coin->peers.active[m++]; iguana_initpeer(coin,addr,(uint32_t)calc_ipbits(line)); - printf("call initpeer.(%s)\n",addr->ipaddr); + //printf("call initpeer.(%s)\n",addr->ipaddr); iguana_launch(coin,"connection",iguana_startconnection,addr,IGUANA_CONNTHREAD); #endif } } else { + lastheight = height = -1; + if ( coin->bundlescount > 0 && (bp= coin->bundles[coin->bundlescount - 1]) != 0 ) + lastheight = bp->bundleheight, lastbundle = bp->hashes[0]; for (k=height=0; kchain->bundlesize,&line[k+1+65]);// + strlen(line+k+1)]); if ( line[k] == ' ' ) { decode_hex(hash2.bytes,sizeof(hash2),line+k+1); - if ( line[k+1 + 65] != 0 ) + //printf("line.(%s) k.%d (%c)(%c)(%d)\n",line,k,line[k+63],line[k+64],line[k+65]); + if ( height >= 0 && bits256_nonz(hash2) != 0 ) + { + if ( (bp= iguana_bundlecreate(coin,&bundlei,height,hash2,zero,0)) != 0 ) + { + //printf("created bundle.%d\n",bp->hdrsi); + lastbundle = hash2; + } + } + if ( line[k + 65] != 0 && line[k+65] != '\n' && line[k+65] != '\r' ) { if ( height > (coin->blocks.maxbits - 1000) ) iguana_recvalloc(coin,height + 100000); decode_hex(allhash.bytes,sizeof(allhash),line+k+1 + 64 + 1); init_hexbytes_noT(checkstr,allhash.bytes,sizeof(allhash)); - if ( strcmp(checkstr,line+k+1 + 64 + 1) == 0 ) + //printf("parseline: k.%d %d height.%d m.%d bundlesize.%d (%s) check.(%s)\n",k,line[k],height,m,coin->chain->bundlesize,&line[k+1+65],checkstr);// + strlen(line+k+1)]); + if ( strncmp(checkstr,line+k+1 + 64 + 1,64) == 0 ) { init_hexbytes_noT(checkstr,hash2.bytes,sizeof(hash2)); - //char str[65],str2[65]; printf(">>>> bundle.%d got (%s)/(%s) allhash.(%s)\n",height,bits256_str(str,hash2),checkstr,bits256_str(str2,allhash)); + if ( strlen(line+k+1 + 2*64 + 2) == sizeof(hash1)*2 ) + decode_hex(hash1.bytes,sizeof(hash1),line+k+1 + 2*64 + 2); + else memset(hash1.bytes,0,sizeof(hash1)); + //char str[65],str2[65]; printf(">>>> bundle.%d got (%s)/(%s) allhash.(%s)\n",height,bits256_str(str,hash1),checkstr,bits256_str(str2,allhash)); if ( (bp= iguana_bundlecreate(coin,&bundlei,height,hash2,allhash,0)) != 0 ) { - bp->bundleheight = height; - lastbundle = hash2; - if ( (block= iguana_blockfind(coin,hash2)) != 0 ) - block->mainchain = 1, block->height = height; - if ( iguana_bundleload(coin,bp) != 0 ) + if ( bits256_cmp(allhash,bp->allhash) != 0 ) { - bp->emitfinish = (uint32_t)time(NULL) + 1; - //printf("LOADED bundle.%d\n",bp->bundleheight); + printf("mismatched allhash.[%d]\n",bp->hdrsi); + bp->allhash = allhash; } - else + if ( height >= lastheight ) { - char str[65]; - init_hexbytes_noT(str,hash2.bytes,sizeof(hash2)); - bp->emitfinish = 0; - iguana_blockQ(coin,bp,0,hash2,1); - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(str),1); + if ( iguana_bundleinitmap(coin,bp,height,hash2,hash1) == 0 ) + lastbundle = hash2, lastheight = height; } } } } - /*init_hexbytes_noT(checkstr,hash2.bytes,sizeof(hash2)); - if ( strncmp(checkstr,line+k+1,64) == 0 ) - { - if ( (height % coin->chain->bundlesize) == 1 ) - { - if ( (bp= coin->bundles[height/coin->chain->bundlesize]) != 0 ) - { - if ( iguana_bundlehash2add(coin,0,bp,1,hash2) == 0 ) - { - //printf("add bundle.%d:%d (%s)\n",bundleheight,bp->hdrsi,bits256_str(str,hash2)); - if ( (block= iguana_blockfind(coin,hash2)) != 0 ) - block->mainchain = 1, block->height = bundleheight+1; - } - } - } - }*/ } } + memset(line,0,sizeof(line)); } - if ( bits256_nonz(lastbundle) > 0 ) + if ( iter == 1 && bits256_nonz(lastbundle) != 0 ) { - char hashstr[65]; - init_hexbytes_noT(hashstr,lastbundle.bytes,sizeof(bits256)); - printf("req lastbundle.(%s)\n",hashstr); - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr),1); + printf("parseline ht.%d\n",lastheight); + iguana_initfinal(coin,lastbundle); + } +} + +void iguana_ramchainpurge(struct iguana_info *coin,struct iguana_bundle *bp,struct iguana_ramchain *ramchain) +{ + iguana_ramchain_free(coin,ramchain,1); +} + +void iguana_bundlepurge(struct iguana_info *coin,struct iguana_bundle *bp) +{ + int32_t i; static const bits256 zero; + iguana_ramchainpurge(coin,bp,&bp->ramchain); + if ( bp->speculative != 0 ) + { + for (i=0; in; i++) + if ( bp->speculativecache[i] != 0 ) + { + free(bp->speculativecache[i]); + bp->speculativecache[i] = 0; + } + myfree(bp->speculative,sizeof(*bp->speculative) * bp->numspec); } + bp->numspec = 0; + bp->speculative = 0; + memset(bp->hashes,0,sizeof(bp->hashes)); + memset(bp->issued,0,sizeof(bp->issued)); + bp->prevbundlehash2 = bp->nextbundlehash2 = bp->allhash = zero; +} + +void iguana_blockpurge(struct iguana_info *coin,struct iguana_block *block) +{ + if ( block->req != 0 ) + { + printf("purge req inside block\n"); + myfree(block->req,block->req->allocsize); + } + free(block); +} + +void iguana_blockspurge(struct iguana_info *coin) +{ + struct iguana_block *block,*tmp; + if ( 1 && coin->blocks.hash != 0 ) + { + HASH_ITER(hh,coin->blocks.hash,block,tmp) + { + HASH_DEL(coin->blocks.hash,block); + iguana_blockpurge(coin,block); + } + coin->blocks.hash = 0; + } + if ( coin->blocks.RO != 0 ) + { + myfree(coin->blocks.RO,coin->blocks.maxbits * sizeof(*coin->blocks.RO)); + coin->blocks.RO = 0; + } + coin->blocks.maxbits = coin->blocks.maxblocks = coin->blocks.initblocks = coin->blocks.hashblocks = coin->blocks.issuedblocks = coin->blocks.recvblocks = coin->blocks.emitblocks = coin->blocks.parsedblocks = coin->blocks.dirty = 0; + memset(&coin->blocks.hwmchain,0,sizeof(coin->blocks.hwmchain)); +} + +void iguana_coinpurge(struct iguana_info *coin) +{ + int32_t i,saved; struct iguana_bundle *bp; char *hashstr; struct iguana_bundlereq *req; struct iguana_blockreq *breq; struct iguana_helper *ptr; + saved = coin->active, coin->active = 0; + coin->started = 0; + while ( coin->idletime == 0 && coin->emitbusy > 0 ) + { + printf("coinpurge.%s waiting for idle %lu emitbusy.%d\n",coin->symbol,time(NULL),coin->emitbusy); + sleep(1); + } + coin->RTgenesis = 0; + while ( (ptr= queue_dequeue(&bundlesQ,0)) != 0 ) + myfree(ptr,ptr->allocsize); + if ( 1 ) + { + while ( (hashstr= queue_dequeue(&coin->hdrsQ,1)) != 0 ) + free_queueitem(hashstr); + while ( (breq= queue_dequeue(&coin->blocksQ,0)) != 0 ) + myfree(breq,sizeof(*breq)); + while ( (breq= queue_dequeue(&coin->priorityQ,0)) != 0 ) + myfree(breq,sizeof(*breq)); + while ( (req= queue_dequeue(&coin->cacheQ,0)) != 0 ) + myfree(req,req->allocsize); + while ( (req= queue_dequeue(&coin->recvQ,0)) != 0 ) + { + if ( req->blocks != 0 ) + myfree(req->blocks,sizeof(*req->blocks) * req->n), req->blocks = 0; + if ( req->hashes != 0 ) + myfree(req->hashes,sizeof(*req->hashes) * req->n), req->hashes = 0; + myfree(req,req->allocsize); + } + } + iguana_RTramchainfree(coin,coin->current); + coin->bundlescount = 0; + for (i=0; ibundlescount; i++) + if ( (bp= coin->bundles[i]) != 0 ) + iguana_bundlepurge(coin,bp); + coin->current = coin->lastpending = 0; + memset(coin->bundles,0,sizeof(coin->bundles)); + iguana_blockspurge(coin); + coin->active = saved; } struct iguana_info *iguana_coinstart(struct iguana_info *coin,int32_t initialheight,int32_t mapflags) { - FILE *fp; char fname[512],*symbol; int32_t iter; + FILE *fp; char fname[512],*symbol; int32_t iter; long fpos; bits256 lastbundle; struct supernet_info *myinfo = SuperNET_MYINFO(0); coin->sleeptime = 10000; symbol = coin->symbol; + if ( iguana_peerslotinit(coin,&coin->internaladdr,IGUANA_MAXPEERS,calc_ipbits("127.0.0.1:7777")) < 0 ) + { + printf("iguana_coinstart: error creating peerslot\n"); + return(0); + } if ( initialheight < coin->chain->bundlesize*10 ) initialheight = coin->chain->bundlesize*10; iguana_recvalloc(coin,initialheight); - coin->longestchain = 1; + if ( coin->longestchain == 0 ) + coin->longestchain = 1; + memset(&coin->blocks.hwmchain,0,sizeof(coin->blocks.hwmchain)); coin->blocks.hwmchain.height = 0; + printf("%s MYSERVICES.%llx\n",coin->symbol,(long long)coin->myservices); if ( (coin->myservices & NODE_NETWORK) != 0 ) { - printf("MYSERVICES.%llx\n",(long long)coin->myservices); - coin->peers.acceptloop = malloc(sizeof(pthread_t)); - if ( OS_thread_create(coin->peers.acceptloop,NULL,(void *)iguana_acceptloop,(void *)coin) != 0 ) + if ( coin->peers.acceptloop == 0 && coin->peers.localaddr == 0 ) { - free(coin->peers.acceptloop); - coin->peers.acceptloop = 0; - printf("error launching accept thread for port.%u\n",coin->chain->portp2p); + coin->peers.acceptloop = malloc(sizeof(pthread_t)); + if ( OS_thread_create(coin->peers.acceptloop,NULL,(void *)iguana_acceptloop,(void *)coin) != 0 ) + { + free(coin->peers.acceptloop); + coin->peers.acceptloop = 0; + printf("error launching accept thread for port.%u\n",coin->chain->portp2p); + } } } - coin->firstblock = coin->blocks.parsedblocks + 1; + if ( (coin->myservices & 0x80) == 0x80 && coin->rpcloop == 0 ) + { + myinfo->argport = coin->chain->rpcport; + coin->rpcloop = malloc(sizeof(pthread_t)); + if ( OS_thread_create(coin->rpcloop,NULL,(void *)iguana_rpcloop,(void *)myinfo) != 0 ) + { + free(coin->rpcloop); + coin->rpcloop = 0; + printf("error launching rpcloop for %s port.%u\n",coin->symbol,coin->chain->rpcport); + } + } + //coin->firstblock = coin->blocks.parsedblocks + 1; iguana_genesis(coin,coin->chain); - for (iter=0; iter<2; iter++) + memset(&lastbundle,0,sizeof(lastbundle)); + for (iter=coin->peers.numranked>8; iter<2; iter++) { - sprintf(fname,"confs/%s_%s.txt",coin->symbol,(iter == 0) ? "peers" : "hdrs"); +#ifdef __PNACL__ + if ( iter == 0 ) + { + char **ipaddrs = 0; int32_t j,num; + char *BTC_ipaddrs[] = { "5.9.102.210", "130.211.146.81", "1176.9.29.76", "108.58.252.82", "148.251.151.48", "74.207.233.193" }; + char *BTCD_ipaddrs[] = { "5.9.102.210", "89.248.160.236", "89.248.160.237", "89.248.160.238", "89.248.160.239", "89.248.160.240", "89.248.160.241", "89.248.160.242", "89.248.160.243", "89.248.160.244", "89.248.160.245", "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" }; + if ( strcmp(coin->symbol,"BTCD") == 0 ) + ipaddrs = BTCD_ipaddrs, num = (int32_t)(sizeof(BTCD_ipaddrs)/sizeof(*BTCD_ipaddrs)); + else if ( strcmp(coin->symbol,"BTC") == 0 ) + ipaddrs = BTC_ipaddrs, num = (int32_t)(sizeof(BTC_ipaddrs)/sizeof(*BTC_ipaddrs)); + if ( ipaddrs != 0 ) + { + for (j=0; jsymbol,"BTCD") == 0 ) + { + bits256 hash2,allhash,hash1; int32_t bundlei,i,nonz,height; struct iguana_bundle *bp; + for (i=nonz=0; i (coin->blocks.maxbits - 1000) ) + iguana_recvalloc(coin,height + 100000); + hash2 = bits256_conv(BTCD_hdrs[i][1]); + if ( BTCD_hdrs[i][2][0] != 0 ) + allhash = bits256_conv(BTCD_hdrs[i][2]); + if ( BTCD_hdrs[i][3][0] != 0 ) + hash1 = bits256_conv(BTCD_hdrs[i][3]); + if ( (bp= iguana_bundlecreate(coin,&bundlei,height,hash2,allhash,0)) != 0 ) + { + if ( iguana_bundleinitmap(coin,bp,height,hash2,hash1) == 0 ) + lastbundle = hash2, nonz++; + } + } + printf("H file.[%d] nonz.%d\n",i,nonz); + //if ( bits256_nonz(lastbundle) != 0 ) + // iguana_initfinal(coin,lastbundle); + //break; + } + } +#endif + sprintf(fname,"%s/%s_%s.txt",GLOBAL_CONFSDIR,coin->symbol,(iter == 0) ? "peers" : "hdrs"), OS_compatible_path(fname); + //sprintf(fname,"confs/%s_%s.txt",coin->symbol,(iter == 0) ? "peers" : "hdrs"); + //sprintf(fname,"tmp/%s/%s.txt",coin->symbol,(iter == 0) ? "peers" : "hdrs"); OS_compatible_path(fname); printf("parsefile.%d %s\n",iter,fname); if ( (fp= fopen(fname,"r")) != 0 ) { iguana_parseline(coin,iter,fp); + fpos = ftell(fp); fclose(fp); - } - printf("done parsefile.%d\n",iter); + } else fpos = -1; + printf("done parsefile.%d (%s) size.%ld\n",iter,fname,fpos); } #ifndef IGUANA_DEDICATED_THREADS coin->peers.peersloop = iguana_launch("peersloop",iguana_peersloop,coin,IGUANA_PERMTHREAD); #endif - if ( 0 && (coin->MAXBUNDLES= coin->bundlescount / 4) < _IGUANA_MAXBUNDLES ) - coin->MAXBUNDLES = _IGUANA_MAXBUNDLES; - printf("started.%s\n",coin->symbol); + printf("started.%s %p active.%d\n",coin->symbol,coin->started,coin->active); return(coin); } diff --git a/iguana/iguana_instantdex.c b/iguana/iguana_instantdex.c index 0c1932799..d1a579cf8 100755 --- a/iguana/iguana_instantdex.c +++ b/iguana/iguana_instantdex.c @@ -17,8 +17,205 @@ #include "exchanges777.h" -#define INSTANTDEX_HOPS 3 -#define INSTANTDEX_DURATION 60 +struct instantdex_stateinfo *BTC_states; int32_t BTC_numstates; + +int64_t instantdex_BTCsatoshis(int64_t price,int64_t volume) +{ + if ( volume > price ) + return(price * dstr(volume)); + else return(dstr(price) * volume); +} + +int64_t instantdex_insurance(struct iguana_info *coin,int64_t amount) +{ + return(amount * INSTANTDEX_INSURANCERATE + coin->chain->txfee); // insurance prevents attack +} + +void instantdex_swapfree(struct instantdex_accept *A,struct bitcoin_swapinfo *swap) +{ + if ( A != 0 ) + free(A); + if ( swap != 0 ) + { + if ( swap->deposit != 0 ) + free(swap->deposit); + if ( swap->payment != 0 ) + free(swap->payment); + if ( swap->altpayment != 0 ) + free(swap->altpayment); + if ( swap->myfee != 0 ) + free(swap->myfee); + if ( swap->otherfee != 0 ) + free(swap->otherfee); + } +} + +cJSON *instantdex_defaultprocess(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) +{ + uint8_t *serdata = *serdatap; int32_t serdatalen = *serdatalenp; + *serdatap = 0, *serdatalenp = 0; + if ( serdata != 0 && serdatalen > 0 ) + { + serdata[serdatalen-1] = 0; + } + return(newjson); +} + +cJSON *instantdex_defaulttimeout(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) +{ + uint8_t *serdata = *serdatap; int32_t serdatalen = *serdatalenp; + *serdatap = 0, *serdatalenp = 0; + if ( serdata != 0 && serdatalen > 0 ) + { + serdata[serdatalen-1] = 0; + } + return(newjson); +} + +struct instantdex_stateinfo instantdex_errorstate = { "error", 0,0, instantdex_defaultprocess, instantdex_defaulttimeout }; +struct instantdex_stateinfo instantdex_timeoutstate = { "timeout", 1,0, instantdex_defaultprocess, instantdex_defaulttimeout }; + +struct instantdex_stateinfo *instantdex_statefind(struct instantdex_stateinfo *states,int32_t numstates,char *statename) +{ + int32_t i; struct instantdex_stateinfo *state = 0; + if ( states != 0 && statename != 0 && numstates > 0 ) + { + for (i=0; iname,statename) == 0 ) + return(state); + } + } + return(0); +} + +void instantdex_stateinit(struct instantdex_stateinfo *states,int32_t numstates,struct instantdex_stateinfo *state,char *name,char *errorstr,char *timeoutstr,void *process_func,void *timeout_func) +{ + struct instantdex_stateinfo *timeoutstate,*errorstate; + memset(state,0,sizeof(*state)); + strcpy(state->name,name); + if ( (errorstate= instantdex_statefind(states,numstates,errorstr)) == 0 ) + errorstate = &instantdex_errorstate; + state->errorind = errorstate->ind; + if ( (timeoutstate= instantdex_statefind(states,numstates,timeoutstr)) == 0 ) + timeoutstate = &instantdex_timeoutstate; + else printf("TS.%s ",timeoutstr); + state->timeoutind = timeoutstate->ind; + if ( (state->process= process_func) == 0 ) + state->process = instantdex_defaultprocess; + if ( (state->timeout= timeout_func) == 0 ) + state->timeout = instantdex_defaulttimeout; +} + +struct instantdex_stateinfo *instantdex_statecreate(struct instantdex_stateinfo *states,int32_t *numstatesp,char *name,cJSON *(*process_func)(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp),cJSON *(*timeout_func)(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp),char *timeoutstr,char *errorstr,int32_t initialstate) +{ + struct instantdex_stateinfo S,*state = 0; + if ( (state= instantdex_statefind(states,*numstatesp,name)) == 0 ) + { + states = realloc(states,sizeof(*states) * (*numstatesp + 1)); + state = &states[*numstatesp]; + instantdex_stateinit(states,*numstatesp,state,name,errorstr,timeoutstr,process_func,timeout_func); + state->initialstate = initialstate; + printf("STATES[%d] %s %p %p %d %d\n",*numstatesp,state->name,state->process,state->timeout,state->timeoutind,state->errorind); + state->ind = (*numstatesp)++; + } + else + { + instantdex_stateinit(states,*numstatesp,&S,name,errorstr,timeoutstr,process_func,timeout_func); + S.ind = state->ind; + S.initialstate = initialstate; + if ( memcmp(&S,state,sizeof(S) - sizeof(void *) - sizeof(int)) != 0 ) + { + int32_t i; + for (i=0; iname,state->process,state->timeout,state->timeoutind,state->errorind,S.name,S.process,S.timeout,S.timeoutind,S.errorind); + printf("statecreate error!!! (%s) already exists\n",name); + } + } + return(states); +} + +struct instantdex_event *instantdex_addevent(struct instantdex_stateinfo *states,int32_t numstates,char *statename,char *cmdstr,char *sendcmd,char *nextstatename) +{ + struct instantdex_stateinfo *nextstate,*state; + if ( (state= instantdex_statefind(states,numstates,statename)) != 0 && (nextstate= instantdex_statefind(states,numstates,nextstatename)) != 0 ) + { + if ( (state->events= realloc(state->events,(state->numevents + 1) * sizeof(*state->events))) != 0 ) + { + memset(&state->events[state->numevents],0,sizeof(state->events[state->numevents])); + strcpy(state->events[state->numevents].cmdstr,cmdstr); + if ( sendcmd != 0 ) + strcpy(state->events[state->numevents].sendcmd,sendcmd); + state->events[state->numevents].nextstateind = nextstate->ind; + state->numevents++; + } + return(state->events); + } + else + { + int32_t i; + for (i=0; i %s) without existing state and nextstate\n",statename,nextstatename); + exit(-1); + return(0); + } +} + +double instantdex_FSMtest(struct instantdex_stateinfo *states,int32_t numstates,int32_t maxiters) +{ + int32_t i,most,r,r2,n,m=0,initials[100],nextstate=-1; + struct instantdex_stateinfo *state; struct instantdex_event *event; double sum = 0.; + if ( maxiters < 1 ) + maxiters = 1; + for (i=n=most=0; i 0 ) + { + printf("initialstate[%d] %d %s\n",i,states[i].initialstate,states[i].name); + initials[n++] = i; + } + if ( n > 0 && n < sizeof(initials)/sizeof(*initials) ) + { + for (i=0; iname[0] == 0 || state->ind >= numstates ) + { + printf("illegal state.(%s) %d? ind.%d >= numstates.%d\n",state->name,nextstate,state->ind,numstates); + break; + } + m = 0; + while ( m++ < 1000 && state->initialstate >= 0 && state->numevents != 0 ) + { + if ( (i % 1000000) == 0 ) + fprintf(stderr,"%s ",state->name); + r2 = rand() % state->numevents; + event = &state->events[r2]; + if ( (nextstate= event->nextstateind) < 0 ) + break; + if ( event->nextstateind >= numstates ) + { + printf("nextstateind overflow? %d vs %d\n",event->nextstateind,numstates); + break; + } + state = &states[event->nextstateind]; + } + if ( m > most ) + most = m; + sum += m; + if ( (i % 1000000) == 0 ) + fprintf(stderr,"reached %s m.%d events most.%d ave %.2f\n",state->name,m,most,sum/(i+1)); + } + } + fprintf(stderr," most.%d ave %.2f\n",most,sum/(i+1)); + return(sum / maxiters); +} cJSON *InstantDEX_argjson(char *reference,char *message,char *othercoinaddr,char *otherNXTaddr,int32_t iter,int32_t val,int32_t val2) { @@ -50,12 +247,6 @@ cJSON *InstantDEX_argjson(char *reference,char *message,char *othercoinaddr,char return(argjson); } -int32_t instantdex_rwdata(int32_t rwflag,uint64_t cmdbits,uint8_t *data,int32_t datalen) -{ - // need to inplace serialize/deserialize here - return(datalen); -} - struct instantdex_msghdr *instantdex_msgcreate(struct supernet_info *myinfo,struct instantdex_msghdr *msg,int32_t datalen) { bits256 otherpubkey; uint64_t signerbits; uint32_t timestamp; uint8_t buf[sizeof(msg->sig)],*data; @@ -65,6 +256,7 @@ struct instantdex_msghdr *instantdex_msgcreate(struct supernet_info *myinfo,stru otherpubkey = acct777_msgpubkey(data,datalen); timestamp = (uint32_t)time(NULL); acct777_sign(&msg->sig,myinfo->privkey,otherpubkey,timestamp,data,datalen); + //printf("signed datalen.%d allocsize.%d crc.%x\n",datalen,msg->sig.allocsize,calc_crc32(0,data,datalen)); if ( (signerbits= acct777_validate(&msg->sig,acct777_msgprivkey(data,datalen),msg->sig.pubkey)) != 0 ) { //int32_t i; @@ -80,39 +272,104 @@ struct instantdex_msghdr *instantdex_msgcreate(struct supernet_info *myinfo,stru return(0); } -char *instantdex_sendcmd(struct supernet_info *myinfo,cJSON *argjson,char *cmdstr,char *ipaddr,int32_t hops) +bits256 instantdex_rwoffer(int32_t rwflag,int32_t *lenp,uint8_t *serialized,struct instantdex_offer *offer) +{ + bits256 orderhash; int32_t len = 0; + if ( rwflag == 1 ) + { + vcalc_sha256(0,orderhash.bytes,(void *)offer,sizeof(*offer)); + /*int32_t i; + for (i=0; ibase),offer->base); + len += iguana_rwstr(rwflag,&serialized[len],sizeof(offer->rel),offer->rel); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(offer->price64),&offer->price64); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(offer->basevolume64),&offer->basevolume64); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(offer->offer64),&offer->offer64); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(offer->expiration),&offer->expiration); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(offer->nonce),&offer->nonce); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(offer->myside),&offer->myside); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(offer->acceptdir),&offer->acceptdir); + if ( rwflag == 0 ) + { + vcalc_sha256(0,orderhash.bytes,(void *)offer,sizeof(*offer)); + /*int32_t i; + for (i=0; icmd); i++) - if ( (msg->cmd[i]= cmdstr[i]) == 0 ) - break; jaddstr(argjson,"agent","SuperNET"); jaddstr(argjson,"method","DHT"); - jaddstr(argjson,"traderip",ipaddr); + jaddstr(argjson,"handle",myinfo->handle); jaddbits256(argjson,"categoryhash",instantdexhash); jaddbits256(argjson,"traderpub",myinfo->myaddr.persistent); + orderhash = instantdex_rwoffer(1,&olen,serialized,offer); + if ( 1 ) + { + struct instantdex_offer checkoffer; bits256 checkhash; int32_t checklen; + checkhash = instantdex_rwoffer(0,&checklen,serialized,&checkoffer); + if ( checkhash.txid != orderhash.txid ) + { + for (i=0; imyaddr.persistent); - reqstr = jprint(argjson,1); - datalen = (int32_t)(strlen(reqstr) + 1); - memcpy(msg->serialized,reqstr,datalen); + reqstr = jprint(argjson,0); + slen = (int32_t)(strlen(reqstr) + 1); + datalen = (int32_t)slen + extralen + olen; + msg = calloc(1,datalen + sizeof(*msg)); + for (i=0; icmd); i++) + if ( (msg->cmd[i]= cmdstr[i]) == 0 ) + break; + memcpy(msg->serialized,reqstr,slen); + memcpy(&msg->serialized[slen],serialized,olen); + //printf("extralen.%d datalen.%d slen.%d olen.%d\n",extralen,datalen,slen,olen); + if ( extralen > 0 ) + memcpy(&msg->serialized[slen + olen],extraser,extralen); free(reqstr); - if ( (datalen+sizeof(*msg))*2+1 < sizeof(hexstr) && instantdex_msgcreate(myinfo,msg,datalen) != 0 ) + if ( instantdex_msgcreate(myinfo,msg,datalen) != 0 ) { - printf("instantdex send.(%s)\n",cmdstr); + printf(">>>>>>>>>>>> instantdex send.(%s) datalen.%d allocsize.%d crc.%x\n",cmdstr,datalen,msg->sig.allocsize,calc_crc32(0,(void *)((long)msg + 8),datalen-8)); + hexstr = malloc(msg->sig.allocsize*2 + 1); init_hexbytes_noT(hexstr,(uint8_t *)msg,msg->sig.allocsize); - return(SuperNET_categorymulticast(myinfo,0,instantdexhash,GENESIS_PUBKEY,hexstr,0,hops,1)); + retstr = SuperNET_categorymulticast(myinfo,0,instantdexhash,desthash,hexstr,0,hops,1,argjson,0); + free_json(argjson), free(hexstr), free(msg); + return(retstr); } else { - printf("cant msgcreate\n"); + free_json(argjson), free(msg); + printf("cant msgcreate datalen.%d\n",datalen); return(clonestr("{\"error\":\"couldnt create instantdex message\"}")); } } @@ -138,17 +395,17 @@ int32_t instantdex_updatesources(struct exchange_info *exchange,struct exchange_ return(n); } -double instantdex_aveprice(struct supernet_info *myinfo,struct exchange_quote *sortbuf,int32_t max,double *totalvolp,char *base,char *rel,double relvolume,cJSON *argjson) +double instantdex_aveprice(struct supernet_info *myinfo,struct exchange_quote *sortbuf,int32_t max,double *totalvolp,char *base,char *rel,double basevolume,cJSON *argjson) { char *str; double totalvol,pricesum; uint32_t timestamp; struct exchange_quote quote; int32_t i,n,dir,num,depth = 100; struct exchange_info *exchange; struct exchange_request *req,*active[64]; timestamp = (uint32_t)time(NULL); - if ( relvolume < 0. ) - relvolume = -relvolume, dir = -1; + if ( basevolume < 0. ) + basevolume = -basevolume, dir = -1; else dir = 1; memset(sortbuf,0,sizeof(*sortbuf) * max); - if ( base != 0 && rel != 0 && relvolume > SMALLVAL ) + if ( base != 0 && rel != 0 && basevolume > SMALLVAL ) { for (i=num=0; inumexchanges && num < sizeof(active)/sizeof(*active); i++) { @@ -183,7 +440,7 @@ double instantdex_aveprice(struct supernet_info *myinfo,struct exchange_quote *s if ( dir < 0 ) revsort64s(&sortbuf[0].satoshis,n,sizeof(*sortbuf)); else sort64s(&sortbuf[0].satoshis,n,sizeof(*sortbuf)); - for (totalvol=pricesum=i=0; iexchange->name,pricesum/totalvol,totalvol); + printf("i.%d of %d %12.8f vol %.8f %s | aveprice %.8f total vol %.8f\n",i,n,sortbuf[i].price,quote.volume,active[quote.val]->exchange->name,pricesum/totalvol,totalvol); } } if ( totalvol > 0. ) @@ -204,101 +461,302 @@ double instantdex_aveprice(struct supernet_info *myinfo,struct exchange_quote *s return(0); } -int32_t instantdex_bidaskdir(struct instantdex_accept *ap) +double instantdex_avehbla(struct supernet_info *myinfo,double retvals[4],char *base,char *rel,double basevolume) +{ + double avebid,aveask,bidvol,askvol; struct exchange_quote sortbuf[256]; cJSON *argjson; + argjson = cJSON_CreateObject(); + aveask = instantdex_aveprice(myinfo,sortbuf,sizeof(sortbuf)/sizeof(*sortbuf),&askvol,base,rel,basevolume,argjson); + avebid = instantdex_aveprice(myinfo,sortbuf,sizeof(sortbuf)/sizeof(*sortbuf),&bidvol,base,rel,-basevolume,argjson); + free_json(argjson); + retvals[0] = avebid, retvals[1] = bidvol, retvals[2] = aveask, retvals[3] = askvol; + if ( avebid > SMALLVAL && aveask > SMALLVAL ) + return((avebid + aveask) * .5); + else return(0); +} + +int32_t instantdex_bidaskdir(struct instantdex_offer *offer) { - if ( ap->A.myside == 0 && ap->A.acceptdir > 0 ) // base + if ( offer->myside == 0 && offer->acceptdir > 0 ) // base return(-1); - else if ( ap->A.myside == 1 && ap->A.acceptdir < 0 ) // rel + else if ( offer->myside == 1 && offer->acceptdir < 0 ) // rel return(1); else return(0); } -cJSON *instantdex_acceptjson(struct instantdex_accept *ap) +cJSON *instantdex_offerjson(struct instantdex_offer *offer,uint64_t orderid) { - int32_t dir; - cJSON *item = cJSON_CreateObject(); - jadd64bits(item,"orderid",ap->orderid); - jadd64bits(item,"offerer",ap->A.offer64); - if ( ap->dead != 0 ) - jadd64bits(item,"dead",ap->dead); - if ( (dir= instantdex_bidaskdir(ap)) > 0 ) + int32_t dir; cJSON *item = cJSON_CreateObject(); + jadd64bits(item,"orderid",orderid); + jadd64bits(item,"offerer",offer->offer64); + if ( (dir= instantdex_bidaskdir(offer)) > 0 ) jaddstr(item,"type","bid"); else if ( dir < 0 ) jaddstr(item,"type","ask"); else { jaddstr(item,"type","strange"); - jaddnum(item,"acceptdir",ap->A.acceptdir); - jaddnum(item,"myside",ap->A.myside); - } - jaddstr(item,"base",ap->A.base); - jaddstr(item,"rel",ap->A.rel); - jaddnum(item,"timestamp",ap->A.expiration); - jaddnum(item,"price",dstr(ap->A.price64)); - jaddnum(item,"volume",dstr(ap->A.basevolume64)); - jaddnum(item,"nonce",ap->A.nonce); + jaddnum(item,"acceptdir",offer->acceptdir); + jaddnum(item,"myside",offer->myside); + } + jaddstr(item,"base",offer->base); + jaddstr(item,"rel",offer->rel); + jaddnum(item,"timestamp",offer->expiration); + jaddnum(item,"price",dstr(offer->price64)); + jaddnum(item,"volume",dstr(offer->basevolume64)); + jaddnum(item,"minperc",offer->minperc); + jaddnum(item,"nonce",offer->nonce); + jaddnum(item,"expiresin",offer->expiration - time(NULL)); + return(item); +} + +cJSON *instantdex_acceptjson(struct instantdex_accept *ap) +{ + cJSON *item = cJSON_CreateObject(); + jadd64bits(item,"orderid",ap->orderid); jaddnum(item,"pendingvolume",dstr(ap->pendingvolume64)); - jaddnum(item,"expiresin",ap->A.expiration - time(NULL)); + if ( ap->dead != 0 ) + jadd64bits(item,"dead",ap->dead); + jadd(item,"offer",instantdex_offerjson(&ap->offer,ap->orderid)); return(item); } -struct instantdex_accept *instantdex_acceptablefind(struct exchange_info *exchange,cJSON *bids,cJSON *asks,uint64_t orderid,char *base,char *rel) +void instantdex_statetxjson(cJSON *array,char *name,struct bitcoin_statetx *tx) +{ + cJSON *item; + if ( tx != 0 ) + { + item = cJSON_CreateObject(); + jaddbits256(item,"txid",tx->txid); + jaddnum(item,"inputsum",dstr(tx->inputsum)); + jaddnum(item,"amount",dstr(tx->amount)); + jaddnum(item,"change",dstr(tx->change)); + jaddnum(item,"txfee",dstr(tx->inputsum) - dstr(tx->amount) - dstr(tx->change)); + jaddnum(item,"confirms",dstr(tx->numconfirms)); + jaddstr(item,"destaddr",tx->destaddr); + jaddstr(item,"txbytes",tx->txbytes); + jadd(array,name,item); + } +} + +cJSON *instantdex_statemachinejson(struct bitcoin_swapinfo *swap) +{ + cJSON *retjson,*txs; int32_t isbob,mydir,otherdir; + retjson = cJSON_CreateObject(); + if ( swap != 0 ) + { + mydir = instantdex_bidaskdir(&swap->mine.offer); + otherdir = instantdex_bidaskdir(&swap->other.offer); + isbob = instantdex_isbob(swap); + jaddnum(retjson,"isbob",isbob); + jaddnum(retjson,"mydir",mydir); + jaddnum(retjson,"otherdir",otherdir); + jaddnum(retjson,"expiration",swap->expiration); + jaddnum(retjson,"insurance",dstr(swap->insurance)); + jaddnum(retjson,"baseamount",dstr(swap->altsatoshis)); + jaddnum(retjson,"BTCamount",dstr(swap->BTCsatoshis)); + jaddnum(retjson,"expiration",swap->expiration); + if ( swap->dead != 0 ) + jadd64bits(retjson,"dead",swap->dead); + jaddbits256(retjson,"privAm",swap->privAm); + jaddbits256(retjson,"pubAm",swap->pubAm); + jaddbits256(retjson,"privBn",swap->privBn); + jaddbits256(retjson,"pubBn",swap->pubBn); + + jaddbits256(retjson,"myorderhash",swap->myorderhash); + jaddnum(retjson,"choosei",swap->choosei); + jaddnum(retjson,"cutverified",swap->cutverified); + jaddbits256(retjson,"othertrader",swap->othertrader); + jaddbits256(retjson,"otherorderhash",swap->otherorderhash); + jaddnum(retjson,"otherchoosei",swap->otherchoosei); + jaddnum(retjson,"otherverifiedcut",swap->otherverifiedcut); + if ( isbob == 0 ) + { + jaddbits256(retjson,"pubA0",swap->mypubs[0]); + jaddbits256(retjson,"pubA1",swap->mypubs[1]); + jaddbits256(retjson,"pubB0",swap->otherpubs[0]); + jaddbits256(retjson,"pubB1",swap->otherpubs[1]); + } + else + { + jaddbits256(retjson,"pubB0",swap->mypubs[0]); + jaddbits256(retjson,"pubB1",swap->mypubs[1]); + jaddbits256(retjson,"pubA0",swap->otherpubs[0]); + jaddbits256(retjson,"pubA1",swap->otherpubs[1]); + } + if ( mydir > 0 && otherdir < 0 ) + { + jadd64bits(retjson,"bidid",swap->mine.orderid); + jadd64bits(retjson,"askid",swap->other.orderid); + } + else if ( mydir < 0 && otherdir > 0 ) + { + jadd64bits(retjson,"askid",swap->mine.orderid); + jadd64bits(retjson,"bidid",swap->other.orderid); + } + if ( swap->matched64 == swap->mine.orderid ) + { + jadd(retjson,"initiator",instantdex_acceptjson(&swap->other)); + jadd(retjson,"matched",instantdex_acceptjson(&swap->mine)); + } + else if ( swap->matched64 == swap->other.orderid ) + { + jadd(retjson,"initiator",instantdex_acceptjson(&swap->mine)); + jadd(retjson,"matched",instantdex_acceptjson(&swap->other)); + } + else jaddstr(retjson,"initiator","illegal initiator missing"); + if ( swap->state != 0 ) + jaddstr(retjson,"state",swap->state->name); + txs = cJSON_CreateObject(); + instantdex_statetxjson(txs,"deposit",swap->deposit); + instantdex_statetxjson(txs,"payment",swap->payment); + instantdex_statetxjson(txs,"altpayment",swap->altpayment); + instantdex_statetxjson(txs,"myfee",swap->myfee); + instantdex_statetxjson(txs,"otherfee",swap->otherfee); + jadd(retjson,"txs",txs); + jaddstr(retjson,"status",swap->status); + } + return(retjson); +} + +cJSON *instantdex_historyjson(struct bitcoin_swapinfo *swap) +{ + // need to make sure accepts are put onto history queue when they are completed or deaded + // also to make permanent copy (somewhere) + return(instantdex_statemachinejson(swap)); +} + +struct bitcoin_swapinfo *instantdex_historyfind(struct supernet_info *myinfo,struct exchange_info *exchange,uint64_t orderid) { - struct instantdex_accept PAD,*ap,*retap = 0; uint32_t now; cJSON *item; char *type; + struct bitcoin_swapinfo PAD,*swap,*retswap = 0; uint32_t now; + now = (uint32_t)time(NULL); + memset(&PAD,0,sizeof(PAD)); + queue_enqueue("historyQ",&exchange->historyQ,&PAD.DL,0); + while ( (swap= queue_dequeue(&exchange->historyQ,0)) != 0 && swap != &PAD ) + { + if ( orderid == swap->mine.orderid ) + retswap = swap; + queue_enqueue("historyQ",&exchange->historyQ,&swap->DL,0); + } + return(retswap); +} + +struct bitcoin_swapinfo *instantdex_statemachinefind(struct supernet_info *myinfo,struct exchange_info *exchange,uint64_t orderid,int32_t requeueflag) +{ + struct bitcoin_swapinfo PAD,*swap,*retswap = 0; uint32_t now; + now = (uint32_t)time(NULL); + memset(&PAD,0,sizeof(PAD)); + queue_enqueue("statemachineQ",&exchange->statemachineQ,&PAD.DL,0); + while ( (swap= queue_dequeue(&exchange->statemachineQ,0)) != 0 && swap != &PAD ) + { + if ( now < swap->expiration && swap->mine.dead == 0 && swap->other.dead == 0 ) + { + if ( orderid == swap->mine.orderid || orderid == swap->other.orderid ) + { + if ( retswap != 0 && requeueflag == 0 ) + queue_enqueue("statemachineQ",&exchange->statemachineQ,&retswap->DL,0); + retswap = swap; + } + } + else + { + strcpy(swap->status,"expired"); + printf("expired pending, need to take action, send timeout event\n"); + queue_enqueue("historyQ",&exchange->historyQ,&swap->DL,0); + continue; + } + if ( swap != retswap || requeueflag != 0 ) + queue_enqueue("statemachineQ",&exchange->statemachineQ,&swap->DL,0); + } + //printf("found statemachine.%p\n",retswap); + return(retswap); +} + +struct instantdex_accept *instantdex_offerfind(struct supernet_info *myinfo,struct exchange_info *exchange,cJSON *bids,cJSON *asks,uint64_t orderid,char *base,char *rel,int32_t requeue) +{ + struct instantdex_accept PAD,*ap,*retap = 0; uint32_t now; cJSON *item,*offerobj; char *type; now = (uint32_t)time(NULL); memset(&PAD,0,sizeof(PAD)); queue_enqueue("acceptableQ",&exchange->acceptableQ,&PAD.DL,0); while ( (ap= queue_dequeue(&exchange->acceptableQ,0)) != 0 && ap != &PAD ) { - if ( now < ap->A.expiration && ap->dead == 0 ) + if ( now < ap->offer.expiration && ap->dead == 0 ) { - if ( (strcmp(base,"*") == 0 || strcmp(base,ap->A.base) == 0) && (strcmp(rel,"*") == 0 || strcmp(rel,ap->A.rel) == 0) && (orderid == 0 || orderid == ap->orderid) ) + //printf("%d %d find cmps %d %d %d %d %d %d me.%llu vs %llu o.%llu | vs %llu\n",instantdex_bidaskdir(&ap->offer),ap->offer.expiration-now,strcmp(base,"*") == 0,strcmp(base,ap->offer.base) == 0,strcmp(rel,"*") == 0,strcmp(rel,ap->offer.rel) == 0,orderid == 0,orderid == ap->orderid,(long long)myinfo->myaddr.nxt64bits,(long long)ap->offer.offer64,(long long)ap->orderid,(long long)orderid); + if ( (strcmp(base,"*") == 0 || strcmp(base,ap->offer.base) == 0) && (strcmp(rel,"*") == 0 || strcmp(rel,ap->offer.rel) == 0) && (orderid == 0 || orderid == ap->orderid) ) { + if ( requeue == 0 && retap != 0 ) + queue_enqueue("acceptableQ",&exchange->acceptableQ,&retap->DL,0); retap = ap; } if ( (item= instantdex_acceptjson(ap)) != 0 ) { //printf("item.(%s)\n",jprint(item,0)); - if ( (type= jstr(item,"type")) != 0 ) + if ( (offerobj= jobj(item,"offer")) != 0 && (type= jstr(offerobj,"type")) != 0 ) { if ( strcmp(type,"bid") == 0 && bids != 0 ) - jaddi(bids,item); + jaddi(bids,jduplicate(offerobj)); else if ( strcmp(type,"ask") == 0 && asks != 0 ) - jaddi(asks,item); + jaddi(asks,jduplicate(offerobj)); } + free_json(item); + } else printf("error generating acceptjson.%llu\n",(long long)ap->orderid); + if ( ap != retap || requeue != 0 ) + { + //printf("requeue.%p\n",ap); + queue_enqueue("acceptableQ",&exchange->acceptableQ,&ap->DL,0); } - queue_enqueue("acceptableQ",&exchange->acceptableQ,&ap->DL,0); } else free(ap); } return(retap); } -struct instantdex_accept *instantdex_acceptable(struct exchange_info *exchange,struct instantdex_accept *A,uint64_t offerbits) +struct instantdex_accept *instantdex_acceptable(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,double minperc) { - struct instantdex_accept PAD,*ap,*retap = 0; uint64_t bestprice64 = 0; - uint32_t now; int32_t offerdir; + struct instantdex_accept PAD,*ap,*retap = 0; double aveprice;//,retvals[4]; + uint64_t minvol,bestprice64 = 0; uint32_t now; int32_t offerdir; + aveprice = 0;//instantdex_avehbla(myinfo,retvals,A->offer.base,A->offer.rel,dstr(A->offer.basevolume64)); now = (uint32_t)time(NULL); memset(&PAD,0,sizeof(PAD)); queue_enqueue("acceptableQ",&exchange->acceptableQ,&PAD.DL,0); - offerdir = instantdex_bidaskdir(A); + offerdir = instantdex_bidaskdir(&A->offer); + minvol = (A->offer.basevolume64 * minperc * .01); + printf("offerdir.%d (%s/%s) minperc %.3f minvol %.8f vs %.8f\n",offerdir,A->offer.base,A->offer.rel,minperc,dstr(minvol),dstr(A->offer.basevolume64)); while ( (ap= queue_dequeue(&exchange->acceptableQ,0)) != 0 && ap != &PAD ) { - if ( now < ap->A.expiration && ap->dead == 0 ) + if ( now > ap->offer.expiration || ap->dead != 0 || A->offer.offer64 == ap->offer.offer64 ) + { + //printf("now.%u skip expired %u/dead.%u or my order orderid.%llu from %llu\n",now,ap->offer.expiration,ap->dead,(long long)ap->orderid,(long long)ap->offer.offer64); + } + else if ( strcmp(ap->offer.base,A->offer.base) != 0 || strcmp(ap->offer.rel,A->offer.rel) != 0 ) + { + //printf("skip mismatched.(%s/%s) orderid.%llu from %llu\n",ap->offer.base,ap->offer.rel,(long long)ap->orderid,(long long)ap->offer.offer64); + } + else if ( offerdir*instantdex_bidaskdir(&ap->offer) > 0 ) + { + //printf("skip same direction %d orderid.%llu from %llu\n",instantdex_bidaskdir(&ap->offer),(long long)ap->orderid,(long long)ap->offer.offer64); + } + else if ( minvol > ap->offer.basevolume64 - ap->pendingvolume64 ) + { + //printf("skip too small order %.8f vs %.8f orderid.%llu from %llu\n",dstr(minvol),dstr(ap->offer.basevolume64)-dstr(ap->pendingvolume64),(long long)ap->orderid,(long long)ap->offer.offer64); + } + else if ( (offerdir > 0 && ap->offer.price64 > A->offer.price64) || (offerdir < 0 && ap->offer.price64 < A->offer.price64) ) { - if ( (offerbits == 0 || offerbits != A->A.offer64) && A->A.basevolume64 > 0. && (strcmp(A->A.base,"*") == 0 || strcmp(A->A.base,ap->A.base) == 0) && (strcmp(A->A.rel,"*") == 0 || strcmp(A->A.rel,ap->A.rel) == 0) && A->A.basevolume64 <= (ap->A.basevolume64 - ap->pendingvolume64) && offerdir*instantdex_bidaskdir(ap) < 0 ) + //printf("skip out of band dir.%d offer %.8f vs %.8f orderid.%llu from %llu\n",offerdir,dstr(ap->offer.price64),dstr(A->offer.price64),(long long)ap->orderid,(long long)ap->offer.offer64); + } + else + { + if ( bestprice64 == 0 || (offerdir > 0 && ap->offer.price64 < bestprice64) || (offerdir < 0 && ap->offer.price64 > bestprice64) ) { - if ( offerdir == 0 || A->A.price64 == 0 || ((offerdir > 0 && ap->A.price64 > A->A.price64) || (offerdir < 0 && ap->A.price64 < A->A.price64)) ) - { - if ( bestprice64 == 0 || (offerdir < 0 && ap->A.price64 < bestprice64) || (offerdir > 0 && ap->A.price64 > bestprice64) ) - { - printf("found better price %f vs %f\n",dstr(ap->A.price64),dstr(bestprice64)); - bestprice64 = ap->A.price64; - retap = ap; - } - } + printf(">>>> MATCHED better price dir.%d offer %.8f vs %.8f orderid.%llu from %llu\n",offerdir,dstr(ap->offer.price64),dstr(A->offer.price64),(long long)ap->orderid,(long long)ap->offer.offer64); + bestprice64 = ap->offer.price64; + if ( retap != 0 ) + queue_enqueue("acceptableQ",&exchange->acceptableQ,&retap->DL,0); + retap = ap; } + } + if ( ap != retap ) queue_enqueue("acceptableQ",&exchange->acceptableQ,&ap->DL,0); - } else free(ap); + else free(ap); } return(retap); } @@ -315,227 +773,493 @@ struct instantdex_accept *instantdex_acceptable(struct exchange_info *exchange,s // NXT node verifies bitcoin txbytes has proper payment and cashes in with onetimepubkey // BTC* node approves phased tx with onetimepubkey +bits256 instantdex_acceptset(struct instantdex_accept *ap,char *base,char *rel,int32_t duration,int32_t myside,int32_t acceptdir,double price,double volume,uint64_t offerbits,uint32_t nonce,uint8_t minperc) +{ + bits256 hash; + memset(ap,0,sizeof(*ap)); + safecopy(ap->offer.base,base,sizeof(ap->offer.base)); + safecopy(ap->offer.rel,rel,sizeof(ap->offer.rel)); + if ( nonce == 0 ) + OS_randombytes((uint8_t *)&ap->offer.nonce,sizeof(ap->offer.nonce)); + else ap->offer.nonce = nonce; + if ( duration < 1000000000 ) + ap->offer.expiration = (uint32_t)time(NULL) + duration; + else ap->offer.expiration = duration; + ap->offer.offer64 = offerbits; + ap->offer.myside = myside; + ap->offer.acceptdir = acceptdir; + ap->offer.minperc = minperc; + ap->offer.price64 = price * SATOSHIDEN; + ap->offer.basevolume64 = volume * SATOSHIDEN; + vcalc_sha256(0,hash.bytes,(void *)&ap->offer,sizeof(ap->offer)); + ap->orderid = hash.txid; + //int32_t i; + //for (i=0; ioffer); i++) + // printf("%02x ",((uint8_t *)&ap->offer)[i]); + //printf("\n(%s/%s) %.8f %.8f acceptdir.%d myside.%d\n",base,rel,price,volume,acceptdir,myside); + return(hash); +} + int32_t instantdex_acceptextract(struct instantdex_accept *ap,cJSON *argjson) { - char *base,*rel; bits256 hash; + char *base,*rel; bits256 hash,traderpub; double price,volume; int32_t baserel,acceptdir,minperc; memset(ap,0,sizeof(*ap)); - if ( (base= jstr(argjson,"b")) != 0 ) - safecopy(ap->A.base,base,sizeof(ap->A.base)); - if ( (rel= jstr(argjson,"r")) != 0 ) - safecopy(ap->A.rel,rel,sizeof(ap->A.rel)); - ap->A.nonce = juint(argjson,"n"); - ap->A.expiration = juint(argjson,"e"); - ap->A.myside = juint(argjson,"s"); - ap->A.acceptdir = jint(argjson,"d"); - ap->A.offer64 = j64bits(argjson,"o"); - ap->A.price64 = j64bits(argjson,"p"); - ap->A.basevolume64 = j64bits(argjson,"v"); - vcalc_sha256(0,hash.bytes,(void *)&ap->A,sizeof(ap->A)); - ap->orderid = j64bits(argjson,"i"); + if ( (base= jstr(argjson,"base")) != 0 ) + { + volume = jdouble(argjson,"volume"); + if ( (minperc= juint(argjson,"minperc")) < INSTANTDEX_MINPERC ) + minperc = INSTANTDEX_MINPERC; + else if ( minperc > 100 ) + minperc = 100; + if ( (rel= jstr(argjson,"rel")) != 0 ) + safecopy(ap->offer.rel,rel,sizeof(ap->offer.rel)); + if ( (price= jdouble(argjson,"maxprice")) > SMALLVAL ) + { + baserel = 1; + acceptdir = -1; + } + else if ( (price= jdouble(argjson,"minprice")) > SMALLVAL ) + { + baserel = 0; + acceptdir = 1; + } else return(-1); + //printf("price %f vol %f baserel.%d acceptdir.%d\n",price,volume,baserel,acceptdir); + traderpub = jbits256(argjson,"traderpub"); + hash = instantdex_acceptset(ap,base,rel,INSTANTDEX_LOCKTIME*2,baserel,acceptdir,price,volume,traderpub.txid,0,minperc); + } + else + { + if ( (base= jstr(argjson,"b")) != 0 ) + safecopy(ap->offer.base,base,sizeof(ap->offer.base)); + if ( (rel= jstr(argjson,"r")) != 0 ) + safecopy(ap->offer.rel,rel,sizeof(ap->offer.rel)); + ap->offer.nonce = juint(argjson,"n"); + ap->offer.expiration = juint(argjson,"e"); + ap->offer.myside = juint(argjson,"s"); + ap->offer.acceptdir = jint(argjson,"d"); + ap->offer.offer64 = j64bits(argjson,"o"); + ap->offer.price64 = j64bits(argjson,"p"); + ap->offer.basevolume64 = j64bits(argjson,"v"); + if ( (ap->offer.minperc= juint(argjson,"m")) < INSTANTDEX_MINPERC ) + ap->offer.minperc = INSTANTDEX_MINPERC; + vcalc_sha256(0,hash.bytes,(void *)&ap->offer,sizeof(ap->offer)); + ap->orderid = j64bits(argjson,"id"); + } if ( hash.txid != ap->orderid ) { - printf("instantdex_acceptset warning %llu != %llu\n",(long long)hash.txid,(long long)ap->orderid); + int32_t i; + for (i=0; iorderid); return(-1); } return(0); } -bits256 instantdex_acceptset(struct instantdex_accept *ap,char *base,char *rel,int32_t duration,int32_t myside,int32_t acceptdir,double price,double volume,uint64_t offerbits) +#include "swaps/iguana_BTCswap.c" +#include "swaps/iguana_ALTswap.c" +#include "swaps/iguana_NXTswap.c" +#include "swaps/iguana_PAXswap.c" + +struct bitcoin_swapinfo *bitcoin_swapinit(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *myap,struct instantdex_accept *otherap,int32_t aminitiator,cJSON *argjson,char *statename) { - bits256 hash; - memset(ap,0,sizeof(*ap)); - safecopy(ap->A.base,base,sizeof(ap->A.base)); - safecopy(ap->A.rel,base,sizeof(ap->A.rel)); - OS_randombytes((uint8_t *)&ap->A.nonce,sizeof(ap->A.nonce)); - ap->A.expiration = (uint32_t)time(NULL) + duration; - ap->A.offer64 = offerbits; - ap->A.myside = myside; - ap->A.acceptdir = acceptdir; - ap->A.price64 = price * SATOSHIDEN; - ap->A.basevolume64 = volume * SATOSHIDEN; - vcalc_sha256(0,hash.bytes,(void *)&ap->A,sizeof(ap->A)); - ap->orderid = hash.txid; - return(hash); + struct bitcoin_swapinfo *swap = 0; struct iguana_info *coinbtc,*altcoin; + swap = calloc(1,sizeof(struct bitcoin_swapinfo)); + swap->state = instantdex_statefind(BTC_states,BTC_numstates,statename); + swap->mine = *myap, swap->other = *otherap; + if ( (swap->isinitiator= aminitiator) != 0 ) + { + swap->matched64 = otherap->orderid; + swap->expiration = otherap->offer.expiration; + } + else + { + swap->matched64 = myap->orderid; + swap->expiration = myap->offer.expiration; + } + swap->choosei = swap->otherchoosei = -1; + strcpy(swap->status,"pending"); + vcalc_sha256(0,swap->myorderhash.bytes,(void *)&swap->mine.offer,sizeof(swap->mine.offer)); + vcalc_sha256(0,swap->otherorderhash.bytes,(void *)&swap->other.offer,sizeof(swap->other.offer)); + swap->mypubkey = myinfo->myaddr.persistent; + swap->othertrader = jbits256(argjson,"traderpub"); + swap->altsatoshis = myap->offer.basevolume64; + swap->BTCsatoshis = instantdex_BTCsatoshis(myap->offer.price64,myap->offer.basevolume64); + if ( (coinbtc= iguana_coinfind("BTC")) == 0 || (altcoin= iguana_coinfind(swap->mine.offer.base)) == 0 ) + { + printf("cant find BTC or %s\n",swap->mine.offer.base); + return(0); + } + swap->insurance = (swap->BTCsatoshis * INSTANTDEX_INSURANCERATE + coinbtc->chain->txfee); + swap->altpremium = (swap->altsatoshis * INSTANTDEX_INSURANCERATE + altcoin->chain->txfee); + if ( myap->offer.myside != instantdex_isbob(swap) || otherap->offer.myside == instantdex_isbob(swap) ) + { + printf("isbob error.(%d %d) %d\n",myap->offer.myside,otherap->offer.myside,instantdex_isbob(swap)); + return(0); + } + return(swap); } -cJSON *instantdex_acceptsendjson(struct instantdex_accept *ap) +char *instantdex_checkoffer(struct supernet_info *myinfo,uint64_t *txidp,struct exchange_info *exchange,struct instantdex_accept *myap,cJSON *argjson) { - cJSON *json = cJSON_CreateObject(); - jaddstr(json,"b",ap->A.base); - jaddstr(json,"r",ap->A.rel); - jaddnum(json,"n",ap->A.nonce); - jaddnum(json,"e",ap->A.expiration); - jaddnum(json,"s",ap->A.myside); - jaddnum(json,"d",ap->A.acceptdir); - jadd64bits(json,"p",ap->A.price64); - jadd64bits(json,"v",ap->A.basevolume64); - jadd64bits(json,"i",ap->orderid); - return(json); + char *retstr = 0; struct instantdex_accept *otherap; struct bitcoin_swapinfo *swap; cJSON *newjson; int32_t isbob = 0; + *txidp = myap->orderid; + if ( (otherap= instantdex_acceptable(myinfo,exchange,myap,myap->offer.minperc)) == 0 ) + { + printf("add.%llu to acceptableQ\n",(long long)myap->orderid); + if ( (retstr= instantdex_sendcmd(myinfo,&myap->offer,argjson,"BTCoffer",GENESIS_PUBKEY,INSTANTDEX_HOPS,0,0)) != 0 ) + free(retstr); + queue_enqueue("acceptableQ",&exchange->acceptableQ,&myap->DL,0); + return(jprint(instantdex_offerjson(&myap->offer,myap->orderid),1)); + } + else + { + isbob = myap->offer.myside; + swap = bitcoin_swapinit(myinfo,exchange,myap,otherap,1,argjson,isbob != 0 ? "BOB_sentoffer" : "ALICE_sentoffer"); + printf("STATEMACHINEQ.(%llu / %llu)\n",(long long)swap->mine.orderid,(long long)swap->other.orderid); + //queue_enqueue("acceptableQ",&exchange->acceptableQ,&swap->DL,0); + queue_enqueue("statemachineQ",&exchange->statemachineQ,&swap->DL,0); + if ( (newjson= instantdex_parseargjson(myinfo,exchange,swap,argjson,1)) == 0 ) + return(clonestr("{\"error\":\"instantdex_checkoffer null newjson\"}")); + return(instantdex_sendcmd(myinfo,&swap->mine.offer,newjson,"BTCoffer",GENESIS_PUBKEY,INSTANTDEX_HOPS,swap->deck,sizeof(swap->deck))); + } + return(retstr); } -#include "swaps/iguana_BTCswap.c" -#include "swaps/iguana_ALTswap.c" -#include "swaps/iguana_NXTswap.c" -#include "swaps/iguana_PAXswap.c" +char *instantdex_gotoffer(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *myap,struct instantdex_accept *otherap,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *serdata,int32_t serdatalen) // receiving side +{ + struct bitcoin_swapinfo *swap = 0; bits256 traderpub; struct iguana_info *coinbtc,*altcoin; cJSON *newjson=0; char *retstr=0; int32_t isbob; + coinbtc = iguana_coinfind("BTC"); + traderpub = jbits256(argjson,"traderpub"); + if ( bits256_cmp(traderpub,myinfo->myaddr.persistent) == 0 ) + { + printf("got my own gotoffer packet orderid.%llu/%llu\n",(long long)myap->orderid,(long long)otherap->orderid); + return(clonestr("{\"result\":\"got my own packet\"}")); + } + if ( 0 ) + { + int32_t i; + for (i=0; ioffer); i++) + printf("%02x ",((uint8_t *)&otherap->offer)[i]); + printf("gotoffer.%llu\n",(long long)otherap->orderid); + } + printf(">>>>>>>>> GOTOFFER T.%d got (%s/%s) %.8f vol %.8f %llu offerside.%d offerdir.%d decksize.%d/datalen.%d\n",bits256_cmp(traderpub,myinfo->myaddr.persistent),myap->offer.base,myap->offer.rel,dstr(myap->offer.price64),dstr(myap->offer.basevolume64),(long long)myap->orderid,myap->offer.myside,myap->offer.acceptdir,(int32_t)sizeof(swap->deck),serdatalen); + if ( exchange == 0 ) + return(clonestr("{\"error\":\"instantdex_BTCswap null exchange ptr\"}")); + if ( (altcoin= iguana_coinfind(myap->offer.base)) == 0 || coinbtc == 0 ) + return(clonestr("{\"error\":\"instantdex_BTCswap cant find btc or other coin info\"}")); + if ( strcmp(myap->offer.rel,"BTC") != 0 ) + return(clonestr("{\"error\":\"instantdex_BTCswap offer non BTC rel\"}")); + if ( myap->offer.expiration < (time(NULL) + INSTANTDEX_DURATION) || otherap->offer.expiration < (time(NULL) + INSTANTDEX_DURATION) ) + return(clonestr("{\"error\":\"instantdex_BTCswap offer too close to expiration\"}")); + isbob = myap->offer.myside; + swap = bitcoin_swapinit(myinfo,exchange,myap,otherap,0,argjson,isbob != 0 ? "BOB_gotoffer" : "ALICE_gotoffer"); + if ( (newjson= instantdex_parseargjson(myinfo,exchange,swap,argjson,1)) == 0 ) + { + printf("error parsing argjson\n"); + return(clonestr("{\"error\":\"instantdex_BTCswap offer null newjson\"}")); + } + else //if ( (retstr= instantdex_addfeetx(myinfo,newjson,ap,swap,"BOB_gotoffer","ALICE_gotoffer")) == 0 ) + { + queue_enqueue("acceptableQ",&exchange->acceptableQ,&swap->DL,0); + queue_enqueue("statemachineQ",&exchange->statemachineQ,&swap->DL,0); + if ( (retstr= instantdex_choosei(swap,newjson,argjson,serdata,serdatalen)) != 0 ) + return(retstr); + else + { + return(instantdex_sendcmd(myinfo,&swap->mine.offer,newjson,"BTCdeckC",traderpub,INSTANTDEX_HOPS,swap->deck,sizeof(swap->deck))); + } + } + return(retstr); +} -char *instantdex_parse(struct supernet_info *myinfo,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *data,int32_t datalen) +char *instantdex_parse(struct supernet_info *myinfo,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,struct instantdex_offer *offer,bits256 orderhash,uint8_t *serdata,int32_t serdatalen) { - char cmdstr[16],*traderip,*orderidstr; struct exchange_info *exchange; uint64_t orderid; - struct instantdex_accept A,*ap; + char cmdstr[16],*retstr; struct exchange_info *exchange; struct instantdex_accept A,*ap = 0; bits256 traderpub; cJSON *newjson; struct bitcoin_swapinfo *swap; + if ( BTC_states == 0 ) + BTC_states = BTC_initFSM(&BTC_numstates); exchange = exchanges777_find("bitcoin"); memset(cmdstr,0,sizeof(cmdstr)), memcpy(cmdstr,msg->cmd,sizeof(msg->cmd)); if ( argjson != 0 ) { + traderpub = jbits256(argjson,"traderpub"); memset(&A,0,sizeof(A)); - if ( (traderip= jstr(argjson,"traderip")) != 0 && strcmp(traderip,myinfo->ipaddr) == 0 ) - { - printf("got my own request\n"); - return(clonestr("{\"result\":\"got my own request\"}")); - } - if ( (orderidstr= jstr(argjson,"id")) != 0 ) - { - orderid = calc_nxt64bits(orderidstr); - if ( (ap= instantdex_acceptablefind(exchange,0,0,orderid,"*","*")) != 0 ) - A = *ap; - } else instantdex_acceptextract(&A,argjson); - if ( strncmp(cmdstr,"BTC",3) == 0 ) - return(instantdex_BTCswap(myinfo,exchange,&A,cmdstr+3,msg,argjson,remoteaddr,signerbits,data,datalen)); - else if ( strncmp(cmdstr,"NXT",3) == 0 ) - return(instantdex_NXTswap(myinfo,exchange,&A,cmdstr+3,msg,argjson,remoteaddr,signerbits,data,datalen)); - else if ( strncmp(cmdstr,"ALT",3) == 0 ) - return(instantdex_ALTswap(myinfo,exchange,&A,cmdstr+3,msg,argjson,remoteaddr,signerbits,data,datalen)); - else if ( strncmp(cmdstr,"PAX",3) == 0 ) - return(instantdex_PAXswap(myinfo,exchanges777_find("PAX"),&A,cmdstr+3,msg,argjson,remoteaddr,signerbits,data,datalen)); - else return(clonestr("{\"error\":\"unrecognized atomic swap family\"}")); + if ( j64bits(argjson,"id") != orderhash.txid ) + { + printf("orderhash %llu mismatch id.%llu\n",(long long)orderhash.txid,(long long)j64bits(argjson,"id")); + return(clonestr("{\"error\":\"orderhash mismatch\"}")); + } + A.offer = *offer; + A.orderid = orderhash.txid; + printf("got.(%s) for %llu offer64.%llu\n",cmdstr,(long long)A.orderid,(long long)A.offer.offer64); + if ( (A.offer.minperc= jdouble(argjson,"p")) < INSTANTDEX_MINPERC ) + A.offer.minperc = INSTANTDEX_MINPERC; + else if ( A.offer.minperc > 100 ) + A.offer.minperc = 100; + if ( strcmp(cmdstr,"BTCoffer") == 0 ) // incoming + { + printf("BTCoffer state\n"); + if ( (ap= instantdex_acceptable(myinfo,exchange,&A,A.offer.minperc)) != 0 ) + { + if ( (retstr= instantdex_gotoffer(myinfo,exchange,ap,&A,msg,argjson,remoteaddr,signerbits,serdata,serdatalen)) != 0 ) // adds to statemachine if no error + { + printf("from GOTOFFER.(%s)\n",retstr); + return(retstr); + } else return(clonestr("{\"error\":\"gotoffer error\"}")); + } + else + { + printf("no matching trade for %s %llu -> InstantDEX_minaccept isbob.%d\n",cmdstr,(long long)A.orderid,A.offer.myside); + if ( instantdex_offerfind(myinfo,exchange,0,0,A.orderid,"*","*",1) == 0 ) + { + ap = calloc(1,sizeof(*ap)); + *ap = A; + printf("acceptableQ <- %llu\n",(long long)ap->orderid); + queue_enqueue("acceptableQ",&exchange->acceptableQ,&ap->DL,0); + return(clonestr("{\"result\":\"added new order to orderbook\"}")); + } else return(clonestr("{\"result\":\"order was already in orderbook\"}")); + } + } + else if ( (swap= instantdex_statemachinefind(myinfo,exchange,A.orderid,1)) != 0 ) + { + //printf("found existing state machine %llu\n",(long long)A.orderid); + newjson = instantdex_parseargjson(myinfo,exchange,swap,argjson,0); + if ( serdatalen == sizeof(swap->otherdeck) && swap->choosei < 0 && (retstr= instantdex_choosei(swap,newjson,argjson,serdata,serdatalen)) != 0 ) + { + printf("error choosei\n"); + return(retstr); + } + return(instantdex_statemachine(BTC_states,BTC_numstates,myinfo,exchange,swap,cmdstr,argjson,newjson,serdata,serdatalen)); + } + else + { + printf("cant find existing order.%llu that matches\n",(long long)A.orderid); + return(clonestr("{\"error\":\"cant find matching order\"}")); + } } return(clonestr("{\"error\":\"request needs argjson\"}")); } -char *InstantDEX_hexmsg(struct supernet_info *myinfo,void *ptr,int32_t len,char *remoteaddr) +char *InstantDEX_hexmsg(struct supernet_info *myinfo,struct category_info *cat,void *ptr,int32_t len,char *remoteaddr) { - struct instantdex_msghdr *msg = ptr; cJSON *argjson; int32_t n,datalen,newlen,flag = 0; - uint64_t signerbits; uint8_t *data; uint8_t tmp[sizeof(msg->sig)]; char *retstr = 0; + struct instantdex_msghdr *msg = ptr; int32_t i,olen,slen,num,datalen,newlen,flag = 0; + uint8_t *serdata; struct supernet_info *myinfos[64]; struct instantdex_offer rawoffer; + uint64_t signerbits; uint8_t tmp[sizeof(msg->sig)]; char *retstr = 0; + bits256 orderhash,traderpub; cJSON *retjson,*item,*argjson = 0; + if ( BTC_states == 0 ) + BTC_states = BTC_initFSM(&BTC_numstates); + datalen = len - (int32_t)sizeof(msg->sig); + serdata = (void *)((long)msg + sizeof(msg->sig)); + //printf("a signed datalen.%d allocsize.%d crc.%x\n",datalen,msg->sig.allocsize,calc_crc32(0,serdata,datalen)); acct777_rwsig(0,(void *)&msg->sig,(void *)tmp); memcpy(&msg->sig,tmp,sizeof(msg->sig)); - datalen = len - (int32_t)sizeof(msg->sig); - data = (void *)((long)msg + sizeof(msg->sig)); + // printf("b signed datalen.%d allocsize.%d crc.%x\n",datalen,msg->sig.allocsize,calc_crc32(0,serdata,datalen)); if ( remoteaddr != 0 && remoteaddr[0] == 0 && strcmp("127.0.0.1",remoteaddr) == 0 && ((uint8_t *)msg)[len-1] == 0 && (argjson= cJSON_Parse((char *)msg)) != 0 ) { - printf("instantdex_hexmsg RESULT.(%s)\n",jprint(argjson,0)); - retstr = instantdex_parse(myinfo,msg,argjson,0,myinfo->myaddr.nxt64bits,0,0); + printf("string instantdex_hexmsg RESULT.(%s)\n",jprint(argjson,0)); free_json(argjson); - return(retstr); + return(clonestr("{\"error\":\"string base packets deprecated\"}")); } - //printf("msg.%p len.%d data.%p datalen.%d crc.%u %s\n",msg,len,data,datalen,calc_crc32(0,(void *)msg,len),bits256_str(str,msg->sig.pubkey)); - //return(0); - else if ( (signerbits= acct777_validate(&msg->sig,acct777_msgprivkey(data,datalen),msg->sig.pubkey)) != 0 ) + else if ( (signerbits= acct777_validate(&msg->sig,acct777_msgprivkey(serdata,datalen),msg->sig.pubkey)) != 0 )//|| 1 ) { flag++; - printf("InstantDEX_hexmsg <<<<<<<<<<<<< sigsize.%ld VALIDATED [%ld] len.%d t%u allocsize.%d (%s) [%d]\n",sizeof(msg->sig),(long)data-(long)msg,datalen,msg->sig.timestamp,msg->sig.allocsize,(char *)msg->serialized,data[datalen-1]); - if ( data[datalen-1] == 0 && (argjson= cJSON_Parse((char *)msg->serialized)) != 0 ) - retstr = instantdex_parse(myinfo,msg,argjson,remoteaddr,signerbits,data,datalen); - else + printf("InstantDEX_hexmsg <<<<<<<<<<<<< sigsize.%d VALIDATED [%ld] len.%d t%u allocsize.%d (%s) [%d]\n",(int32_t)sizeof(msg->sig),(long)serdata-(long)msg,datalen,msg->sig.timestamp,msg->sig.allocsize,(char *)msg->serialized,serdata[datalen-1]); + newlen = (int32_t)(msg->sig.allocsize - ((long)msg->serialized - (long)msg)); + serdata = msg->serialized; + //printf("newlen.%d diff.%ld alloc.%d datalen.%d\n",newlen,((long)msg->serialized - (long)msg),msg->sig.allocsize,datalen); + if ( (argjson= cJSON_Parse((char *)serdata)) != 0 ) + { + slen = (int32_t)strlen((char *)serdata) + 1; + serdata = &serdata[slen]; + newlen -= slen; + } + if ( newlen > 0 ) { - newlen = (int32_t)(msg->sig.allocsize - sizeof(*msg)); - data = msg->serialized; - if ( msg->serialized[len - 1] == 0 ) + orderhash = instantdex_rwoffer(0,&olen,serdata,&rawoffer); + newlen -= olen; + //newlen -= ((long)msg->serialized - (long)msg); + serdata = &serdata[olen]; + //printf("received orderhash.%llu olen.%d slen.%d newlen.%d\n",(long long)orderhash.txid,olen,slen,newlen); + } else olen = 0; + if ( newlen <= 0 ) + serdata = 0, newlen = 0; + if ( serdata != 0 || argjson != 0 ) + { + //printf("CALL instantdex_parse.(%s)\n",argjson!=0?jprint(argjson,0):""); + retjson = cJSON_CreateArray(); + if ( (num= SuperNET_MYINFOS(myinfos,sizeof(myinfos)/sizeof(*myinfos))) == 0 ) { - if ( (argjson= cJSON_Parse((char *)msg->serialized)) != 0 ) + myinfos[0] = myinfo; + num = 1; + } + for (i=0; imyaddr.persistent)); + traderpub = jbits256(argjson,"traderpub"); + if ( bits256_cmp(traderpub,myinfo->myaddr.persistent) == 0 ) + continue; + if ( (retstr= instantdex_parse(myinfo,msg,argjson,remoteaddr,signerbits,&rawoffer,orderhash,serdata,newlen)) != 0 ) { - n = (int32_t)(strlen((char *)msg->serialized) + 1); - newlen -= n; - if ( n >= 0 ) - data = &msg->serialized[n]; - else data = 0; + item = cJSON_CreateObject(); + jaddstr(item,"result",retstr); + if ( myinfo->handle[0] != 0 ) + jaddstr(item,"handle",myinfo->handle); + jaddbits256(item,"traderpub",myinfo->myaddr.persistent); + jaddi(retjson,item); } } - if ( data != 0 ) - retstr = instantdex_parse(myinfo,msg,argjson,remoteaddr,signerbits,data,newlen); + retstr = jprint(retjson,1); } - } + } else printf("sig err datalen.%d\n",datalen); if ( argjson != 0 ) free_json(argjson); return(retstr); } -char *instantdex_queueaccept(struct exchange_info *exchange,char *base,char *rel,double price,double basevolume,int32_t acceptdir,char *mysidestr,int32_t duration) +char *instantdex_createaccept(struct supernet_info *myinfo,struct instantdex_accept **aptrp,struct exchange_info *exchange,char *base,char *rel,double price,double basevolume,int32_t acceptdir,char *mysidestr,int32_t duration,uint64_t offerer,int32_t queueflag,uint8_t minperc) { - struct instantdex_accept *ap; int32_t myside; struct supernet_info *myinfo = SuperNET_MYINFO(0); + struct instantdex_accept *ap; int32_t myside; char *retstr; + *aptrp = 0; if ( exchange != 0 ) { - ap = calloc(1,sizeof(*ap)); + *aptrp = ap = calloc(1,sizeof(*ap)); if ( strcmp(mysidestr,base) == 0 ) myside = 0; else if ( strcmp(mysidestr,rel) == 0 ) myside = 1; - else myside = -1; - instantdex_acceptset(ap,base,rel,duration,myside,acceptdir,price,basevolume,myinfo->myaddr.nxt64bits); - queue_enqueue("acceptableQ",&exchange->acceptableQ,&ap->DL,0); - return(jprint(instantdex_acceptjson(ap),1)); + else + { + myside = -1; + printf("myside.(%s) != base.%s or rel.%s\n",mysidestr,base,rel); + } + instantdex_acceptset(ap,base,rel,duration,myside,acceptdir,price,basevolume,offerer,0,minperc); + if ( queueflag != 0 ) + { + printf("acceptableQ <- %llu\n",(long long)ap->orderid); + queue_enqueue("acceptableQ",&exchange->acceptableQ,&ap->DL,0); + } + retstr = jprint(instantdex_acceptjson(ap),1); + //printf("acceptableQ %llu (%s)\n",(long long)ap->orderid,retstr); + return(retstr); + } else return(clonestr("{\"error\":\"invalid exchange\"}")); +} + +void instantdex_update(struct supernet_info *myinfo) +{ + struct instantdex_msghdr *pm; struct category_msg *m; bits256 instantdexhash; char *str,remote[64]; queue_t *Q; struct queueitem *item; struct category_info *cat; + instantdexhash = calc_categoryhashes(0,"InstantDEX",0); + //char str2[65]; printf("instantdexhash.(%s)\n",bits256_str(str2,instantdexhash)); + if ( (Q= category_Q(&cat,instantdexhash,myinfo->myaddr.persistent)) != 0 && queue_size(Q) > 0 && (item= Q->list) != 0 ) + { + m = (void *)item; + m = queue_dequeue(Q,0); + pm = (struct instantdex_msghdr *)m->msg; + //printf("loop cmd.(%s)\n",pm->cmd); + //if ( m->remoteipbits == 0 && (m= queue_dequeue(Q,0)) ) + { + //if ( (void *)m == (void *)item ) + { + pm = (struct instantdex_msghdr *)m->msg; + if ( m->remoteipbits != 0 ) + expand_ipbits(remote,m->remoteipbits); + else remote[0] = 0; + if ( (str= InstantDEX_hexmsg(myinfo,cat,pm,m->len,remote)) != 0 ) + free(str); + } //else printf("instantdex_update: unexpected m.%p changed item.%p\n",m,item); + free(m); + } } - else return(clonestr("{\"error\":\"invalid exchange\"}")); } #include "../includes/iguana_apidefs.h" TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,maxaccept,base,rel,maxprice,basevolume) { - if ( remoteaddr == 0 ) - return(instantdex_queueaccept(exchanges777_find("bitcoin"),base,rel,maxprice,basevolume,-1,rel,INSTANTDEX_OFFERDURATION)); - else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}")); + struct instantdex_accept *ap; char *retstr; struct exchange_info *exchange; uint64_t txid; + myinfo = SuperNET_accountfind(json); + if ( remoteaddr == 0 && (exchange= exchanges777_find("bitcoin")) != 0 ) + { + retstr = instantdex_createaccept(myinfo,&ap,exchange,base,rel,maxprice,basevolume,-1,rel,INSTANTDEX_OFFERDURATION,myinfo->myaddr.nxt64bits,1,juint(json,"minperc")); + return(instantdex_checkoffer(myinfo,&txid,exchange,ap,json)); + + } else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}")); } TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,minaccept,base,rel,minprice,basevolume) { - if ( remoteaddr == 0 ) - return(instantdex_queueaccept(exchanges777_find("bitcoin"),base,rel,minprice,basevolume,1,base,INSTANTDEX_OFFERDURATION)); - else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}")); + struct instantdex_accept *ap; char *retstr; struct exchange_info *exchange; uint64_t txid; + myinfo = SuperNET_accountfind(json); + if ( remoteaddr == 0 && (exchange= exchanges777_find("bitcoin")) != 0 ) + { + retstr = instantdex_createaccept(myinfo,&ap,exchanges777_find("bitcoin"),base,rel,minprice,basevolume,1,base,INSTANTDEX_OFFERDURATION,myinfo->myaddr.nxt64bits,1,juint(json,"minperc")); + return(instantdex_checkoffer(myinfo,&txid,exchange,ap,json)); + } else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}")); } -TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,BTCoffer,othercoin,otherassetid,maxprice,othervolume) +char *instantdex_statemachineget(struct supernet_info *myinfo,struct bitcoin_swapinfo **swapp,cJSON *argjson,char *remoteaddr) { - if ( remoteaddr == 0 ) - return(instantdex_btcoffer(myinfo,exchanges777_find("bitcoin"),othercoin[0] != 0 ? othercoin : otherassetid,othervolume,maxprice)); - else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}")); + struct bitcoin_swapinfo *swap; uint64_t orderid,otherorderid; struct exchange_info *exchange; + *swapp = 0; + if ( remoteaddr == 0 && (exchange= exchanges777_find("bitcoin")) != 0 ) + { + orderid = j64bits(argjson,"myorderid"); + otherorderid = j64bits(argjson,"otherid"); + if ( (swap= instantdex_statemachinefind(myinfo,exchange,orderid,1)) != 0 ) + { + if ( swap->other.orderid != otherorderid ) + return(clonestr("{\"error\":\"statemachine otherid mismatch\"}")); + else + { + *swapp = swap; + return(0); + } + } else return(clonestr("{\"error\":\"statemachine not found\"}")); + } else return(clonestr("{\"error\":\"atomic API request only local usage!\"}")); } -STRING_AND_TWO_DOUBLES(InstantDEX,ALToffer,basecoin,minprice,basevolume) +THREE_STRINGS(atomic,approve,myorderid,otherid,txname) { - int32_t hops = INSTANTDEX_HOPS; cJSON *argjson; char *str; struct instantdex_accept A; - if ( remoteaddr == 0 ) + char *retstr,virtualevent[16]; cJSON *newjson; struct bitcoin_statetx *tx; struct bitcoin_swapinfo *swap = 0; + if ( (retstr= instantdex_statemachineget(myinfo,&swap,json,remoteaddr)) != 0 ) + return(retstr); + else if ( (tx= instantdex_getstatetx(swap,txname)) == 0 ) + return(clonestr("{\"error\":\"cant find txname\"}")); + else { - if ( iguana_coinfind(basecoin) == 0 ) - return(clonestr("{\"error\":\"InstantDEX basecoin is not active, need to addcoin\"}")); - instantdex_acceptset(&A,basecoin,"BTC",INSTANTDEX_OFFERDURATION,0,1,minprice,basevolume,myinfo->myaddr.nxt64bits); - argjson = instantdex_acceptsendjson(&A); - if ( minprice > 0. ) - { - if ( (str= InstantDEX_minaccept(IGUANA_CALLARGS,basecoin,"BTC",minprice,basevolume)) != 0 ) - free(str); - } - return(instantdex_sendcmd(myinfo,argjson,"ALToffer",myinfo->ipaddr,hops)); - } else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}")); + strcpy(virtualevent,txname); + strcat(virtualevent,"found"); + newjson = cJSON_CreateObject(); + if ( (retstr= instantdex_sendcmd(myinfo,&swap->mine.offer,newjson,virtualevent,myinfo->myaddr.persistent,0,0,0)) != 0 ) + return(retstr); + else return(clonestr("{\"result\":\"statemachine sent found event\"}")); + } } -STRING_AND_TWO_DOUBLES(InstantDEX,NXToffer,assetid,minprice,basevolume) +THREE_STRINGS(atomic,claim,myorderid,otherid,txname) { - int32_t hops = INSTANTDEX_HOPS; cJSON *argjson; char *base,*str; struct instantdex_accept A; - if ( remoteaddr == 0 ) + char *retstr; struct bitcoin_statetx *tx; struct bitcoin_swapinfo *swap = 0; + if ( (retstr= instantdex_statemachineget(myinfo,&swap,json,remoteaddr)) != 0 ) + return(retstr); + else if ( (tx= instantdex_getstatetx(swap,txname)) == 0 ) + return(clonestr("{\"error\":\"cant find txname\"}")); + else { - if ( assetid == 0 || assetid[0] == 0 || strcmp(assetid,"0") == 0 || strcmp(assetid,"NXT") == 0 || strcmp(assetid,"nxt") == 0 ) - base = "NXT"; - else if ( is_decimalstr(assetid) <= 0 ) - return(clonestr("{\"error\":\"InstantDEX NXToffer illegal assetid\"}")); - else base = assetid; - instantdex_acceptset(&A,base,"BTC",INSTANTDEX_OFFERDURATION,0,1,minprice,basevolume,myinfo->myaddr.nxt64bits); - argjson = instantdex_acceptsendjson(&A); - if ( minprice > 0. ) - { - if ( (str= InstantDEX_minaccept(IGUANA_CALLARGS,base,"BTC",minprice,basevolume)) != 0 ) - free(str); - } - return(instantdex_sendcmd(myinfo,argjson,"NXToffer",myinfo->ipaddr,hops)); - } else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}")); + return(clonestr("{\"result\":\"statemachine should claim tx\"}")); + } +} + +THREE_STRINGS_AND_DOUBLE(tradebot,aveprice,comment,base,rel,basevolume) +{ + double retvals[4],aveprice; cJSON *retjson = cJSON_CreateObject(); + aveprice = instantdex_avehbla(myinfo,retvals,base,rel,basevolume); + jaddstr(retjson,"result","success"); + jaddnum(retjson,"aveprice",aveprice); + jaddnum(retjson,"avebid",retvals[0]); + jaddnum(retjson,"bidvol",retvals[1]); + jaddnum(retjson,"aveask",retvals[2]); + jaddnum(retjson,"askvol",retvals[3]); + return(jprint(retjson,1)); } #include "../includes/iguana_apiundefs.h" diff --git a/iguana/iguana_interpreter.c b/iguana/iguana_interpreter.c new file mode 100755 index 000000000..36dad141d --- /dev/null +++ b/iguana/iguana_interpreter.c @@ -0,0 +1,2552 @@ +/****************************************************************************** + * 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" +#include "exchanges/bitcoin.h" +#include "mini-gmp.h" + +#define MAX_SCRIPT_ELEMENT_SIZE 520 +#define MAX_OPS_PER_SCRIPT 201 // Maximum number of non-push operations per script +#define MAX_PUBKEYS_PER_MULTISIG 20 // Maximum number of public keys per multisig + +#define IGUANA_MAXSTACKITEMS ((int32_t)(IGUANA_MAXSCRIPTSIZE / sizeof(uint32_t))) +#define IGUANA_MAXSTACKDEPTH 128 + +#define IGUANA_OP_0 0x00 +#define IGUANA_OP_PUSHDATA1 0x4c +#define IGUANA_OP_PUSHDATA2 0x4d +#define IGUANA_OP_PUSHDATA4 0x4e +#define IGUANA_OP_1NEGATE 0x4f +#define IGUANA_OP_1 0x51 +#define IGUANA_OP_16 0x60 +#define IGUANA_OP_NOP 0x61 +#define IGUANA_OP_IF 0x63 +#define IGUANA_OP_NOTIF 0x64 +#define IGUANA_OP_ELSE 0x67 +#define IGUANA_OP_ENDIF 0x68 +#define IGUANA_OP_VERIFY 0x69 +#define IGUANA_OP_RETURN 0x6a + +#define IGUANA_OP_TOALTSTACK 0x6b +#define IGUANA_OP_FROMALTSTACK 0x6c +#define IGUANA_OP_2DROP 0x6d +#define IGUANA_OP_2DUP 0x6e +#define IGUANA_OP_3DUP 0x6f +#define IGUANA_OP_2OVER 0x70 +#define IGUANA_OP_2ROT 0x71 +#define IGUANA_OP_2SWAP 0x72 +#define IGUANA_OP_IFDUP 0x73 +#define IGUANA_OP_DEPTH 0x74 +#define IGUANA_OP_DROP 0x75 +#define IGUANA_OP_DUP 0x76 +#define IGUANA_OP_NIP 0x77 +#define IGUANA_OP_OVER 0x78 +#define IGUANA_OP_PICK 0x79 +#define IGUANA_OP_ROLL 0x7a +#define IGUANA_OP_ROT 0x7b +#define IGUANA_OP_SWAP 0x7c +#define IGUANA_OP_TUCK 0x7d + +#define IGUANA_OP_EQUAL 0x87 +#define IGUANA_OP_EQUALVERIFY 0x88 + +#define IGUANA_OP_1ADD 0x8b +#define IGUANA_OP_1SUB 0x8c +#define IGUANA_OP_NEGATE 0x8f +#define IGUANA_OP_ABS 0x90 +#define IGUANA_OP_NOT 0x91 +#define IGUANA_OP_0NOTEQUAL 0x92 +#define IGUANA_OP_ADD 0x93 +#define IGUANA_OP_SUB 0x94 + +#define IGUANA_OP_BOOLAND 0x9a +#define IGUANA_OP_BOOLOR 0x9b +#define IGUANA_OP_NUMEQUAL 0x9c +#define IGUANA_OP_NUMEQUALVERIFY 0x9d +#define IGUANA_OP_NUMNOTEQUAL 0x9e +#define IGUANA_OP_LESSTHAN 0x9f +#define IGUANA_OP_GREATERTHAN 0xa0 +#define IGUANA_OP_LESSTHANOREQUAL 0xa1 +#define IGUANA_OP_GREATERTHANOREQUAL 0xa2 +#define IGUANA_OP_MIN 0xa3 +#define IGUANA_OP_MAX 0xa4 +#define IGUANA_OP_WITHIN 0xa5 + +#define IGUANA_OP_RIPEMD160 0xa6 +#define IGUANA_OP_SHA1 0xa7 +#define IGUANA_OP_SHA256 0xa8 +#define IGUANA_OP_HASH160 0xa9 +#define IGUANA_OP_HASH256 0xaa +#define IGUANA_OP_CODESEPARATOR 0xab +#define IGUANA_OP_CHECKSIG 0xac +#define IGUANA_OP_CHECKSIGVERIFY 0xad +#define IGUANA_OP_CHECKMULTISIG 0xae +#define IGUANA_OP_CHECKMULTISIGVERIFY 0xaf + +#define IGUANA_OP_NOP1 0xb0 +#define IGUANA_OP_CHECKLOCKTIMEVERIFY 0xb1 +#define IGUANA_OP_CHECKSEQUENCEVERIFY 0xb2 +#define IGUANA_OP_NOP10 0xb9 + +#define IGUANA_NOPFLAG 1 +#define IGUANA_ALWAYSILLEGAL 2 +#define IGUANA_EXECUTIONILLEGAL 4 +#define IGUANA_POSTVERIFY 8 +#define IGUANA_CRYPTOFLAG 16 +#define IGUANA_MATHFLAG 32 +#define IGUANA_CONTROLFLAG 64 +#define IGUANA_STACKFLAG 128 + +enum opcodetype +{ + // push value + OP_0 = 0x00, + OP_FALSE = OP_0, + OP_PUSHDATA1 = 0x4c, + OP_PUSHDATA2 = 0x4d, + OP_PUSHDATA4 = 0x4e, + OP_1NEGATE = 0x4f, + OP_RESERVED = 0x50, + OP_1 = 0x51, + OP_TRUE=OP_1, + OP_2 = 0x52, + OP_3 = 0x53, + OP_4 = 0x54, + OP_5 = 0x55, + OP_6 = 0x56, + OP_7 = 0x57, + OP_8 = 0x58, + OP_9 = 0x59, + OP_10 = 0x5a, + OP_11 = 0x5b, + OP_12 = 0x5c, + OP_13 = 0x5d, + OP_14 = 0x5e, + OP_15 = 0x5f, + OP_16 = 0x60, + + // control + OP_NOP = 0x61, + OP_VER = 0x62, + OP_IF = 0x63, + OP_NOTIF = 0x64, + OP_VERIF = 0x65, + OP_VERNOTIF = 0x66, + OP_ELSE = 0x67, + OP_ENDIF = 0x68, + OP_VERIFY = 0x69, + OP_RETURN = 0x6a, + + // stack ops + OP_TOALTSTACK = 0x6b, + OP_FROMALTSTACK = 0x6c, + OP_2DROP = 0x6d, + OP_2DUP = 0x6e, + OP_3DUP = 0x6f, + OP_2OVER = 0x70, + OP_2ROT = 0x71, + OP_2SWAP = 0x72, + OP_IFDUP = 0x73, + OP_DEPTH = 0x74, + OP_DROP = 0x75, + OP_DUP = 0x76, + OP_NIP = 0x77, + OP_OVER = 0x78, + OP_PICK = 0x79, + OP_ROLL = 0x7a, + OP_ROT = 0x7b, + OP_SWAP = 0x7c, + OP_TUCK = 0x7d, + + // splice ops + OP_CAT = 0x7e, + OP_SUBSTR = 0x7f, + OP_LEFT = 0x80, + OP_RIGHT = 0x81, + OP_SIZE = 0x82, + + // bit logic + OP_INVERT = 0x83, + OP_AND = 0x84, + OP_OR = 0x85, + OP_XOR = 0x86, + OP_EQUAL = 0x87, + OP_EQUALVERIFY = 0x88, + OP_RESERVED1 = 0x89, + OP_RESERVED2 = 0x8a, + + // numeric + OP_1ADD = 0x8b, + OP_1SUB = 0x8c, + OP_2MUL = 0x8d, + OP_2DIV = 0x8e, + OP_NEGATE = 0x8f, + OP_ABS = 0x90, + OP_NOT = 0x91, + OP_0NOTEQUAL = 0x92, + + OP_ADD = 0x93, + OP_SUB = 0x94, + OP_MUL = 0x95, + OP_DIV = 0x96, + OP_MOD = 0x97, + OP_LSHIFT = 0x98, + OP_RSHIFT = 0x99, + + OP_BOOLAND = 0x9a, + OP_BOOLOR = 0x9b, + OP_NUMEQUAL = 0x9c, + OP_NUMEQUALVERIFY = 0x9d, + OP_NUMNOTEQUAL = 0x9e, + OP_LESSTHAN = 0x9f, + OP_GREATERTHAN = 0xa0, + OP_LESSTHANOREQUAL = 0xa1, + OP_GREATERTHANOREQUAL = 0xa2, + OP_MIN = 0xa3, + OP_MAX = 0xa4, + + OP_WITHIN = 0xa5, + + // crypto + OP_RIPEMD160 = 0xa6, + OP_SHA1 = 0xa7, + OP_SHA256 = 0xa8, + OP_HASH160 = 0xa9, + OP_HASH256 = 0xaa, + OP_CODESEPARATOR = 0xab, + OP_CHECKSIG = 0xac, + OP_CHECKSIGVERIFY = 0xad, + OP_CHECKMULTISIG = 0xae, + OP_CHECKMULTISIGVERIFY = 0xaf, + + // expansion + OP_NOP1 = 0xb0, + OP_CHECKLOCKTIMEVERIFY = 0xb1, + OP_CHECKSEQUENCEVERIFY = 0xb2, + OP_NOP4 = 0xb3, + OP_NOP5 = 0xb4, + OP_NOP6 = 0xb5, + OP_NOP7 = 0xb6, + OP_NOP8 = 0xb7, + OP_NOP9 = 0xb8, + OP_NOP10 = 0xb9, + + // template matching params + //OP_SMALLINTEGER = 0xfa, + //OP_PUBKEYS = 0xfb, + //OP_PUBKEYHASH = 0xfd, + //OP_PUBKEY = 0xfe, + + OP_INVALIDOPCODE = 0xff, +}; + +const char *get_opname(uint8_t *stackitemsp,uint8_t *flagsp,int32_t *extralenp,enum opcodetype opcode) +{ + *extralenp = 0; + switch ( opcode ) + { + // push value + case OP_0 : return "0"; + case OP_PUSHDATA1 : *extralenp = 1; return "OP_PUSHDATA1"; + case OP_PUSHDATA2 : *extralenp = 2; return "OP_PUSHDATA2"; + case OP_PUSHDATA4 : *flagsp = IGUANA_EXECUTIONILLEGAL; return "OP_PUSHDATA4"; + case OP_1NEGATE : return "-1"; + case OP_RESERVED : *flagsp = IGUANA_EXECUTIONILLEGAL; return "OP_RESERVED"; + case OP_1 : return "1"; + case OP_2 : return "2"; + case OP_3 : return "3"; + case OP_4 : return "4"; + case OP_5 : return "5"; + case OP_6 : return "6"; + case OP_7 : return "7"; + case OP_8 : return "8"; + case OP_9 : return "9"; + case OP_10 : return "10"; + case OP_11 : return "11"; + case OP_12 : return "12"; + case OP_13 : return "13"; + case OP_14 : return "14"; + case OP_15 : return "15"; + case OP_16 : return "16"; + + // control + case OP_NOP : *flagsp = IGUANA_NOPFLAG; return "OP_NOP"; + case OP_VER : *flagsp = IGUANA_EXECUTIONILLEGAL; return "OP_VER"; + case OP_IF : *flagsp = IGUANA_CONTROLFLAG; *stackitemsp = 1; return "OP_IF"; + case OP_NOTIF : *flagsp = IGUANA_CONTROLFLAG; *stackitemsp = 1; return "OP_NOTIF"; + case OP_VERIF : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_VERIF"; + case OP_VERNOTIF : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_VERNOTIF"; + case OP_ELSE : *flagsp = IGUANA_CONTROLFLAG; return "OP_ELSE"; + case OP_ENDIF : *flagsp = IGUANA_CONTROLFLAG; return "OP_ENDIF"; + case OP_VERIFY : *flagsp = IGUANA_POSTVERIFY; return "OP_VERIFY"; + case OP_RETURN : *flagsp = IGUANA_CONTROLFLAG; return "OP_RETURN"; + + // stack ops + case OP_TOALTSTACK : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 1; return "OP_TOALTSTACK"; + case OP_FROMALTSTACK : *flagsp = IGUANA_STACKFLAG; return "OP_FROMALTSTACK"; + case OP_2DROP : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 2; return "OP_2DROP"; + case OP_2DUP : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 2; return "OP_2DUP"; + case OP_3DUP : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 3; return "OP_3DUP"; + case OP_2OVER : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 4; return "OP_2OVER"; + case OP_2ROT : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 6; return "OP_2ROT"; + case OP_2SWAP : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 4; return "OP_2SWAP"; + case OP_IFDUP : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 1; return "OP_IFDUP"; + case OP_DEPTH : *flagsp = IGUANA_STACKFLAG; return "OP_DEPTH"; + case OP_DROP : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 1; return "OP_DROP"; + case OP_DUP : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 1; return "OP_DUP"; + case OP_NIP : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 2; return "OP_NIP"; + case OP_OVER : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 2; return "OP_OVER"; + case OP_PICK : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 1; return "OP_PICK"; + case OP_ROLL : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 1; return "OP_ROLL"; + case OP_ROT : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 3; return "OP_ROT"; + case OP_SWAP : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 2; return "OP_SWAP"; + case OP_TUCK : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 2; return "OP_TUCK"; + + // splice ops + case OP_CAT : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_CAT"; + case OP_SUBSTR : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_SUBSTR"; + case OP_LEFT : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_LEFT"; + case OP_RIGHT : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_RIGHT"; + case OP_SIZE : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_SIZE"; + + // bit logic + case OP_INVERT : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_INVERT"; + case OP_AND : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_AND"; + case OP_OR : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_OR"; + case OP_XOR : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_XOR"; + case OP_EQUAL : *stackitemsp = 2; return "OP_EQUAL"; + case OP_EQUALVERIFY : *stackitemsp = 2; *flagsp = IGUANA_POSTVERIFY; return "OP_EQUALVERIFY"; + case OP_RESERVED1 : *flagsp = IGUANA_EXECUTIONILLEGAL; return "OP_RESERVED1"; + case OP_RESERVED2 : *flagsp = IGUANA_EXECUTIONILLEGAL; return "OP_RESERVED2"; + + // numeric + case OP_1ADD : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 1; return "OP_1ADD"; + case OP_1SUB : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 1; return "OP_1SUB"; + case OP_2MUL : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_2MUL"; + case OP_2DIV : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_2DIV"; + case OP_NEGATE : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 1; return "OP_NEGATE"; + case OP_ABS : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 1; return "OP_ABS"; + case OP_NOT : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 1; return "OP_NOT"; + case OP_0NOTEQUAL : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 1; return "OP_0NOTEQUAL"; + case OP_ADD : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_ADD"; + case OP_SUB : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_SUB"; + case OP_MUL : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_MUL"; + case OP_DIV : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_DIV"; + case OP_MOD : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_MOD"; + case OP_LSHIFT : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_LSHIFT"; + case OP_RSHIFT : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_RSHIFT"; + case OP_BOOLAND : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_BOOLAND"; + case OP_BOOLOR : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_BOOLOR"; + case OP_NUMEQUAL : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_NUMEQUAL"; + case OP_NUMEQUALVERIFY: *flagsp = IGUANA_MATHFLAG | IGUANA_POSTVERIFY; *stackitemsp = 2; return "OP_NUMEQUALVERIFY"; + case OP_NUMNOTEQUAL : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_NUMNOTEQUAL"; + case OP_LESSTHAN : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_LESSTHAN"; + case OP_GREATERTHAN : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_GREATERTHAN"; + case OP_LESSTHANOREQUAL: *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_LESSTHANOREQUAL"; + case OP_GREATERTHANOREQUAL: *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_GREATERTHANOREQUAL"; + case OP_MIN : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_MIN"; + case OP_MAX : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_MAX"; + case OP_WITHIN : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 3; return "OP_WITHIN"; + + // crypto + case OP_RIPEMD160 : *stackitemsp = 1; *flagsp = IGUANA_CRYPTOFLAG; return "OP_RIPEMD160"; + case OP_SHA1 : *stackitemsp = 1; *flagsp = IGUANA_CRYPTOFLAG; return "OP_SHA1"; + case OP_SHA256 : *stackitemsp = 1; *flagsp = IGUANA_CRYPTOFLAG; return "OP_SHA256"; + case OP_HASH160 : *stackitemsp = 1; *flagsp = IGUANA_CRYPTOFLAG; return "OP_HASH160"; + case OP_HASH256 : *stackitemsp = 1; *flagsp = IGUANA_CRYPTOFLAG; return "OP_HASH256"; + case OP_CODESEPARATOR: return "OP_CODESEPARATOR"; + case OP_CHECKSIG : *stackitemsp = 2; *flagsp = IGUANA_CRYPTOFLAG; return "OP_CHECKSIG"; + case OP_CHECKSIGVERIFY: *stackitemsp = 2; *flagsp = IGUANA_CRYPTOFLAG | IGUANA_POSTVERIFY; return "OP_CHECKSIGVERIFY"; + case OP_CHECKMULTISIG: *flagsp = IGUANA_CRYPTOFLAG; return "OP_CHECKMULTISIG"; + case OP_CHECKMULTISIGVERIFY: *flagsp = IGUANA_CRYPTOFLAG | IGUANA_POSTVERIFY; return "OP_CHECKMULTISIGVERIFY"; + + // expanson + case OP_NOP1 : *flagsp = IGUANA_NOPFLAG; return "OP_NOP1"; + case OP_CHECKLOCKTIMEVERIFY: *stackitemsp = 1; return "OP_CHECKLOCKTIMEVERIFY"; + case OP_CHECKSEQUENCEVERIFY: *stackitemsp = 1; return "OP_CHECKSEQUENCEVERIFY"; + case OP_NOP4 : *flagsp = IGUANA_NOPFLAG; return "OP_NOP4"; + case OP_NOP5 : *flagsp = IGUANA_NOPFLAG; return "OP_NOP5"; + case OP_NOP6 : *flagsp = IGUANA_NOPFLAG; return "OP_NOP6"; + case OP_NOP7 : *flagsp = IGUANA_NOPFLAG; return "OP_NOP7"; + case OP_NOP8 : *flagsp = IGUANA_NOPFLAG; return "OP_NOP8"; + case OP_NOP9 : *flagsp = IGUANA_NOPFLAG; return "OP_NOP9"; + case OP_NOP10 : *flagsp = IGUANA_NOPFLAG; return "OP_NOP10"; + + case OP_INVALIDOPCODE: return "OP_INVALIDOPCODE"; + default: return "OP_UNKNOWN"; + } +} + +static inline int32_t is_delim(int32_t c) +{ + if ( c == 0 || c == ' ' || c == '\t' || c == '\r' || c == '\n' ) + return(1); + else return(0); +} + +union iguana_stacknum { int32_t val; int64_t val64; uint8_t rmd160[20]; bits256 hash2; uint8_t pubkey[33]; uint8_t sig[74]; }; +struct iguana_stackdata { uint8_t *data; uint16_t size; union iguana_stacknum U; }; + +struct iguana_interpreter +{ + int32_t active,ifdepth,elsedepth,codeseparator,stackdepth,altstackdepth,maxstackdepth; + int8_t lastpath[IGUANA_MAXSTACKDEPTH]; + cJSON *logarray; + struct iguana_stackdata stack[]; +}; +static struct bitcoin_opcode { UT_hash_handle hh; uint8_t opcode,flags,stackitems; int8_t extralen; } *OPTABLE; static char *OPCODES[0x100]; static int32_t OPCODELENS[0x100]; + +static struct iguana_stackdata iguana_pop(struct iguana_interpreter *stacks) +{ + struct iguana_stackdata Snum; + Snum = stacks->stack[--stacks->stackdepth]; + memset(&stacks->stack[stacks->stackdepth],0,sizeof(Snum)); + return(Snum); +} + +static int32_t iguana_altpush(struct iguana_interpreter *stacks,struct iguana_stackdata Snum) +{ + stacks->stack[2*IGUANA_MAXSTACKITEMS - ++stacks->altstackdepth] = Snum; + return(stacks->altstackdepth); +} + +static struct iguana_stackdata iguana_altpop(struct iguana_interpreter *stacks) +{ + struct iguana_stackdata Snum,*ptr; + ptr = &stacks->stack[2*IGUANA_MAXSTACKITEMS - --stacks->altstackdepth]; + Snum = *ptr; + memset(ptr,0,sizeof(Snum)); + return(Snum); +} + +static struct iguana_stackdata iguana_clone(struct iguana_stackdata Snum) +{ + struct iguana_stackdata clone; + clone = Snum; + if ( Snum.data != 0 ) + { + clone.data = malloc(Snum.size); + memcpy(clone.data,Snum.data,Snum.size); + } + return(clone); +} + +static int32_t iguana_isnonz(struct iguana_stackdata Snum) +{ + uint8_t *buf; int32_t i; + if ( Snum.size == sizeof(int32_t) ) + return(Snum.U.val != 0); + else if ( Snum.size == sizeof(int64_t) ) + return(Snum.U.val64 != 0); + else if ( Snum.size == 20 ) + buf = Snum.U.rmd160; + else if ( Snum.size == sizeof(bits256) ) + buf = Snum.U.hash2.bytes; + else if ( Snum.size == 33 ) + buf = Snum.U.pubkey; + else if ( Snum.size < 74 ) + buf = Snum.U.sig; + else buf = Snum.data; + for (i=0; imaxstackdepth > 0 ) + { + printf("PUSHDATA.[%d]\n",numlen); + if ( stacks->stackdepth < stacks->maxstackdepth ) + { + if ( stacks->logarray != 0 ) + item = cJSON_CreateObject(); + memset(&Snum,0,sizeof(Snum)); + if ( numbuf != 0 ) + { + if ( numlen <= sizeof(int32_t) ) + { + iguana_rwnum(1,(void *)&num,numlen,numbuf); + numlen = sizeof(num); + Snum.U.val = num; + if ( item != 0 ) + jaddnum(item,"push",num); + } + else if ( numlen <= sizeof(int64_t) ) + { + iguana_rwnum(1,(void *)&num64,numlen,numbuf); + numlen = sizeof(num64); + Snum.U.val64 = num64; + if ( item != 0 ) + jadd64bits(item,"push",num64); + } + else if ( numlen == 20 ) + { + memcpy(Snum.U.rmd160,numbuf,20); + if ( item != 0 ) + { + init_hexbytes_noT(str,Snum.U.rmd160,20); + jaddstr(item,"push",str); + } + } + else if ( numlen == sizeof(bits256) ) + { + iguana_rwbignum(1,Snum.U.hash2.bytes,sizeof(Snum.U.hash2),numbuf); + if ( item != 0 ) + jaddbits256(item,"push",Snum.U.hash2); + } + else if ( numlen == 33 ) + { + memcpy(Snum.U.pubkey,numbuf,numlen); + if ( item != 0 ) + jaddnum(item,"push",numlen); + } + else if ( numlen < 74 ) + { + memcpy(Snum.U.sig,numbuf,numlen); + if ( item != 0 ) + jaddnum(item,"push",numlen); + } + else + { + Snum.data = malloc(numlen); + memcpy(Snum.data,numbuf,numlen); + if ( item != 0 ) + jaddnum(item,"push",numlen); + } + Snum.size = numlen; + } + else if ( num64 <= 0xffffffff ) // what about negative numbers? + Snum.U.val = num, Snum.size = sizeof(num); + else Snum.U.val64 = num64, Snum.size = sizeof(num64); + if ( item != 0 ) + { + jaddnum(item,"depth",stacks->stackdepth); + if ( stacks->logarray != 0 ) + jaddi(stacks->logarray,item); + } + stacks->stack[stacks->stackdepth++] = Snum; + } else return(-1); + } else stacks->stackdepth++; + return(0); +} + +int32_t iguana_databuf(uint8_t *databuf,struct iguana_stackdata Snum) +{ + if ( Snum.size == 4 ) + memcpy(databuf,&Snum.U.val,4); + else if ( Snum.size == 8 ) + memcpy(databuf,&Snum.U.val64,8); + else if ( Snum.size == 20 ) + memcpy(databuf,&Snum.U.rmd160,20); + else if ( Snum.size == 32 ) + memcpy(databuf,&Snum.U.hash2.bytes,32); + else if ( Snum.size == 33 ) + memcpy(databuf,&Snum.U.pubkey,33); + else if ( Snum.size < 74 ) + memcpy(databuf,&Snum.U.sig,Snum.size); + else memcpy(databuf,&Snum.data,Snum.size); + return(Snum.size); +} + +static int32_t iguana_cmp(struct iguana_stackdata *a,struct iguana_stackdata *b) +{ + if ( a->size == b->size ) + { + if ( a->size == 4 ) + return(a->U.val == b->U.val); + else if ( a->size == 8 ) + return(a->U.val64 == b->U.val64); + else if ( a->size == 20 ) + return(memcmp(a->U.rmd160,b->U.rmd160,sizeof(a->U.rmd160)) == 0); + else if ( a->size == 32 ) + return(memcmp(a->U.hash2.bytes,b->U.hash2.bytes,sizeof(a->U.hash2)) == 0); + else if ( a->size == 33 ) + return(memcmp(a->U.pubkey,b->U.pubkey,33) == 0); + else if ( a->size < 74 ) + return(memcmp(a->U.sig,b->U.sig,a->size) == 0); + else return(memcmp(a->data,b->data,sizeof(a->size)) == 0); + } + return(-1); +} + +static int32_t iguana_dataparse(struct iguana_interpreter *stacks,uint8_t *script,int32_t k,char *str,int32_t *lenp) +{ + int32_t n,c,len; char tmp[4]; + *lenp = 0; + c = str[0]; + n = is_hexstr(str,0); + if ( n > 0 ) + { + if ( (n & 1) != 0 ) + len = (n+1) >> 1; + else len = n >> 1; + if ( len > 0 && len < 76 ) + { + if ( len == 1 ) + { + if ( n == 1 ) + { + tmp[0] = '0'; + tmp[1] = c; + tmp[2] = 0; + decode_hex(&script[k],1,tmp), (*lenp) = 1; + if ( script[k] != 0 ) + script[k++] += (IGUANA_OP_1 - 1); + iguana_pushdata(stacks,c,0,0); + return(k); + } + else if ( n == 2 && c == '1' && str[1] == '0' && is_delim(str[2]) != 0 ) + { + script[k++] = (IGUANA_OP_1 - 1) + 0x10, (*lenp) = 2; + iguana_pushdata(stacks,0x10,0,0); + return(k); + } + else if ( n == 2 && c == '8' && is_delim(str[2]) != 0 ) + { + if ( str[1] == '1' ) + { + script[k++] = IGUANA_OP_1NEGATE, (*lenp) = 2; + iguana_pushdata(stacks,-1,0,0); + return(k); + } + else if ( str[1] == '0' ) + { + script[k++] = IGUANA_OP_0, (*lenp) = 2; + iguana_pushdata(stacks,0,0,0); + return(k); + } + } + } + if ( len != 0 ) + script[k++] = len; + } + else if ( len <= 0xff ) + { + script[k++] = IGUANA_OP_PUSHDATA1; + script[k++] = len; + } + else if ( len <= 0xffff ) + { + if ( len <= MAX_SCRIPT_ELEMENT_SIZE ) + { + script[k++] = IGUANA_OP_PUSHDATA2; + script[k++] = (len & 0xff); + script[k++] = ((len >> 8) & 0xff); + } + else + { + printf("len.%d > MAX_SCRIPT_ELEMENT_SIZE.%d, offset.%d\n",len,MAX_SCRIPT_ELEMENT_SIZE,k); + return(-1); + } + } + else + { + printf("len.%d > MAX_SCRIPT_ELEMENT_SIZE.%d, offset.%d\n",len,MAX_SCRIPT_ELEMENT_SIZE,k); + return(-1); + } + if ( len != 0 ) + { + uint8_t *numstart; int32_t numlen; + numstart = &script[k], numlen = len; + if ( (n & 1) != 0 ) + { + tmp[0] = '0'; + tmp[1] = c; + tmp[2] = 0; + decode_hex(&script[k++],1,tmp), *lenp = 1; + len--; + } + if ( len != 0 ) + { + decode_hex(&script[k],len,str), (*lenp) += (len << 1); + k += len; + } + iguana_pushdata(stacks,0,numstart,numlen); + } + return(k); + } + return(0); +} + +void iguana_stack(struct iguana_interpreter *stacks,struct iguana_stackdata *args,int32_t num,char *pushstr,char *clonestr) +{ + int32_t i,c; + while ( (c= *pushstr++) != 0 ) + stacks->stack[stacks->stackdepth++] = args[c - '0']; + while ( (c= *clonestr++) != 0 ) + stacks->stack[stacks->stackdepth++] = iguana_clone(args[c - '0']); + if ( num > 0 ) + { + for (i=0; i 0 && siglen > 0 && siglen < 74 ) + return(bitcoin_verify(coin->ctx,sig,siglen-1,sigtxid,pubkey,plen) == 0); + return(0); +} + +int32_t iguana_checkmultisig(struct iguana_info *coin,struct iguana_interpreter *stacks,int32_t M,int32_t N,bits256 txhash2) +{ + int32_t i,j=0,len,valid=0,numsigners = 0,siglens[MAX_PUBKEYS_PER_MULTISIG]; uint8_t pubkeys[MAX_PUBKEYS_PER_MULTISIG][MAX_SCRIPT_ELEMENT_SIZE],sigs[MAX_PUBKEYS_PER_MULTISIG][MAX_SCRIPT_ELEMENT_SIZE]; + if ( M <= N && N <= MAX_PUBKEYS_PER_MULTISIG ) + { + for (i=0; istackdepth <= 0 ) + return(0); + len = iguana_databuf(pubkeys[i],iguana_pop(stacks)); + if ( len == bitcoin_pubkeylen(pubkeys[i]) ) + numsigners++; + else + { + memcpy(sigs[0],pubkeys[i],len); + siglens[0] = len; + break; + } + } + for (i=1; istackdepth <= 0 ) + return(0); + siglens[i] = iguana_databuf(sigs[i],iguana_pop(stacks)); + if ( siglens[i] > 0 && siglens[i] < 74 ) + break; + } + if ( i == numsigners ) + { + iguana_pop(stacks); + j = numsigners-1; + for (i=numsigners-1; i>=0; i--) + { + for (; j>=0; j--) + { + if ( bitcoin_verify(coin->ctx,sigs[i],siglens[i],txhash2,pubkeys[j],bitcoin_pubkeylen(pubkeys[j])) == 0 ) + { + if ( ++valid >= M ) + return(1); + j--; + break; + } + } + } + } + } + printf("valid.%d j.%d M.%d N.%d numsigners.%d\n",valid,j,M,N,numsigners); + return(0); +} + +int32_t iguana_checklocktimeverify(struct iguana_info *coin,int64_t nLockTime,uint32_t nSequence,struct iguana_stackdata Snum) +{ + int32_t num = iguana_num(Snum); + if ( num < 0 || (num >= 500000000 && nLockTime < 500000000) || (num < 500000000 && nLockTime >= 500000000) || nSequence == 0xffffffff || num > nLockTime ) + return(-1); + return(0); +} + +int32_t iguana_checksequenceverify(struct iguana_info *coin,int64_t nLockTime,uint32_t nSequence,struct iguana_stackdata Snum) +{ + return(0); +} + +void iguana_optableinit(struct iguana_info *coin) +{ + int32_t i,extralen; uint8_t stackitems,flags; char *opname; struct bitcoin_opcode *op; + if ( OPTABLE == 0 ) + { + for (i=0; i<0x100; i++) + OPCODES[i] = "OP_UNKNOWN"; + for (i=0; i<0x100; i++) + { + extralen = stackitems = flags = 0; + opname = (char *)get_opname(&stackitems,&flags,&extralen,i); + if ( strcmp("OP_UNKNOWN",opname) != 0 ) + { + op = calloc(1,sizeof(*op)); + HASH_ADD_KEYPTR(hh,OPTABLE,opname,strlen(opname),op); + //printf("{%-16s %02x} ",opname,i); + op->opcode = i; + op->flags = flags; + op->stackitems = stackitems; + op->extralen = extralen; + OPCODES[i] = (char *)op->hh.key; + OPCODELENS[i] = (int32_t)strlen(OPCODES[i]); + } + } + //printf("bitcoin opcodes\n"); + } +} + +int32_t iguana_expandscript(struct iguana_info *coin,char *asmstr,int32_t maxlen,uint8_t *script,int32_t scriptlen) +{ + int32_t len,n,j,i = 0; uint8_t opcode; uint32_t val,extraflag; + iguana_optableinit(coin); + asmstr[0] = len = 0; + while ( i < scriptlen ) + { + val = extraflag = 0; + opcode = script[i++]; + if ( opcode > 0 && opcode < 76 ) + { + for (j=0; j= IGUANA_OP_1 && opcode <= IGUANA_OP_16 ) + { + sprintf(&asmstr[len],"%d",opcode - IGUANA_OP_1 + 1); + len += strlen(&asmstr[len]); + } + else if ( opcode == IGUANA_OP_0 ) + { + strcpy(&asmstr[len],"OP_FALSE"); + len += 8; + } + else if ( opcode == IGUANA_OP_1NEGATE ) + { + asmstr[len++] = '-'; + asmstr[len++] = '1'; + } + else + { + //printf("dest.%p <- %p %02x\n",&asmstr[len],OPCODES[opcode],opcode); + strcpy(&asmstr[len],OPCODES[opcode]); + len += OPCODELENS[opcode]; + } + if ( i < scriptlen ) + asmstr[len++] = ' '; + if ( opcode == IGUANA_OP_PUSHDATA1 ) + { + n = script[i++]; + for (j=0; j (%s)\n",asmstr); + jaddstr(spendasm,"interpreter",asmstr); + return(spendasm); +} + +int32_t bitcoin_assembler(struct iguana_info *coin,uint8_t script[IGUANA_MAXSCRIPTSIZE],cJSON *interpreter,int32_t interpret,int64_t nLockTime,struct vin_info *V) +{ + struct bitcoin_opcode *op; cJSON *array = 0; struct iguana_interpreter STACKS,*stacks = &STACKS; + struct iguana_stackdata args[MAX_PUBKEYS_PER_MULTISIG]; + uint8_t databuf[MAX_SCRIPT_ELEMENT_SIZE]; char *asmstr,*str,*hexstr; + int32_t c,numops,plen,numvars,numused,numargs=0,i,j,k,n,len,val,datalen,errs=0; + iguana_optableinit(coin); + if ( (asmstr= jstr(interpreter,"interpreter")) == 0 ) + return(-1); + if ( (numvars= juint(interpreter,"numvars")) > 0 ) + { + if ( (array= jarray(&n,interpreter,"args")) == 0 || (interpret != 0 && n != numvars) ) + return(-2); + } + str = asmstr; + if ( interpret != 0 ) + { + stacks = calloc(1,sizeof(*stacks) + sizeof(*stacks->stack)*2*IGUANA_MAXSTACKITEMS); + stacks->maxstackdepth = IGUANA_MAXSTACKITEMS; + if ( interpret > 1 ) + stacks->logarray = cJSON_CreateArray(); + if ( V->M == 0 && V->N == 0 ) + V->N = V->M = 1; + for (i=0; iN; i++) + { + if ( V->signers[i].siglen != 0 ) + { + iguana_pushdata(stacks,0,V->signers[i].sig,V->signers[i].siglen); + if ( bitcoin_pubkeylen(V->signers[i].pubkey) <= 0 ) + { + printf("missing pubkey.[%d]\n",i); + free(stacks); + return(-1); + } + } + } + for (i=0; iN; i++) + { + if ( V->signers[i].siglen != 0 ) + { + plen = bitcoin_pubkeylen(V->signers[i].pubkey); + if ( V->spendscript[0] != plen || V->spendscript[V->spendlen - 1] != IGUANA_OP_CHECKSIG || bitcoin_pubkeylen(&V->spendscript[1]) <= 0 ) + iguana_pushdata(stacks,0,V->signers[i].pubkey,plen); + } + } + if ( V->extras != 0 ) + { + if ( (n= cJSON_GetArraySize(V->extras)) > 0 ) + { + for (i=0; iextras,i),0)) != 0 && (len= is_hexstr(hexstr,0)) > 0 ) + { + len >>= 1; + decode_hex(databuf,len,hexstr); + iguana_pushdata(stacks,0,databuf,len); + } + } + } + } + } else memset(stacks,0,sizeof(*stacks)); + stacks->lastpath[0] = 1; + k = numops = numused = 0; + script[k] = 0; + while ( (c= *str++) != 0 ) + { + if ( is_delim(c) != 0 ) + { + //if ( c == 0 ) + // break; + continue; + } + if ( c == '/' && *str == '/' ) // support // + break; + else if ( c == '-' && *str == '1' && is_delim(str[1]) != 0 ) + { + script[k++] = IGUANA_OP_1NEGATE, str += 3; // OP_1NEGATE; + iguana_pushdata(stacks,-1,0,0); + continue; + } + else if ( c == '%' && *str == 's' ) + { + str++; + if ( numused < numvars && (hexstr= jstr(jitem(array,numused++),0)) != 0 ) + { + if ( (n= iguana_dataparse(stacks,script,k,str,&len)) > 0 ) + { + k += n; + continue; + } + } + printf("dataparse error.%d, numused.%d >= numvars.%d\n",n,numused,numvars); + errs++; + break; + } + else + { + str--; + if ( (n= iguana_dataparse(stacks,script,k,str,&len)) > 0 ) + { + k += n; + str += len; + continue; + } + else if ( n < 0 ) + { + errs++; + break; + } + } + for (j=0; j<32; j++) + if ( is_delim(str[j]) != 0 ) + break; + if ( j == 32 ) + { + printf("too long opcode.%s at offset.%ld\n",str,(long)str-(long)asmstr); + errs++; + break; + } + HASH_FIND(hh,OPTABLE,str,j,op); + str += j; + if ( op != 0 ) + { + if ( numargs > 0 ) + { + for (i=0; iopcode <= IGUANA_OP_16 || ++numops <= MAX_OPS_PER_SCRIPT ) + { + script[k++] = op->opcode; + if ( stacks->logarray ) + jaddistr(stacks->logarray,(char *)op->hh.key); + if ( (op->flags & IGUANA_ALWAYSILLEGAL) != 0 ) + { + printf("disabled opcode.%s at offset.%ld\n",str,(long)str-(long)asmstr); + errs++; + break; + } + else if ( op->extralen > 0 ) + { + if ( is_delim(*str) != 0 ) + str++; + if ( is_hexstr(str,0) != (op->extralen<<1) ) + { + printf("expected extralen.%d of hex, got.(%s) at offset.%ld\n",op->extralen,str,(long)str-(long)asmstr); + errs++; + break; + } + decode_hex(&script[k],op->extralen,str), str += (op->extralen << 1); + if ( op->extralen == 1 ) + iguana_pushdata(stacks,script[k],0,0); + else if ( op->extralen == 2 ) + iguana_pushdata(stacks,script[k] + ((uint32_t)script[k]<<8),0,0); + k += op->extralen; + continue; + } + if ( interpret == 0 || V == 0 ) + continue; + if ( (numargs= op->stackitems) > 0 ) + { + if ( stacks->stackdepth < op->stackitems ) + { + printf("stackdepth.%d needed.%d (%s) at offset.%ld\n",stacks->stackdepth,op->stackitems,str,(long)str-(long)asmstr); + errs++; + break; + } + for (i=0; iflags & IGUANA_NOPFLAG) != 0 ) + continue; + if ( (op->flags & IGUANA_CONTROLFLAG) != 0 ) + { + switch ( op->opcode ) + { + case IGUANA_OP_IF: case IGUANA_OP_NOTIF: + if ( stacks->ifdepth >= IGUANA_MAXSTACKDEPTH ) + { + printf("ifdepth.%d >= MAXSTACKDEPTH.%d\n",stacks->ifdepth,IGUANA_MAXSTACKDEPTH); + errs++; + } + else + { + if ( iguana_isnonz(args[0]) == (op->opcode == IGUANA_OP_IF) ) + val = 1; + else val = -1; + stacks->lastpath[++stacks->ifdepth] = val; + } + break; + case IGUANA_OP_ELSE: + if ( stacks->ifdepth <= stacks->elsedepth ) + { + printf("unhandled opcode.%02x stacks->ifdepth %d <= %d stacks->elsedepth\n",op->opcode,stacks->ifdepth,stacks->elsedepth); + errs++; + } + stacks->lastpath[stacks->ifdepth] *= -1; + break; + case IGUANA_OP_ENDIF: + if ( stacks->ifdepth <= 0 ) + { + printf("endif without if offset.%ld\n",(long)str-(long)asmstr); + errs++; + } + stacks->ifdepth--; + break; + case IGUANA_OP_VERIFY: break; + case IGUANA_OP_RETURN: + iguana_pushdata(stacks,0,0,0); + errs++; + break; + } + if ( errs != 0 ) + break; + continue; + } + if ( stacks->lastpath[stacks->ifdepth] < 0 ) + { + if ( stacks->logarray ) + jaddistr(stacks->logarray,"skip"); + continue; + } + else if ( (op->flags & IGUANA_EXECUTIONILLEGAL) != 0 ) + { + printf("opcode not allowed to run.%s at %ld\n",(char *)op->hh.key,(long)str-(long)asmstr); + errs++; + break; + } + else if ( op->opcode == IGUANA_OP_EQUALVERIFY || op->opcode == IGUANA_OP_EQUAL ) + { + if ( iguana_cmp(&args[0],&args[1]) == 0 ) + iguana_pushdata(stacks,1,0,0); + else iguana_pushdata(stacks,0,0,0); + } + else if ( (op->flags & IGUANA_CRYPTOFLAG) != 0 ) + { + uint8_t rmd160[20]; bits256 hash; + datalen = iguana_databuf(databuf,args[0]); + switch ( op->opcode ) + { + case IGUANA_OP_RIPEMD160: + calc_rmd160(0,rmd160,databuf,datalen); + iguana_pushdata(stacks,0,rmd160,sizeof(rmd160)); + break; + case IGUANA_OP_SHA1: + calc_sha1(0,rmd160,databuf,datalen); + iguana_pushdata(stacks,0,rmd160,sizeof(rmd160)); + break; + case IGUANA_OP_HASH160: + calc_rmd160_sha256(rmd160,databuf,datalen); + iguana_pushdata(stacks,0,rmd160,sizeof(rmd160)); + break; + case IGUANA_OP_SHA256: + vcalc_sha256(0,hash.bytes,databuf,datalen); + iguana_pushdata(stacks,0,hash.bytes,sizeof(hash)); + break; + case IGUANA_OP_HASH256: + hash = bits256_doublesha256(0,databuf,datalen); + iguana_pushdata(stacks,0,hash.bytes,sizeof(hash)); + break; + case IGUANA_OP_CHECKSIG: case IGUANA_OP_CHECKSIGVERIFY: + iguana_pushdata(stacks,iguana_checksig(coin,args[1],args[0],V->sigtxid),0,0); + break; + case IGUANA_OP_CHECKMULTISIG: case IGUANA_OP_CHECKMULTISIGVERIFY: + iguana_pushdata(stacks,iguana_checkmultisig(coin,stacks,V->M,V->N,V->sigtxid),0,0); + break; + } + } + else if ( op->opcode == IGUANA_OP_CHECKLOCKTIMEVERIFY ) // former OP_NOP2 + { + if ( iguana_checklocktimeverify(coin,nLockTime,V->sequence,args[0]) < 0 ) + { + iguana_stack(stacks,args,1,"0",""); + errs++; + break; + } + iguana_stack(stacks,args,1,"0",""); + continue; + } + else if ( op->opcode == IGUANA_OP_CHECKSEQUENCEVERIFY ) // former OP_NOP3 + { + if ( iguana_checksequenceverify(coin,nLockTime,V->sequence,args[0]) < 0 ) + { + iguana_stack(stacks,args,1,"0",""); + errs++; + break; + } + iguana_stack(stacks,args,1,"0",""); + continue; + } + else if ( (op->flags & IGUANA_STACKFLAG) != 0 ) + { + if ( op->opcode == IGUANA_OP_PICK || op->opcode == IGUANA_OP_ROLL ) + { + if ( interpret != 0 && stacks->stackdepth < (val= iguana_num(args[0])) ) + { + printf("stack not deep enough %d < %d\n",stacks->stackdepth,iguana_num(args[0])); + errs++; + break; + } + if ( op->opcode == IGUANA_OP_PICK ) + { + stacks->stack[stacks->stackdepth] = iguana_clone(stacks->stack[stacks->stackdepth - 1 - val]); + stacks->stackdepth++; + } + else + { + args[1] = stacks->stack[stacks->stackdepth - 1 - val]; + for (i=stacks->stackdepth-1-val; istackdepth-1; i++) + stacks->stack[i] = stacks->stack[i+1]; + stacks->stack[stacks->stackdepth - 1] = args[1]; + } + } + else + { + switch ( op->opcode ) + { + case IGUANA_OP_TOALTSTACK: + if ( stacks->altstackdepth < stacks->maxstackdepth ) + { + iguana_altpush(stacks,args[0]); + memset(&args[0],0,sizeof(args[0])); + } + else + { + printf("altstack overflow %d vs %d\n",stacks->altstackdepth,stacks->maxstackdepth); + errs++; + } + break; + case IGUANA_OP_FROMALTSTACK: + stacks->stack[stacks->stackdepth++] = iguana_altpop(stacks); + break; + case IGUANA_OP_DEPTH: iguana_pushdata(stacks,stacks->stackdepth,0,0); break; + case IGUANA_OP_DROP: case IGUANA_OP_2DROP: break; + case IGUANA_OP_3DUP: iguana_stack(stacks,args,3,"012","012"); break; + case IGUANA_OP_2OVER: iguana_stack(stacks,args,4,"0123","01"); break; + case IGUANA_OP_2ROT: iguana_stack(stacks,args,6,"234501",""); break; + case IGUANA_OP_2SWAP: iguana_stack(stacks,args,4,"2301",""); break; + case IGUANA_OP_IFDUP: + if ( iguana_isnonz(args[0]) != 0 ) + iguana_stack(stacks,args,0,"","0"); + iguana_stack(stacks,args,1,"0",""); + break; + case IGUANA_OP_DUP: iguana_stack(stacks,args,1,"0","0"); break; + case IGUANA_OP_2DUP: iguana_stack(stacks,args,2,"01","01"); break; + case IGUANA_OP_NIP: + if ( args[0].data != 0 ) + free(args[0].data); + iguana_stack(stacks,args,2,"1",""); + break; + case IGUANA_OP_OVER: iguana_stack(stacks,args,2,"01","0"); break; + case IGUANA_OP_ROT: iguana_stack(stacks,args,3,"120",""); break; + case IGUANA_OP_SWAP: iguana_stack(stacks,args,2,"10",""); break; + case IGUANA_OP_TUCK: iguana_stack(stacks,args,2,"10","1"); break; + } + } + } + else if ( (op->flags & IGUANA_MATHFLAG) != 0 ) + { + int32_t numA,numB,numC; + for (i=0; istackitems; i++) + { + if ( args[i].size != sizeof(int32_t) ) + break; + if ( i == 0 ) + numA = iguana_num(args[i]); + else if ( i == 1 ) + numB = iguana_num(args[i]); + else if ( i == 2 ) + numC = iguana_num(args[i]); + } + if ( i != op->stackitems ) + { + printf("math script non-int32_t arg[%d] of %d\n",i,op->stackitems); + errs++; + break; + } + switch ( op->opcode ) + { + case IGUANA_OP_1ADD: iguana_pushdata(stacks,numA + 1,0,0); break; + case IGUANA_OP_1SUB: iguana_pushdata(stacks,numA - 1,0,0); break; + case IGUANA_OP_NEGATE: iguana_pushdata(stacks,-numA,0,0); break; + case IGUANA_OP_ABS: iguana_pushdata(stacks,numA<0?-numA:numA,0,0); break; + case IGUANA_OP_NOT: iguana_pushdata(stacks,numA == 0,0,0); break; + case IGUANA_OP_0NOTEQUAL: iguana_pushdata(stacks,numA != 0,0,0); break; + case IGUANA_OP_ADD: iguana_pushdata(stacks,numA + numB,0,0); break; + case IGUANA_OP_SUB: iguana_pushdata(stacks,numA - numB,0,0); break; + case IGUANA_OP_BOOLAND:iguana_pushdata(stacks,numA != 0 && numB != 0,0,0); break; + case IGUANA_OP_BOOLOR: iguana_pushdata(stacks,numA != 0 || numB != 0,0,0); break; + case IGUANA_OP_NUMEQUAL: case IGUANA_OP_NUMEQUALVERIFY: + iguana_pushdata(stacks,numA == numB,0,0); break; + case IGUANA_OP_NUMNOTEQUAL:iguana_pushdata(stacks,numA != numB,0,0); break; + case IGUANA_OP_LESSTHAN: iguana_pushdata(stacks,numA < numB,0,0); break; + case IGUANA_OP_GREATERTHAN:iguana_pushdata(stacks,numA > numB,0,0); break; + case IGUANA_OP_LESSTHANOREQUAL:iguana_pushdata(stacks,numA <= numB,0,0); break; + case IGUANA_OP_GREATERTHANOREQUAL:iguana_pushdata(stacks,numA >= numB,0,0); break; + case IGUANA_OP_MIN: iguana_pushdata(stacks,numA <= numB ? numA : numB,0,0); break; + case IGUANA_OP_MAX: iguana_pushdata(stacks,numA >= numB ? numA : numB,0,0); break; + case IGUANA_OP_WITHIN: iguana_pushdata(stacks,numB <= numA && numA < numC,0,0); break; + } + } + else if ( op->opcode == IGUANA_OP_CODESEPARATOR ) + { + if ( stacks != 0 ) + stacks->codeseparator = k; + continue; + } + else + { + printf("unhandled opcode.%02x (%s)\n",op->opcode,str); + errs++; + break; + } + if ( (op->flags & IGUANA_POSTVERIFY) != 0 ) + { + if ( stacks->stackdepth < 1 ) + { + printf("empty stack at offset.%ld\n",(long)str - (long)asmstr); + errs++; + break; + } + if ( iguana_isnonz(stacks->stack[stacks->stackdepth-1]) == 0 ) + break; + } + } + else + { + printf("too many ops opcode.%s at offset.%ld\n",str,(long)str - (long)asmstr); + errs++; + break; + } + } + else + { + printf("unknown opcode.%s at offset.%ld\n",str,(long)str - (long)asmstr); + errs++; + break; + } + } + if ( stacks != &STACKS ) + { + if ( jobj(interpreter,"result") != 0 ) + jdelete(interpreter,"result"); + if ( stacks->stackdepth <= 0 ) + { + errs++; + printf("empty stack error\n"); + jadd(interpreter,"result",jfalse()); + } + else if ( iguana_isnonz(stacks->stack[--stacks->stackdepth]) != 0 ) + { + printf("Evaluate true, depth.%d errs.%d\n",stacks->stackdepth,errs); + jadd(interpreter,"result",jtrue()); + } + if ( stacks->logarray != 0 ) + printf("LOG.(%s)\n",jprint(stacks->logarray,1)); + if ( numargs > 0 ) + { + for (i=0; i& stack) +{ + if (stack.empty()) + throw runtime_error("popstack(): stack empty"); + stack.pop_back(); +} + +bool static IsCompressedOrUncompressedPubKey(const valtype &vchPubKey) { + if (vchPubKey.size() < 33) { + // Non-canonical public key: too short + return false; + } + if (vchPubKey[0] == 0x04) { + if (vchPubKey.size() != 65) { + // Non-canonical public key: invalid length for uncompressed key + return false; + } + } else if (vchPubKey[0] == 0x02 || vchPubKey[0] == 0x03) { + if (vchPubKey.size() != 33) { + // Non-canonical public key: invalid length for compressed key + return false; + } + } else { + // Non-canonical public key: neither compressed nor uncompressed + return false; + } + return true; +} + +/** + * A canonical signature exists of: <30> <02> <02> + * Where R and S are not negative (their first byte has its highest bit not set), and not + * excessively padded (do not start with a 0 byte, unless an otherwise negative number follows, + * in which case a single 0 byte is necessary and even required). + * + * See https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623 + * + * This function is consensus-critical since BIP66. + */ +bool static IsValidSignatureEncoding(const std::vector &sig) { + // Format: 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S] [sighash] + // * total-length: 1-byte length descriptor of everything that follows, + // excluding the sighash byte. + // * R-length: 1-byte length descriptor of the R value that follows. + // * R: arbitrary-length big-endian encoded R value. It must use the shortest + // possible encoding for a positive integers (which means no null bytes at + // the start, except a single one when the next byte has its highest bit set). + // * S-length: 1-byte length descriptor of the S value that follows. + // * S: arbitrary-length big-endian encoded S value. The same rules apply. + // * sighash: 1-byte value indicating what data is hashed (not part of the DER + // signature) + + // Minimum and maximum size constraints. + if (sig.size() < 9) return false; + if (sig.size() > 73) return false; + + // A signature is of type 0x30 (compound). + if (sig[0] != 0x30) return false; + + // Make sure the length covers the entire signature. + if (sig[1] != sig.size() - 3) return false; + + // Extract the length of the R element. + unsigned int lenR = sig[3]; + + // Make sure the length of the S element is still inside the signature. + if (5 + lenR >= sig.size()) return false; + + // Extract the length of the S element. + unsigned int lenS = sig[5 + lenR]; + + // Verify that the length of the signature matches the sum of the length + // of the elements. + if ((size_t)(lenR + lenS + 7) != sig.size()) return false; + + // Check whether the R element is an integer. + if (sig[2] != 0x02) return false; + + // Zero-length integers are not allowed for R. + if (lenR == 0) return false; + + // Negative numbers are not allowed for R. + if (sig[4] & 0x80) return false; + + // Null bytes at the start of R are not allowed, unless R would + // otherwise be interpreted as a negative number. + if (lenR > 1 && (sig[4] == 0x00) && !(sig[5] & 0x80)) return false; + + // Check whether the S element is an integer. + if (sig[lenR + 4] != 0x02) return false; + + // Zero-length integers are not allowed for S. + if (lenS == 0) return false; + + // Negative numbers are not allowed for S. + if (sig[lenR + 6] & 0x80) return false; + + // Null bytes at the start of S are not allowed, unless S would otherwise be + // interpreted as a negative number. + if (lenS > 1 && (sig[lenR + 6] == 0x00) && !(sig[lenR + 7] & 0x80)) return false; + + return true; +} + +bool static IsLowDERSignature(const valtype &vchSig, ScriptError* serror) { + if (!IsValidSignatureEncoding(vchSig)) { + return set_error(serror, SCRIPT_ERR_SIG_DER); + } + std::vector vchSigCopy(vchSig.begin(), vchSig.begin() + vchSig.size() - 1); + if (!CPubKey::CheckLowS(vchSigCopy)) { + return set_error(serror, SCRIPT_ERR_SIG_HIGH_S); + } + return true; +} + +bool static IsDefinedHashtypeSignature(const valtype &vchSig) { + if (vchSig.size() == 0) { + return false; + } + unsigned char nHashType = vchSig[vchSig.size() - 1] & (~(SIGHASH_ANYONECANPAY)); + if (nHashType < SIGHASH_ALL || nHashType > SIGHASH_SINGLE) + return false; + + return true; +} + +bool CheckSignatureEncoding(const vector &vchSig, unsigned int flags, ScriptError* serror) { + // Empty signature. Not strictly DER encoded, but allowed to provide a + // compact way to provide an invalid signature for use with CHECK(MULTI)SIG + if (vchSig.size() == 0) { + return true; + } + if ((flags & (SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC)) != 0 && !IsValidSignatureEncoding(vchSig)) { + return set_error(serror, SCRIPT_ERR_SIG_DER); + } else if ((flags & SCRIPT_VERIFY_LOW_S) != 0 && !IsLowDERSignature(vchSig, serror)) { + // serror is set + return false; + } else if ((flags & SCRIPT_VERIFY_STRICTENC) != 0 && !IsDefinedHashtypeSignature(vchSig)) { + return set_error(serror, SCRIPT_ERR_SIG_HASHTYPE); + } + return true; +} + +bool static CheckPubKeyEncoding(const valtype &vchSig, unsigned int flags, ScriptError* serror) { + if ((flags & SCRIPT_VERIFY_STRICTENC) != 0 && !IsCompressedOrUncompressedPubKey(vchSig)) { + return set_error(serror, SCRIPT_ERR_PUBKEYTYPE); + } + return true; +} + +bool static CheckMinimalPush(const valtype& data, opcodetype opcode) { + if (data.size() == 0) { + // Could have used OP_0. + return opcode == OP_0; + } else if (data.size() == 1 && data[0] >= 1 && data[0] <= 16) { + // Could have used OP_1 .. OP_16. + return opcode == OP_1 + (data[0] - 1); + } else if (data.size() == 1 && data[0] == 0x81) { + // Could have used OP_1NEGATE. + return opcode == OP_1NEGATE; + } else if (data.size() <= 75) { + // Could have used a direct push (opcode indicating number of bytes pushed + those bytes). + return opcode == data.size(); + } else if (data.size() <= 255) { + // Could have used OP_PUSHDATA. + return opcode == OP_PUSHDATA1; + } else if (data.size() <= 65535) { + // Could have used OP_PUSHDATA2. + return opcode == OP_PUSHDATA2; + } + return true; +} + +bool EvalScript(vector >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror) +{ + static const CScriptNum bnZero(0); + static const CScriptNum bnOne(1); + static const CScriptNum bnFalse(0); + static const CScriptNum bnTrue(1); + static const valtype vchFalse(0); + static const valtype vchZero(0); + static const valtype vchTrue(1, 1); + + CScript::const_iterator pc = script.begin(); + CScript::const_iterator pend = script.end(); + CScript::const_iterator pbegincodehash = script.begin(); + opcodetype opcode; + valtype vchPushValue; + vector vfExec; + vector altstack; + set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR); + if (script.size() > 10000) + return set_error(serror, SCRIPT_ERR_SCRIPT_SIZE); + int nOpCount = 0; + bool fRequireMinimal = (flags & SCRIPT_VERIFY_MINIMALDATA) != 0; + + try + { + while (pc < pend) + { + bool fExec = !count(vfExec.begin(), vfExec.end(), false); + + // + // Read instruction + // + if (!script.GetOp(pc, opcode, vchPushValue)) + return set_error(serror, SCRIPT_ERR_BAD_OPCODE); + if (vchPushValue.size() > MAX_SCRIPT_ELEMENT_SIZE) + return set_error(serror, SCRIPT_ERR_PUSH_SIZE); + + // Note how OP_RESERVED does not count towards the opcode limit. + if (opcode > OP_16 && ++nOpCount > MAX_OPS_PER_SCRIPT) + return set_error(serror, SCRIPT_ERR_OP_COUNT); + + if (opcode == OP_CAT || + opcode == OP_SUBSTR || + opcode == OP_LEFT || + opcode == OP_RIGHT || + opcode == OP_INVERT || + opcode == OP_AND || + opcode == OP_OR || + opcode == OP_XOR || + opcode == OP_2MUL || + opcode == OP_2DIV || + opcode == OP_MUL || + opcode == OP_DIV || + opcode == OP_MOD || + opcode == OP_LSHIFT || + opcode == OP_RSHIFT) + return set_error(serror, SCRIPT_ERR_DISABLED_OPCODE); // Disabled opcodes. + + if (fExec && 0 <= opcode && opcode <= OP_PUSHDATA4) { + if (fRequireMinimal && !CheckMinimalPush(vchPushValue, opcode)) { + return set_error(serror, SCRIPT_ERR_MINIMALDATA); + } + stack.push_back(vchPushValue); + } else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF)) + switch (opcode) + { + // + // Push value + // + case OP_1NEGATE: + case OP_1: + case OP_2: + case OP_3: + case OP_4: + case OP_5: + case OP_6: + case OP_7: + case OP_8: + case OP_9: + case OP_10: + case OP_11: + case OP_12: + case OP_13: + case OP_14: + case OP_15: + case OP_16: + { + // ( -- value) + CScriptNum bn((int)opcode - (int)(OP_1 - 1)); + stack.push_back(bn.getvch()); + // The result of these opcodes should always be the minimal way to push the data + // they push, so no need for a CheckMinimalPush here. + } + break; + + + // + // Control + // + case OP_NOP: + break; + + case OP_CHECKLOCKTIMEVERIFY: + { + if (!(flags & SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY)) { + // not enabled; treat as a NOP2 + if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) { + return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS); + } + break; + } + + if (stack.size() < 1) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + + // Note that elsewhere numeric opcodes are limited to + // operands in the range -2**31+1 to 2**31-1, however it is + // legal for opcodes to produce results exceeding that + // range. This limitation is implemented by CScriptNum's + // default 4-byte limit. + // + // If we kept to that limit we'd have a year 2038 problem, + // even though the nLockTime field in transactions + // themselves is uint32 which only becomes meaningless + // after the year 2106. + // + // Thus as a special case we tell CScriptNum to accept up + // to 5-byte bignums, which are good until 2**39-1, well + // beyond the 2**32-1 limit of the nLockTime field itself. + const CScriptNum nLockTime(stacktop(-1), fRequireMinimal, 5); + + // In the rare event that the argument may be < 0 due to + // some arithmetic being done first, you can always use + // 0 MAX CHECKLOCKTIMEVERIFY. + if (nLockTime < 0) + return set_error(serror, SCRIPT_ERR_NEGATIVE_LOCKTIME); + + // Actually compare the specified lock time with the transaction. + if (!checker.CheckLockTime(nLockTime)) + return set_error(serror, SCRIPT_ERR_UNSATISFIED_LOCKTIME); + + break; + } + + case OP_NOP1: case OP_NOP3: case OP_NOP4: case OP_NOP5: + case OP_NOP6: case OP_NOP7: case OP_NOP8: case OP_NOP9: case OP_NOP10: + { + if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) + return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS); + } + break; + + case OP_IF: + case OP_NOTIF: + { + // if [statements] [else [statements]] endif + bool fValue = false; + if (fExec) + { + if (stack.size() < 1) + return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL); + valtype& vch = stacktop(-1); + fValue = CastToBool(vch); + if (opcode == OP_NOTIF) + fValue = !fValue; + popstack(stack); + } + vfExec.push_back(fValue); + } + break; + + case OP_ELSE: + { + if (vfExec.empty()) + return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL); + vfExec.back() = !vfExec.back(); + } + break; + + case OP_ENDIF: + { + if (vfExec.empty()) + return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL); + vfExec.pop_back(); + } + break; + + case OP_VERIFY: + { + // (true -- ) or + // (false -- false) and return + if (stack.size() < 1) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + bool fValue = CastToBool(stacktop(-1)); + if (fValue) + popstack(stack); + else + return set_error(serror, SCRIPT_ERR_VERIFY); + } + break; + + case OP_RETURN: + { + return set_error(serror, SCRIPT_ERR_OP_RETURN); + } + break; + + + // + // Stack ops + // + case OP_TOALTSTACK: + { + if (stack.size() < 1) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + altstack.push_back(stacktop(-1)); + popstack(stack); + } + break; + + case OP_FROMALTSTACK: + { + if (altstack.size() < 1) + return set_error(serror, SCRIPT_ERR_INVALID_ALTSTACK_OPERATION); + stack.push_back(altstacktop(-1)); + popstack(altstack); + } + break; + + case OP_2DROP: + { + // (x1 x2 -- ) + if (stack.size() < 2) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + popstack(stack); + popstack(stack); + } + break; + + case OP_2DUP: + { + // (x1 x2 -- x1 x2 x1 x2) + if (stack.size() < 2) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + valtype vch1 = stacktop(-2); + valtype vch2 = stacktop(-1); + stack.push_back(vch1); + stack.push_back(vch2); + } + break; + + case OP_3DUP: + { + // (x1 x2 x3 -- x1 x2 x3 x1 x2 x3) + if (stack.size() < 3) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + valtype vch1 = stacktop(-3); + valtype vch2 = stacktop(-2); + valtype vch3 = stacktop(-1); + stack.push_back(vch1); + stack.push_back(vch2); + stack.push_back(vch3); + } + break; + + case OP_2OVER: + { + // (x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2) + if (stack.size() < 4) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + valtype vch1 = stacktop(-4); + valtype vch2 = stacktop(-3); + stack.push_back(vch1); + stack.push_back(vch2); + } + break; + + case OP_2ROT: + { + // (x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2) + if (stack.size() < 6) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + valtype vch1 = stacktop(-6); + valtype vch2 = stacktop(-5); + stack.erase(stack.end()-6, stack.end()-4); + stack.push_back(vch1); + stack.push_back(vch2); + } + break; + + case OP_2SWAP: + { + // (x1 x2 x3 x4 -- x3 x4 x1 x2) + if (stack.size() < 4) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + swap(stacktop(-4), stacktop(-2)); + swap(stacktop(-3), stacktop(-1)); + } + break; + + case OP_IFDUP: + { + // (x - 0 | x x) + if (stack.size() < 1) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + valtype vch = stacktop(-1); + if (CastToBool(vch)) + stack.push_back(vch); + } + break; + + case OP_DEPTH: + { + // -- stacksize + CScriptNum bn(stack.size()); + stack.push_back(bn.getvch()); + } + break; + + case OP_DROP: + { + // (x -- ) + if (stack.size() < 1) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + popstack(stack); + } + break; + + case OP_DUP: + { + // (x -- x x) + if (stack.size() < 1) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + valtype vch = stacktop(-1); + stack.push_back(vch); + } + break; + + case OP_NIP: + { + // (x1 x2 -- x2) + if (stack.size() < 2) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + stack.erase(stack.end() - 2); + } + break; + + case OP_OVER: + { + // (x1 x2 -- x1 x2 x1) + if (stack.size() < 2) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + valtype vch = stacktop(-2); + stack.push_back(vch); + } + break; + + case OP_PICK: + case OP_ROLL: + { + // (xn ... x2 x1 x0 n - xn ... x2 x1 x0 xn) + // (xn ... x2 x1 x0 n - ... x2 x1 x0 xn) + if (stack.size() < 2) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + int n = CScriptNum(stacktop(-1), fRequireMinimal).getint(); + popstack(stack); + if (n < 0 || n >= (int)stack.size()) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + valtype vch = stacktop(-n-1); + if (opcode == OP_ROLL) + stack.erase(stack.end()-n-1); + stack.push_back(vch); + } + break; + + case OP_ROT: + { + // (x1 x2 x3 -- x2 x3 x1) + // x2 x1 x3 after first swap + // x2 x3 x1 after second swap + if (stack.size() < 3) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + swap(stacktop(-3), stacktop(-2)); + swap(stacktop(-2), stacktop(-1)); + } + break; + + case OP_SWAP: + { + // (x1 x2 -- x2 x1) + if (stack.size() < 2) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + swap(stacktop(-2), stacktop(-1)); + } + break; + + case OP_TUCK: + { + // (x1 x2 -- x2 x1 x2) + if (stack.size() < 2) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + valtype vch = stacktop(-1); + stack.insert(stack.end()-2, vch); + } + break; + + + case OP_SIZE: + { + // (in -- in size) + if (stack.size() < 1) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + CScriptNum bn(stacktop(-1).size()); + stack.push_back(bn.getvch()); + } + break; + + + // + // Bitwise logic + // + case OP_EQUAL: + case OP_EQUALVERIFY: + //case OP_NOTEQUAL: // use OP_NUMNOTEQUAL + { + // (x1 x2 - bool) + if (stack.size() < 2) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + valtype& vch1 = stacktop(-2); + valtype& vch2 = stacktop(-1); + bool fEqual = (vch1 == vch2); + // OP_NOTEQUAL is disabled because it would be too easy to say + // something like n != 1 and have some wiseguy pass in 1 with extra + // zero bytes after it (numerically, 0x01 == 0x0001 == 0x000001) + //if (opcode == OP_NOTEQUAL) + // fEqual = !fEqual; + popstack(stack); + popstack(stack); + stack.push_back(fEqual ? vchTrue : vchFalse); + if (opcode == OP_EQUALVERIFY) + { + if (fEqual) + popstack(stack); + else + return set_error(serror, SCRIPT_ERR_EQUALVERIFY); + } + } + break; + + + // + // Numeric + // + case OP_1ADD: + case OP_1SUB: + case OP_NEGATE: + case OP_ABS: + case OP_NOT: + case OP_0NOTEQUAL: + { + // (in -- out) + if (stack.size() < 1) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + CScriptNum bn(stacktop(-1), fRequireMinimal); + switch (opcode) + { + case OP_1ADD: bn += bnOne; break; + case OP_1SUB: bn -= bnOne; break; + case OP_NEGATE: bn = -bn; break; + case OP_ABS: if (bn < bnZero) bn = -bn; break; + case OP_NOT: bn = (bn == bnZero); break; + case OP_0NOTEQUAL: bn = (bn != bnZero); break; + default: assert(!"invalid opcode"); break; + } + popstack(stack); + stack.push_back(bn.getvch()); + } + break; + + case OP_ADD: + case OP_SUB: + case OP_BOOLAND: + case OP_BOOLOR: + case OP_NUMEQUAL: + case OP_NUMEQUALVERIFY: + case OP_NUMNOTEQUAL: + case OP_LESSTHAN: + case OP_GREATERTHAN: + case OP_LESSTHANOREQUAL: + case OP_GREATERTHANOREQUAL: + case OP_MIN: + case OP_MAX: + { + // (x1 x2 -- out) + if (stack.size() < 2) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + CScriptNum bn1(stacktop(-2), fRequireMinimal); + CScriptNum bn2(stacktop(-1), fRequireMinimal); + CScriptNum bn(0); + switch (opcode) + { + case OP_ADD: + bn = bn1 + bn2; + break; + + case OP_SUB: + bn = bn1 - bn2; + break; + + case OP_BOOLAND: bn = (bn1 != bnZero && bn2 != bnZero); break; + case OP_BOOLOR: bn = (bn1 != bnZero || bn2 != bnZero); break; + case OP_NUMEQUAL: bn = (bn1 == bn2); break; + case OP_NUMEQUALVERIFY: bn = (bn1 == bn2); break; + case OP_NUMNOTEQUAL: bn = (bn1 != bn2); break; + case OP_LESSTHAN: bn = (bn1 < bn2); break; + case OP_GREATERTHAN: bn = (bn1 > bn2); break; + case OP_LESSTHANOREQUAL: bn = (bn1 <= bn2); break; + case OP_GREATERTHANOREQUAL: bn = (bn1 >= bn2); break; + case OP_MIN: bn = (bn1 < bn2 ? bn1 : bn2); break; + case OP_MAX: bn = (bn1 > bn2 ? bn1 : bn2); break; + default: assert(!"invalid opcode"); break; + } + popstack(stack); + popstack(stack); + stack.push_back(bn.getvch()); + + if (opcode == OP_NUMEQUALVERIFY) + { + if (CastToBool(stacktop(-1))) + popstack(stack); + else + return set_error(serror, SCRIPT_ERR_NUMEQUALVERIFY); + } + } + break; + + case OP_WITHIN: + { + // (x min max -- out) + if (stack.size() < 3) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + CScriptNum bn1(stacktop(-3), fRequireMinimal); + CScriptNum bn2(stacktop(-2), fRequireMinimal); + CScriptNum bn3(stacktop(-1), fRequireMinimal); + bool fValue = (bn2 <= bn1 && bn1 < bn3); + popstack(stack); + popstack(stack); + popstack(stack); + stack.push_back(fValue ? vchTrue : vchFalse); + } + break; + + + // + // Crypto + // + case OP_RIPEMD160: + case OP_SHA1: + case OP_SHA256: + case OP_HASH160: + case OP_HASH256: + { + // (in -- hash) + if (stack.size() < 1) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + valtype& vch = stacktop(-1); + valtype vchHash((opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160) ? 20 : 32); + if (opcode == OP_RIPEMD160) + CRIPEMD160().Write(begin_ptr(vch), vch.size()).Finalize(begin_ptr(vchHash)); + else if (opcode == OP_SHA1) + CSHA1().Write(begin_ptr(vch), vch.size()).Finalize(begin_ptr(vchHash)); + else if (opcode == OP_SHA256) + CSHA256().Write(begin_ptr(vch), vch.size()).Finalize(begin_ptr(vchHash)); + else if (opcode == OP_HASH160) + CHash160().Write(begin_ptr(vch), vch.size()).Finalize(begin_ptr(vchHash)); + else if (opcode == OP_HASH256) + CHash256().Write(begin_ptr(vch), vch.size()).Finalize(begin_ptr(vchHash)); + popstack(stack); + stack.push_back(vchHash); + } + break; + + case OP_CODESEPARATOR: + { + // Hash starts after the code separator + pbegincodehash = pc; + } + break; + + case OP_CHECKSIG: + case OP_CHECKSIGVERIFY: + { + // (sig pubkey -- bool) + if (stack.size() < 2) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + + valtype& vchSig = stacktop(-2); + valtype& vchPubKey = stacktop(-1); + + // Subset of script starting at the most recent codeseparator + CScript scriptCode(pbegincodehash, pend); + + // Drop the signature, since there's no way for a signature to sign itself + scriptCode.FindAndDelete(CScript(vchSig)); + + if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, serror)) { + //serror is set + return false; + } + bool fSuccess = checker.CheckSig(vchSig, vchPubKey, scriptCode); + + popstack(stack); + popstack(stack); + stack.push_back(fSuccess ? vchTrue : vchFalse); + if (opcode == OP_CHECKSIGVERIFY) + { + if (fSuccess) + popstack(stack); + else + return set_error(serror, SCRIPT_ERR_CHECKSIGVERIFY); + } + } + break; + + case OP_CHECKMULTISIG: + case OP_CHECKMULTISIGVERIFY: + { + // ([sig ...] num_of_signatures [pubkey ...] num_of_pubkeys -- bool) + + int i = 1; + if ((int)stack.size() < i) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + + int nKeysCount = CScriptNum(stacktop(-i), fRequireMinimal).getint(); + if (nKeysCount < 0 || nKeysCount > MAX_PUBKEYS_PER_MULTISIG) + return set_error(serror, SCRIPT_ERR_PUBKEY_COUNT); + nOpCount += nKeysCount; + if (nOpCount > MAX_OPS_PER_SCRIPT) + return set_error(serror, SCRIPT_ERR_OP_COUNT); + int ikey = ++i; + i += nKeysCount; + if ((int)stack.size() < i) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + + int nSigsCount = CScriptNum(stacktop(-i), fRequireMinimal).getint(); + if (nSigsCount < 0 || nSigsCount > nKeysCount) + return set_error(serror, SCRIPT_ERR_SIG_COUNT); + int isig = ++i; + i += nSigsCount; + if ((int)stack.size() < i) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + + // Subset of script starting at the most recent codeseparator + CScript scriptCode(pbegincodehash, pend); + + // Drop the signatures, since there's no way for a signature to sign itself + for (int k = 0; k < nSigsCount; k++) + { + valtype& vchSig = stacktop(-isig-k); + scriptCode.FindAndDelete(CScript(vchSig)); + } + + bool fSuccess = true; + while (fSuccess && nSigsCount > 0) + { + valtype& vchSig = stacktop(-isig); + valtype& vchPubKey = stacktop(-ikey); + + // Note how this makes the exact order of pubkey/signature evaluation + // distinguishable by CHECKMULTISIG NOT if the STRICTENC flag is set. + // See the script_(in)valid tests for details. + if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, serror)) { + // serror is set + return false; + } + + // Check signature + bool fOk = checker.CheckSig(vchSig, vchPubKey, scriptCode); + + if (fOk) { + isig++; + nSigsCount--; + } + ikey++; + nKeysCount--; + + // If there are more signatures left than keys left, + // then too many signatures have failed. Exit early, + // without checking any further signatures. + if (nSigsCount > nKeysCount) + fSuccess = false; + } + + // Clean up stack of actual arguments + while (i-- > 1) + popstack(stack); + + // A bug causes CHECKMULTISIG to consume one extra argument + // whose contents were not checked in any way. + // + // Unfortunately this is a potential source of mutability, + // so optionally verify it is exactly equal to zero prior + // to removing it from the stack. + if (stack.size() < 1) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + if ((flags & SCRIPT_VERIFY_NULLDUMMY) && stacktop(-1).size()) + return set_error(serror, SCRIPT_ERR_SIG_NULLDUMMY); + popstack(stack); + + stack.push_back(fSuccess ? vchTrue : vchFalse); + + if (opcode == OP_CHECKMULTISIGVERIFY) + { + if (fSuccess) + popstack(stack); + else + return set_error(serror, SCRIPT_ERR_CHECKMULTISIGVERIFY); + } + } + break; + + default: + return set_error(serror, SCRIPT_ERR_BAD_OPCODE); + } + + // Size limits + if (stack.size() + altstack.size() > 1000) + return set_error(serror, SCRIPT_ERR_STACK_SIZE); + } + } + catch (...) + { + return set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR); + } + + if (!vfExec.empty()) + return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL); + + return set_success(serror); +} + +namespace { + + /** + * Wrapper that serializes like CTransaction, but with the modifications + * required for the signature hash done in-place + */ + class CTransactionSignatureSerializer { + private: + const CTransaction &txTo; //! reference to the spending transaction (the one being serialized) + const CScript &scriptCode; //! output script being consumed + const unsigned int nIn; //! input index of txTo being signed + const bool fAnyoneCanPay; //! whether the hashtype has the SIGHASH_ANYONECANPAY flag set + const bool fHashSingle; //! whether the hashtype is SIGHASH_SINGLE + const bool fHashNone; //! whether the hashtype is SIGHASH_NONE + + public: + CTransactionSignatureSerializer(const CTransaction &txToIn, const CScript &scriptCodeIn, unsigned int nInIn, int nHashTypeIn) : + txTo(txToIn), scriptCode(scriptCodeIn), nIn(nInIn), + fAnyoneCanPay(!!(nHashTypeIn & SIGHASH_ANYONECANPAY)), + fHashSingle((nHashTypeIn & 0x1f) == SIGHASH_SINGLE), + fHashNone((nHashTypeIn & 0x1f) == SIGHASH_NONE) {} + + /** Serialize the passed scriptCode, skipping OP_CODESEPARATORs */ + template + void SerializeScriptCode(S &s, int nType, int nVersion) const { + CScript::const_iterator it = scriptCode.begin(); + CScript::const_iterator itBegin = it; + opcodetype opcode; + unsigned int nCodeSeparators = 0; + while (scriptCode.GetOp(it, opcode)) { + if (opcode == OP_CODESEPARATOR) + nCodeSeparators++; + } + ::WriteCompactSize(s, scriptCode.size() - nCodeSeparators); + it = itBegin; + while (scriptCode.GetOp(it, opcode)) { + if (opcode == OP_CODESEPARATOR) { + s.write((char*)&itBegin[0], it-itBegin-1); + itBegin = it; + } + } + if (itBegin != scriptCode.end()) + s.write((char*)&itBegin[0], it-itBegin); + } + + /** Serialize an input of txTo */ + template + void SerializeInput(S &s, unsigned int nInput, int nType, int nVersion) const { + // In case of SIGHASH_ANYONECANPAY, only the input being signed is serialized + if (fAnyoneCanPay) + nInput = nIn; + // Serialize the prevout + ::Serialize(s, txTo.vin[nInput].prevout, nType, nVersion); + // Serialize the script + if (nInput != nIn) + // Blank out other inputs' signatures + ::Serialize(s, CScriptBase(), nType, nVersion); + else + SerializeScriptCode(s, nType, nVersion); + // Serialize the nSequence + if (nInput != nIn && (fHashSingle || fHashNone)) + // let the others update at will + ::Serialize(s, (int)0, nType, nVersion); + else + ::Serialize(s, txTo.vin[nInput].nSequence, nType, nVersion); + } + + /** Serialize an output of txTo */ + template + void SerializeOutput(S &s, unsigned int nOutput, int nType, int nVersion) const { + if (fHashSingle && nOutput != nIn) + // Do not lock-in the txout payee at other indices as txin + ::Serialize(s, CTxOut(), nType, nVersion); + else + ::Serialize(s, txTo.vout[nOutput], nType, nVersion); + } + + /** Serialize txTo */ + template + void Serialize(S &s, int nType, int nVersion) const { + // Serialize nVersion + ::Serialize(s, txTo.nVersion, nType, nVersion); + // Serialize vin + unsigned int nInputs = fAnyoneCanPay ? 1 : txTo.vin.size(); + ::WriteCompactSize(s, nInputs); + for (unsigned int nInput = 0; nInput < nInputs; nInput++) + SerializeInput(s, nInput, nType, nVersion); + // Serialize vout + unsigned int nOutputs = fHashNone ? 0 : (fHashSingle ? nIn+1 : txTo.vout.size()); + ::WriteCompactSize(s, nOutputs); + for (unsigned int nOutput = 0; nOutput < nOutputs; nOutput++) + SerializeOutput(s, nOutput, nType, nVersion); + // Serialize nLockTime + ::Serialize(s, txTo.nLockTime, nType, nVersion); + } + }; + +} // anon namespace + +uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, size_t* nHashedOut) +{ + static const uint256 one(uint256S("0000000000000000000000000000000000000000000000000000000000000001")); + if (nIn >= txTo.vin.size()) { + // nIn out of range + return one; + } + + // Check for invalid use of SIGHASH_SINGLE + if ((nHashType & 0x1f) == SIGHASH_SINGLE) { + if (nIn >= txTo.vout.size()) { + // nOut out of range + return one; + } + } + + // Wrapper to serialize only the necessary parts of the transaction being signed + CTransactionSignatureSerializer txTmp(txTo, scriptCode, nIn, nHashType); + + // Serialize and hash + CHashWriter ss(SER_GETHASH, 0); + ss << txTmp << nHashType; + if (nHashedOut != NULL) + *nHashedOut = ss.GetNumBytesHashed(); + return ss.GetHash(); +} + +bool TransactionSignatureChecker::VerifySignature(const std::vector& vchSig, const CPubKey& pubkey, const uint256& sighash) const +{ + return pubkey.Verify(sighash, vchSig); +} + +bool TransactionSignatureChecker::CheckSig(const vector& vchSigIn, const vector& vchPubKey, + const CScript& scriptCode) const +{ + CPubKey pubkey(vchPubKey); + if (!pubkey.IsValid()) + return false; + + // Hash type is one byte tacked on to the end of the signature + vector vchSig(vchSigIn); + if (vchSig.empty()) + return false; + int nHashType = vchSig.back(); + vchSig.pop_back(); + + size_t nHashed = 0; + uint256 sighash = SignatureHash(scriptCode, *txTo, nIn, nHashType, &nHashed); + nBytesHashed += nHashed; + ++nSigops; + + if (!VerifySignature(vchSig, pubkey, sighash)) + return false; + + return true; +} + +bool TransactionSignatureChecker::CheckLockTime(const CScriptNum& nLockTime) const +{ + // There are two kinds of nLockTime: lock-by-blockheight + // and lock-by-blocktime, distinguished by whether + // nLockTime < LOCKTIME_THRESHOLD. + // + // We want to compare apples to apples, so fail the script + // unless the type of nLockTime being tested is the same as + // the nLockTime in the transaction. + if (!( + (txTo->nLockTime < LOCKTIME_THRESHOLD && nLockTime < LOCKTIME_THRESHOLD) || + (txTo->nLockTime >= LOCKTIME_THRESHOLD && nLockTime >= LOCKTIME_THRESHOLD) + )) + return false; + + // Now that we know we're comparing apples-to-apples, the + // comparison is a simple numeric one. + if (nLockTime > (int64_t)txTo->nLockTime) + return false; + + // Finally the nLockTime feature can be disabled and thus + // CHECKLOCKTIMEVERIFY bypassed if every txin has been + // finalized by setting nSequence to maxint. The + // transaction would be allowed into the blockchain, making + // the opcode ineffective. + // + // Testing if this vin is not final is sufficient to + // prevent this condition. Alternatively we could test all + // inputs, but testing just this input minimizes the data + // required to prove correct CHECKLOCKTIMEVERIFY execution. + if (txTo->vin[nIn].IsFinal()) + return false; + + return true; +} + + +bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror) +{ + set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR); + + if ((flags & SCRIPT_VERIFY_SIGPUSHONLY) != 0 && !scriptSig.IsPushOnly()) { + return set_error(serror, SCRIPT_ERR_SIG_PUSHONLY); + } + + vector > stack, stackCopy; + if (!EvalScript(stack, scriptSig, flags, checker, serror)) + // serror is set + return false; + if (flags & SCRIPT_VERIFY_P2SH) + stackCopy = stack; + if (!EvalScript(stack, scriptPubKey, flags, checker, serror)) + // serror is set + return false; + if (stack.empty()) + return set_error(serror, SCRIPT_ERR_EVAL_FALSE); + if (CastToBool(stack.back()) == false) + return set_error(serror, SCRIPT_ERR_EVAL_FALSE); + + // Additional validation for spend-to-script-hash transactions: + if ((flags & SCRIPT_VERIFY_P2SH) && scriptPubKey.IsPayToScriptHash()) + { + // scriptSig must be literals-only or validation fails + if (!scriptSig.IsPushOnly()) + return set_error(serror, SCRIPT_ERR_SIG_PUSHONLY); + + // Restore stack. + swap(stack, stackCopy); + + // stack cannot be empty here, because if it was the + // P2SH HASH <> EQUAL scriptPubKey would be evaluated with + // an empty stack and the EvalScript above would return false. + assert(!stack.empty()); + + const valtype& pubKeySerialized = stack.back(); + CScript pubKey2(pubKeySerialized.begin(), pubKeySerialized.end()); + popstack(stack); + + if (!EvalScript(stack, pubKey2, flags, checker, serror)) + // serror is set + return false; + if (stack.empty()) + return set_error(serror, SCRIPT_ERR_EVAL_FALSE); + if (!CastToBool(stack.back())) + return set_error(serror, SCRIPT_ERR_EVAL_FALSE); + } + + // The CLEANSTACK check is only performed after potential P2SH evaluation, + // as the non-P2SH evaluation of a P2SH script will obviously not result in + // a clean stack (the P2SH inputs remain). + if ((flags & SCRIPT_VERIFY_CLEANSTACK) != 0) { + // Disallow CLEANSTACK without P2SH, as otherwise a switch CLEANSTACK->P2SH+CLEANSTACK + // would be possible, which is not a softfork (and P2SH should be one). + assert((flags & SCRIPT_VERIFY_P2SH) != 0); + if (stack.size() != 1) { + return set_error(serror, SCRIPT_ERR_CLEANSTACK); + } + } + + return set_success(serror); +} +#endif + diff --git a/iguana/iguana_json.c b/iguana/iguana_json.c index d1fe12e2e..2b74906c8 100755 --- a/iguana/iguana_json.c +++ b/iguana/iguana_json.c @@ -71,6 +71,15 @@ cJSON *helparray3(cJSON *array,cJSON *obj0,cJSON *obj1,cJSON *obj2) { jaddi(arra cJSON *helparray4(cJSON *array,cJSON *obj0,cJSON *obj1,cJSON *obj2,cJSON *obj3) { jaddi(array,obj0); return(helparray3(array,obj1,obj2,obj3)); } cJSON *helparray5(cJSON *array,cJSON *obj0,cJSON *obj1,cJSON *obj2,cJSON *obj3,cJSON *obj4) { jaddi(array,obj0); return(helparray4(array,obj1,obj2,obj3,obj4)); } cJSON *helparray6(cJSON *array,cJSON *obj0,cJSON *obj1,cJSON *obj2,cJSON *obj3,cJSON *obj4,cJSON *obj5) { jaddi(array,obj0); return(helparray5(array,obj1,obj2,obj3,obj4,obj5)); } +cJSON *helparray7(cJSON *array,cJSON *obj0,cJSON *obj1,cJSON *obj2,cJSON *obj3,cJSON *obj4,cJSON *obj5,cJSON *obj6) { jaddi(array,obj0); return(helparray6(array,obj1,obj2,obj3,obj4,obj5,obj6)); } +cJSON *helparray8(cJSON *array,cJSON *obj0,cJSON *obj1,cJSON *obj2,cJSON *obj3,cJSON *obj4,cJSON *obj5,cJSON *obj6,cJSON *obj7) { jaddi(array,obj0); return(helparray7(array,obj1,obj2,obj3,obj4,obj5,obj6,obj7)); } +cJSON *helparray9(cJSON *array,cJSON *obj0,cJSON *obj1,cJSON *obj2,cJSON *obj3,cJSON *obj4,cJSON *obj5,cJSON *obj6,cJSON *obj7,cJSON *obj9) { jaddi(array,obj0); return(helparray8(array,obj1,obj2,obj3,obj4,obj5,obj6,obj7,obj9)); } +cJSON *helparray10(cJSON *array,cJSON *obj0,cJSON *obj1,cJSON *obj2,cJSON *obj3,cJSON *obj4,cJSON *obj5,cJSON *obj6,cJSON *obj7,cJSON *obj9,cJSON *obj10) { jaddi(array,obj0); return(helparray9(array,obj1,obj2,obj3,obj4,obj5,obj6,obj7,obj9,obj10)); } +cJSON *helparray11(cJSON *array,cJSON *obj0,cJSON *obj1,cJSON *obj2,cJSON *obj3,cJSON *obj4,cJSON *obj5,cJSON *obj6,cJSON *obj7,cJSON *obj9,cJSON *obj10,cJSON *obj11) { jaddi(array,obj0); return(helparray10(array,obj1,obj2,obj3,obj4,obj5,obj6,obj7,obj9,obj10,obj11)); } +cJSON *helparray12(cJSON *array,cJSON *obj0,cJSON *obj1,cJSON *obj2,cJSON *obj3,cJSON *obj4,cJSON *obj5,cJSON *obj6,cJSON *obj7,cJSON *obj9,cJSON *obj10,cJSON *obj11,cJSON *obj12) { jaddi(array,obj0); return(helparray11(array,obj1,obj2,obj3,obj4,obj5,obj6,obj7,obj9,obj10,obj11,obj12)); } +cJSON *helparray13(cJSON *array,cJSON *obj0,cJSON *obj1,cJSON *obj2,cJSON *obj3,cJSON *obj4,cJSON *obj5,cJSON *obj6,cJSON *obj7,cJSON *obj9,cJSON *obj10,cJSON *obj11,cJSON *obj12,cJSON *obj13) { jaddi(array,obj0); return(helparray12(array,obj1,obj2,obj3,obj4,obj5,obj6,obj7,obj9,obj10,obj11,obj12,obj13)); } +cJSON *helparray14(cJSON *array,cJSON *obj0,cJSON *obj1,cJSON *obj2,cJSON *obj3,cJSON *obj4,cJSON *obj5,cJSON *obj6,cJSON *obj7,cJSON *obj9,cJSON *obj10,cJSON *obj11,cJSON *obj12,cJSON *obj13,cJSON *obj14) { jaddi(array,obj0); return(helparray13(array,obj1,obj2,obj3,obj4,obj5,obj6,obj7,obj9,obj10,obj11,obj12,obj13,obj14)); } +cJSON *helparray15(cJSON *array,cJSON *obj0,cJSON *obj1,cJSON *obj2,cJSON *obj3,cJSON *obj4,cJSON *obj5,cJSON *obj6,cJSON *obj7,cJSON *obj9,cJSON *obj10,cJSON *obj11,cJSON *obj12,cJSON *obj13,cJSON *obj14,cJSON *obj15) { jaddi(array,obj0); return(helparray14(array,obj1,obj2,obj3,obj4,obj5,obj6,obj7,obj9,obj10,obj11,obj12,obj13,obj14,obj15)); } cJSON *SuperNET_helpjson() { @@ -110,6 +119,7 @@ cJSON *SuperNET_helpjson() #define IGUANA_HELP_64A(agent,name,j64,obj) array = helpjson(IGUANA_ARGS,#agent,#name,helparray2(cJSON_CreateArray(),helpitem(#j64,"u64bits"),helpitem(#obj,"array"))) #define IGUANA_HELP_AA(agent,name,obj,obj2) array = helpjson(IGUANA_ARGS,#agent,#name,helparray2(cJSON_CreateArray(),helpitem(#obj,"array"),helpitem(#obj2,"array"))) +#define IGUANA_HELP_AOI(agent,name,obj,obj2,val) array = helpjson(IGUANA_ARGS,#agent,#name,helparray3(cJSON_CreateArray(),helpitem(#obj,"array"),helpitem(#obj2,"object"),helpitem(#val,"int"))) #define IGUANA_HELP_D(agent,name,amount) array = helpjson(IGUANA_ARGS,#agent,#name,helparray(cJSON_CreateArray(),helpitem(#amount,"float"))) #define IGUANA_HELP_H(agent,name,hash) array = helpjson(IGUANA_ARGS,#agent,#name,helparray(cJSON_CreateArray(),helpitem(#hash,"hash"))) @@ -124,8 +134,11 @@ cJSON *SuperNET_helpjson() #define IGUANA_HELP_SSDIS(agent,name,str,str2,amount,val,str3) array = helpjson(IGUANA_ARGS,#agent,#name,helparray5(cJSON_CreateArray(),helpitem(#str,"string"),helpitem(#str2,"string"),helpitem(#amount,"float"),helpitem(#val,"int"),helpitem(#str3,"string"))) #define IGUANA_HELP_SSDISS(agent,name,str,str2,amount,val,str3,str4) array = helpjson(IGUANA_ARGS,#agent,#name,helparray6(cJSON_CreateArray(),helpitem(#str,"string"),helpitem(#str2,"string"),helpitem(#amount,"float"),helpitem(#val,"int"),helpitem(#str3,"string"),helpitem(#str4,"string"))) #define IGUANA_HELP_SAIS(agent,name,str,obj,val,str2) array = helpjson(IGUANA_ARGS,#agent,#name,helparray4(cJSON_CreateArray(),helpitem(#str,"string"),helpitem(#obj,"array"),helpitem(#val,"int"),helpitem(#str2,"string"))) +#define IGUANA_HELP_SAOS(agent,name,str,obj,obj2,str2) array = helpjson(IGUANA_ARGS,#agent,#name,helparray4(cJSON_CreateArray(),helpitem(#str,"string"),helpitem(#obj,"array"),helpitem(#obj2,"object"),helpitem(#str2,"string"))) #define IGUANA_HELP_SDSS(agent,name,str,amount,str2,str3) array = helpjson(IGUANA_ARGS,#agent,#name,helparray4(cJSON_CreateArray(),helpitem(#str,"string"),helpitem(#amount,"float"),helpitem(#str2,"string"),helpitem(#str3,"string"))) +#define IGUANA_HELP_SHI_SDSD_II_SSSSSS(agent,name,str,hash,val,str2,amount,str3,amount2,val2,val3,str4,str5,str6,str7,str8,str9) array = helpjson(IGUANA_ARGS,#agent,#name,helparray15(cJSON_CreateArray(),helpitem(#str,"string"),helpitem(#hash,"hash"),helpitem(#val,"int"),helpitem(#str2,"string"),helpitem(#amount,"float"),helpitem(#str3,"string"),helpitem(#amount2,"float"),helpitem(#val2,"int"),helpitem(#val3,"int"),helpitem(#str4,"string"),helpitem(#str5,"string"),helpitem(#str6,"string"),helpitem(#str7,"string"),helpitem(#str8,"string"),helpitem(#str9,"string"))) + // API functions #define ZERO_ARGS IGUANA_HELP0 #define INT_ARG IGUANA_HELP_I @@ -168,6 +181,9 @@ cJSON *SuperNET_helpjson() #define STRING_AND_DOUBLE IGUANA_HELP_SD #define TWO_STRINGS_AND_TWO_DOUBLES IGUANA_HELP_SSDD #define STRING_AND_TWO_DOUBLES IGUANA_HELP_SDD +#define P2SH_SPENDAPI IGUANA_HELP_SHI_SDSD_II_SSSSSS +#define ARRAY_OBJ_INT IGUANA_HELP_AOI +#define STRING_ARRAY_OBJ_STRING IGUANA_HELP_SAOS #include "../includes/iguana_apideclares.h" @@ -210,6 +226,10 @@ int32_t agentform(FILE *fp,char *form,int32_t max,char *agent,cJSON *methoditem) width = 24; else if ( strcmp(typestr,"u64bits") == 0 ) width = 24; + else if ( strcmp(typestr,"array") == 0 ) + width = 64; + else if ( strcmp(typestr,"object") == 0 ) + width = 64; else width = 0; } //sprintf(buf,"",fieldname); @@ -350,7 +370,7 @@ cJSON *update_docjson(cJSON *docjson,char *agent,char *method) if ( agent != 0 && method != 0 ) { sprintf(stubstr,"{\"agent\":\"%s\",\"method\":\"%s\",\"field0\":\"put in helpful info field0\",\"field1\":\"put in helpful info for field1\",\"help\":\"put helpful info here\",\"teststatus\":[{\"tester\":\"bob\",\"result\":\"put result here\",\"notes\":\"put useful notes here\",\"automated\":\"notyet\",\"sourcefile\":\"%s_%s_test.py\"}]}",agent,method,agent,method); - sprintf(fname,"help/%s_%s.json",agent,method); + sprintf(fname,"%s/%s_%s.json",GLOBAL_HELPDIR,agent,method); if ( (docstr= OS_filestr(&allocsize,fname)) != 0 ) { if ( (item= cJSON_Parse(docstr)) == 0 ) @@ -378,7 +398,7 @@ cJSON *update_docjson(cJSON *docjson,char *agent,char *method) char *formfname(char *name,char *suffix) { static char retbuf[512]; - sprintf(retbuf,"help/%s.%s",name,suffix); + sprintf(retbuf,"%s/%s.%s",GLOBAL_HELPDIR,name,suffix); return(retbuf); } @@ -460,7 +480,7 @@ char *SuperNET_htmlstr(char *fname,char *htmlstr,int32_t maxsize,char *agentstr) pretty_forms(fname,agentstr,"html"); printf("autocreate %s\n","_API.md"); pretty_forms("_API.md",0,"md"); - return(OS_filestr(&filesize,"index7778.html")); +return(OS_filestr(&filesize,"index7778.html")); sprintf(htmlstr," SuperUGLY GUI> "); size = (int32_t)strlen(htmlstr); if ( (helpjson= SuperNET_helpjson()) != 0 ) @@ -588,7 +608,12 @@ STRING_ARG(iguana,addcoin,newcoin) symbol = coin->symbol; if ( symbol != 0 ) { - if ( (retval= iguana_launchcoin(symbol,json)) > 0 ) + printf(">> addcoin.%s\n",symbol); +#ifdef __PNACL__ +// if ( strcmp(symbol,"BTC") == 0 ) +// return(clonestr("{\"result\":\"BTC for chrome app is not yet\"}")); +#endif + if ( (retval= iguana_launchcoin(myinfo,symbol,json)) > 0 ) { if ( myinfo->rpcsymbol[0] == 0 ) safecopy(myinfo->rpcsymbol,symbol,sizeof(myinfo->rpcsymbol)); @@ -609,6 +634,16 @@ STRING_ARG(iguana,startcoin,activecoin) } else return(clonestr("{\"error\":\"startcoin needs coin\"}")); } +STRING_ARG(iguana,stopcoin,activecoin) +{ + if ( coin != 0 ) + { + coin->active = 0; + iguana_coinpurge(coin); + return(clonestr("{\"result\":\"coin stopped\"}")); + } else return(clonestr("{\"error\":\"stopcoin needs coin\"}")); +} + STRING_ARG(iguana,pausecoin,activecoin) { if ( coin != 0 ) @@ -725,7 +760,7 @@ STRING_AND_INT(iguana,maxpeers,activecoin,max) char *hmac_dispatch(char *(*hmacfunc)(char *dest,char *key,int32_t key_size,char *message),char *name,char *message,char *password) { char hexstr[1025]; cJSON *json; - if ( message != 0 && password != 0 ) + if ( message != 0 && password != 0 && message[0] != 0 && password[0] != 0 ) { memset(hexstr,0,sizeof(hexstr)); (*hmacfunc)(hexstr,password,password==0?0:(int32_t)strlen(password),message); @@ -740,7 +775,7 @@ char *hmac_dispatch(char *(*hmacfunc)(char *dest,char *key,int32_t key_size,char char *hash_dispatch(void (*hashfunc)(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len),char *name,char *message) { char hexstr[16384]; uint8_t databuf[8192]; cJSON *json; - if ( message != 0 ) + if ( message != 0 && message[0] != 0 ) { memset(hexstr,0,sizeof(hexstr)); (*hashfunc)(hexstr,databuf,(uint8_t *)message,(int32_t)strlen(message)); @@ -800,12 +835,19 @@ TWO_STRINGS(hmac,whirlpool,message,passphrase) { return(hmac_dispatch(hmac_whirl STRING_ARG(SuperNET,bitcoinrpc,setcoin) { + char buf[1024]; if ( setcoin != 0 && setcoin[0] != 0 ) { strcpy(myinfo->rpcsymbol,setcoin); touppercase(myinfo->rpcsymbol); - iguana_launchcoin(myinfo->rpcsymbol,json); - return(clonestr("{\"result\":\"set bitcoin RPC coin\"}")); + printf("bitcoinrpc.%s\n",myinfo->rpcsymbol); + if ( iguana_launchcoin(myinfo,myinfo->rpcsymbol,json) < 0 ) + return(clonestr("{\"error\":\"error creating coin\"}")); + else + { + sprintf(buf,"{\"result\":\"success\",\"setcoin\":\"%s\"}",setcoin); + return(clonestr(buf)); + } } else return(clonestr("{\"error\":\"bitcoinrpc needs setcoin value\"}")); } @@ -849,8 +891,8 @@ char *SuperNET_parser(struct supernet_info *myinfo,char *agentstr,char *method,c coinstr = myinfo->rpcsymbol; if ( coinstr != 0 && coinstr[0] != 0 ) coin = iguana_coinfind(coinstr); - if ( strcmp(agentstr,"ramchain") == 0 && coin == 0 ) - return(clonestr("{\"error\":\"ramchain needs coin\"}")); + if ( strcmp(agentstr,"bitcoinrpc") == 0 && coin == 0 ) + return(clonestr("{\"error\":\"bitcoinrpc needs coin\"}")); #define IGUANA_ARGS myinfo,coin,json,remoteaddr #define IGUANA_DISPATCH0(agent,name) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS)) #define IGUANA_DISPATCH_S(agent,name,str) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jstr(json,#str))) @@ -873,6 +915,7 @@ char *SuperNET_parser(struct supernet_info *myinfo,char *agentstr,char *method,c #define IGUANA_DISPATCH_SDD(agent,name,str,val,val2) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jstr(json,#str),jdouble(json,#val),jdouble(json,#val2))) #define IGUANA_DISPATCH_SA(agent,name,str,array) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jstr(json,#str),jobj(json,#array))) #define IGUANA_DISPATCH_SAA(agent,name,str,array,array2) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jstr(json,#str),jobj(json,#array),jobj(json,#array2))) +#define IGUANA_DISPATCH_AOI(agent,name,array,object,val) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jobj(json,#array),jobj(json,#object),juint(json,#val))) #define IGUANA_DISPATCH_SIII(agent,name,str,val,val2,val3) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jstr(json,#str),juint(json,#val),juint(json,#val2),juint(json,#val3))) #define IGUANA_DISPATCH_I(agent,name,val) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,juint(json,#val))) @@ -899,8 +942,11 @@ char *SuperNET_parser(struct supernet_info *myinfo,char *agentstr,char *method,c #define IGUANA_DISPATCH_SSDIS(agent,name,str,str2,amount,val,str3) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jstr(json,#str),jstr(json,#str2),jdouble(json,#amount),juint(json,#val),jstr(json,#str3))) #define IGUANA_DISPATCH_SSDISS(agent,name,str,str2,amount,val,str3,str4) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jstr(json,#str),jstr(json,#str2),jdouble(json,#amount),juint(json,#val),jstr(json,#str3),jstr(json,#str4))) #define IGUANA_DISPATCH_SAIS(agent,name,str,array,val,str2) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jstr(json,#str),jobj(json,#array),juint(json,#val),jstr(json,#str2))) +#define IGUANA_DISPATCH_SAOS(agent,name,str,array,object,str2) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jstr(json,#str),jobj(json,#array),jobj(json,#object),jstr(json,#str2))) #define IGUANA_DISPATCH_SDSS(agent,name,str,amount,str2,str3) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jstr(json,#str),jdouble(json,#amount),jstr(json,#str2),jstr(json,#str3))) +#define IGUANA_DISPATCH_SHI_SDSD_II_SSSSSS(agent,name,str,hash,val,str2,amount,str3,amount2,val2,val3,str4,str5,str6,str7,str8,str9) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jstr(json,#str),jbits256(json,#hash),jint(json,#val),jstr(json,#str2),jdouble(json,#amount),jstr(json,#str3),jdouble(json,#amount2),juint(json,#val2),juint(json,#val3),jstr(json,#str4),jstr(json,#str5),jstr(json,#str6),jstr(json,#str7),jstr(json,#str8),jstr(json,#str9))) + // API functions #define ZERO_ARGS IGUANA_DISPATCH0 #define INT_ARG IGUANA_DISPATCH_I @@ -943,13 +989,17 @@ char *SuperNET_parser(struct supernet_info *myinfo,char *agentstr,char *method,c #define STRING_AND_DOUBLE IGUANA_DISPATCH_SD #define TWO_STRINGS_AND_TWO_DOUBLES IGUANA_DISPATCH_SSDD #define STRING_AND_TWO_DOUBLES IGUANA_DISPATCH_SDD +#define P2SH_SPENDAPI IGUANA_DISPATCH_SHI_SDSD_II_SSSSSS +#define ARRAY_OBJ_INT IGUANA_DISPATCH_AOI +#define STRING_ARRAY_OBJ_STRING IGUANA_DISPATCH_SAOS #include "../includes/iguana_apideclares.h" //#undef IGUANA_ARGS #include "../includes/iguana_apiundefs.h" - - return(clonestr("{\"error\":\"illegal ramchain method or missing coin\"}")); + char errstr[512]; + sprintf(errstr,"{\"error\":\"unsupported call\",\"agent\":\"%s\",\"method\":\"%s\"}",agentstr,method); + return(clonestr(errstr)); } diff --git a/iguana/iguana_msg.c b/iguana/iguana_msg.c index 64a45f816..e21f5e8ff 100755 --- a/iguana/iguana_msg.c +++ b/iguana/iguana_msg.c @@ -71,7 +71,7 @@ int32_t iguana_rwversion(int32_t rwflag,uint8_t *serialized,struct iguana_msgver else if ( msg->nVersion > 70000 ) len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->relayflag),&msg->relayflag); //if ( rwflag == 0 ) - printf("readsize.%d %-15s v.%llu srv.%llx %u ht.%llu [%s].R%d nonce.%llx\n",readsize,ipaddr,(long long)msg->nVersion,(long long)msg->nServices,(uint32_t)msg->nTime,(long long)msg->nStartingHeight,msg->strSubVer,msg->relayflag,(long long)msg->nonce); + //printf("readsize.%d %-15s v.%llu srv.%llx %u ht.%llu [%s].R%d nonce.%llx\n",readsize,ipaddr,(long long)msg->nVersion,(long long)msg->nServices,(uint32_t)msg->nTime,(long long)msg->nStartingHeight,msg->strSubVer,msg->relayflag,(long long)msg->nonce); // 6e ea 00 00 01 00 00 00 00 00 00 00 86 5f a8 56 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ff b5 2f b7 bc c6 83 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ff 67 e5 7e c2 07 80 00 00 00 00 00 00 00 00 10 2f 42 69 74 4e 65 74 3a 31 2e 31 2e 33 2e 32 2f 92 d0 09 00 6c 04 00 00 01 00 00 00 80 07 01 9a 03 9b 03 01 return(len); } @@ -88,7 +88,7 @@ int32_t iguana_rwblock(int32_t rwflag,bits256 *hash2p,uint8_t *serialized,struct len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->H.bits),&msg->H.bits); len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->H.nonce),&msg->H.nonce); *hash2p = bits256_doublesha256(blockhash,serialized,len); - //char str[65]; printf("len.%d: block version.%d timestamp.%u bits.%x nonce.%u prev.(%s) %llx blockhash.(%s) %llx\n",len,msg->H.version,msg->H.timestamp,msg->H.bits,msg->H.nonce,bits256_str(str,msg->H.prev_block),(long long)msg->H.merkle_root.txid,blockhash,(long long)hash2p->txid); + // char str[65]; printf("len.%d: block version.%d timestamp.%u bits.%x nonce.%u prev.(%s) %llx blockhash.(%s) %llx\n",len,msg->H.version,msg->H.timestamp,msg->H.bits,msg->H.nonce,bits256_str(str,msg->H.prev_block),(long long)msg->H.merkle_root.txid,blockhash,(long long)hash2p->txid); if ( rwflag != 0 ) x = msg->txn_count; len += iguana_rwvarint(rwflag,&serialized[len],&x); @@ -155,7 +155,7 @@ int32_t iguana_rwblockhash(int32_t rwflag,uint8_t *serialized,uint32_t *nVersion void iguana_gotversion(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msgversion *vers) { uint8_t serialized[sizeof(struct iguana_msghdr)]; - printf("gotversion from %s: starting height.%d services.%llx proto.%d\n",addr->ipaddr,vers->nStartingHeight,(long long)vers->nServices,vers->nVersion); + //printf("gotversion from %s: starting height.%d services.%llx proto.%d\n",addr->ipaddr,vers->nStartingHeight,(long long)vers->nServices,vers->nVersion); if ( (vers->nServices & NODE_NETWORK) != 0 )//&& vers->nonce != coin->instance_nonce ) { addr->protover = (vers->nVersion < PROTOCOL_VERSION) ? vers->nVersion : PROTOCOL_VERSION; @@ -166,11 +166,20 @@ void iguana_gotversion(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_queue_send(coin,addr,0,serialized,"verack",0,0,0); //iguana_send_ping(coin,addr); } + else if ( (vers->nServices & (1<<7)) == 0 ) + addr->dead = (uint32_t)time(NULL); if ( (vers->nServices & (1<<7)) == (1<<7) ) addr->supernet = 1; - else printf("nServices.%lld nonce.%llu non-relay node.(%s) supernet.%d\n",(long long)vers->nServices,(long long)vers->nonce,addr->ipaddr,addr->supernet); - if ( vers->nStartingHeight > coin->longestchain ) - coin->longestchain = vers->nStartingHeight; + if ( addr->supernet != 0 ) + printf("height.%d nServices.%lld nonce.%llu %srelay node.(%s) supernet.%d\n",vers->nStartingHeight,(long long)vers->nServices,(long long)vers->nonce,addr->relayflag==0?"non-":"",addr->ipaddr,addr->supernet); + if ( (int32_t)vers->nStartingHeight > coin->longestchain ) + { + if ( coin->badlongestchain != 0 && (int32_t)vers->nStartingHeight >= coin->badlongestchain ) + { + printf("peer.(%s) gives badlongestchain.%d\n",addr->ipaddr,vers->nStartingHeight); + addr->dead = 1; + } else coin->longestchain = vers->nStartingHeight; + } iguana_queue_send(coin,addr,0,serialized,"getaddr",0,0,0); } @@ -182,7 +191,7 @@ int32_t iguana_send_version(struct iguana_info *coin,struct iguana_peer *addr,ui msg.nServices = myservices; msg.nTime = (int64_t)time(NULL); msg.nonce = coin->instance_nonce; - sprintf(msg.strSubVer,"/Satoshi:0.11.99/"); + sprintf(msg.strSubVer,"/Satoshi:0.10.0/"); msg.nStartingHeight = coin->blocks.hwmchain.height; iguana_gotdata(coin,addr,msg.nStartingHeight); len = iguana_rwversion(1,&serialized[sizeof(struct iguana_msghdr)],&msg,addr->ipaddr,0); @@ -208,7 +217,7 @@ void iguana_gotverack(struct iguana_info *coin,struct iguana_peer *addr) uint8_t serialized[sizeof(struct iguana_msghdr)]; if ( addr != 0 ) { - printf("gotverack from %s\n",addr->ipaddr); + //printf("gotverack from %s\n",addr->ipaddr); addr->A.nTime = (uint32_t)time(NULL); iguana_queue_send(coin,addr,0,serialized,"getaddr",0,0,0); if ( addr->supernet != 0 ) @@ -227,20 +236,29 @@ void iguana_gotaddr(struct iguana_info *coin,struct iguana_peer *addr,struct igu expand_ipbits(ipaddr,ipbits); if ( port != 0 ) sprintf(ipport,"%s:%d",ipaddr,port); + if ( 0 ) + { + int32_t i; + printf("{{"); + for (i=0; i<16; i++) + printf("0x%02x%s",A->ip[i],i<15?",":""); + printf("}, 14631},\n"); + } iguana_possible_peer(coin,ipport); - //printf("gotaddr.(%s:%d)\n",ipaddr,port); + //printf("gotaddr.(%s:%d) from (%s)\n",ipaddr,port,addr->ipaddr); } void iguana_gotping(struct iguana_info *coin,struct iguana_peer *addr,uint64_t nonce,uint8_t *data) { - int32_t len; uint8_t serialized[sizeof(struct iguana_msghdr) + sizeof(nonce)]; + int32_t len; char myipaddr[64]; uint8_t serialized[sizeof(struct iguana_msghdr) + sizeof(nonce)]; len = iguana_rwnum(1,&serialized[sizeof(struct iguana_msghdr)],sizeof(uint64_t),&nonce); if ( memcmp(data,&serialized[sizeof(struct iguana_msghdr)],sizeof(nonce)) != 0 ) printf("ping ser error %llx != %llx\n",(long long)nonce,*(long long *)data); iguana_queue_send(coin,addr,0,serialized,"pong",len,0,0); if ( addr->supernet != 0 ) { - printf("send getpeers to %s\n",addr->ipaddr); + expand_ipbits(myipaddr,(uint32_t)nonce); + printf("send getpeers to %s, myipaddr.(%s)\n",addr->ipaddr,myipaddr); iguana_send_supernet(coin,addr,SUPERNET_GETPEERSTR,0); } } @@ -251,10 +269,11 @@ int32_t iguana_send_ping(struct iguana_info *coin,struct iguana_peer *addr) if ( (nonce= addr->pingnonce) == 0 ) { OS_randombytes((uint8_t *)&nonce,sizeof(nonce)); - addr->pingnonce = nonce; + addr->pingnonce = ((nonce & 0xffffffff) << 32) | ((uint32_t)addr->ipbits & 0xffffffff); addr->pingtime = (uint32_t)time(NULL); } - printf("pingnonce.%llx\n",(long long)nonce); + //printf("pingnonce.%llx from (%s)\n",(long long)nonce,addr->ipaddr); + iguana_queue_send(coin,addr,0,serialized,"getaddr",0,0,0); len = iguana_rwnum(1,&serialized[sizeof(struct iguana_msghdr)],sizeof(uint64_t),&nonce); if ( addr->supernet != 0 ) iguana_send_supernet(coin,addr,SUPERNET_GETPEERSTR,0); @@ -280,7 +299,7 @@ void iguana_gotpong(struct iguana_info *coin,struct iguana_peer *addr,uint64_t n } if ( nonce != addr->pingnonce ) { - printf("pong received invalid pingnonce (%s) %llx vs %llx\n",addr->ipaddr,(long long)addr->pingnonce,(long long)nonce); + // printf("pong received invalid pingnonce (%s) %llx vs %llx\n",addr->ipaddr,(long long)addr->pingnonce,(long long)nonce); } else printf("(%s) pong verified with pingnonce.%llx\n",addr->ipaddr,(long long)addr->pingnonce); addr->pingnonce = 0; addr->sendmillis = 0; @@ -300,28 +319,32 @@ int32_t iguana_gethdrs(struct iguana_info *coin,uint8_t *serialized,char *cmd,ch return(iguana_sethdr((void *)serialized,coin->chain->netmagic,cmd,&serialized[sizeof(struct iguana_msghdr)],len)); } -int32_t iguana_getdata(struct iguana_info *coin,uint8_t *serialized,int32_t type,char *hashstr) +int32_t iguana_getdata(struct iguana_info *coin,uint8_t *serialized,int32_t type,bits256 *hashes,int32_t n) { - uint32_t len,i,n=1; bits256 hash2; - decode_hex(hash2.bytes,sizeof(hash2),hashstr); + uint32_t len,i; //bits256 hash2; len = iguana_rwvarint32(1,&serialized[sizeof(struct iguana_msghdr)],(uint32_t *)&n); for (i=0; ichain->netmagic,"getdata",&serialized[sizeof(struct iguana_msghdr)],len)); } int32_t iguana_rwvin(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized,struct iguana_msgvin *msg) { - int32_t len = 0; + int32_t len = 0; uint32_t tmp; len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->prev_hash),msg->prev_hash.bytes); len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->prev_vout),&msg->prev_vout); - len += iguana_rwvarint32(rwflag,&serialized[len],&msg->scriptlen); + if ( rwflag == 1 ) + tmp = msg->scriptlen; + len += iguana_rwvarint32(rwflag,&serialized[len],&tmp); if ( rwflag == 0 ) - msg->script = iguana_memalloc(mem,msg->scriptlen,1); - len += iguana_rwmem(rwflag,&serialized[len],msg->scriptlen,msg->script); + { + msg->scriptlen = tmp; + msg->vinscript = iguana_memalloc(mem,msg->scriptlen,1); + } + len += iguana_rwmem(rwflag,&serialized[len],msg->scriptlen,msg->vinscript); len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->sequence),&msg->sequence); //char str[65]; printf("MSGvin.(%s/v%d) script[%d]\n",bits256_str(str,msg->prev_hash),msg->prev_vout,msg->scriptlen); //int i; for (i=0; iscriptlen; i++) @@ -330,6 +353,7 @@ int32_t iguana_rwvin(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized, return(len); } +int32_t debugtest; int32_t iguana_rwvout(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized,struct iguana_msgvout *msg) { int32_t len = 0; @@ -338,10 +362,13 @@ int32_t iguana_rwvout(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized if ( rwflag == 0 ) msg->pk_script = iguana_memalloc(mem,msg->pk_scriptlen,1); len += iguana_rwmem(rwflag,&serialized[len],msg->pk_scriptlen,msg->pk_script); - //printf("(%.8f scriptlen.%d) ",dstr(msg->value),msg->pk_scriptlen); - //int i; for (i=0; ipk_scriptlen; i++) - // printf("%02x",msg->pk_script[i]); - //printf("\n"); + if ( debugtest != 0 ) + { + printf("(%.8f scriptlen.%d) ",dstr(msg->value),msg->pk_scriptlen); + int i; for (i=0; ipk_scriptlen; i++) + printf("%02x",msg->pk_script[i]); + printf("\n"); + } return(len); } @@ -353,32 +380,30 @@ int32_t iguana_rwtx(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized,s len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->timestamp),&msg->timestamp); len += iguana_rwvarint32(rwflag,&serialized[len],&msg->tx_in); //printf("version.%d ",msg->version); - if ( msg->tx_in > 0 && msg->tx_out*100 < maxsize ) - { - if ( rwflag == 0 ) - msg->vins = iguana_memalloc(mem,msg->tx_in * sizeof(*msg->vins),1); - for (i=0; itx_in; i++) - len += iguana_rwvin(rwflag,mem,&serialized[len],&msg->vins[i]); - //printf("numvins.%d\n",msg->tx_in); - } - else + if ( rwflag == 0 ) + msg->vins = iguana_memalloc(mem,msg->tx_in * sizeof(*msg->vins),1); + for (i=0; itx_in; i++) { - printf("invalid tx_in.%d\n",msg->tx_in); - return(-1); + len += iguana_rwvin(rwflag,mem,&serialized[len],&msg->vins[i]); + if ( len > maxsize ) + { + printf("invalid tx_in.%d len.%d vs maxsize.%d\n",msg->tx_in,len,maxsize); + return(-1); + } } + //printf("numvins.%d\n",msg->tx_in); len += iguana_rwvarint32(rwflag,&serialized[len],&msg->tx_out); - if ( msg->tx_out > 0 && msg->tx_out*32 < maxsize ) - { - //printf("numvouts.%d ",msg->tx_out); - if ( rwflag == 0 ) - msg->vouts = iguana_memalloc(mem,msg->tx_out * sizeof(*msg->vouts),1); - for (i=0; itx_out; i++) - len += iguana_rwvout(rwflag,mem,&serialized[len],&msg->vouts[i]); - } - else + //printf("numvouts.%d ",msg->tx_out); + if ( rwflag == 0 ) + msg->vouts = iguana_memalloc(mem,msg->tx_out * sizeof(*msg->vouts),1); + for (i=0; itx_out; i++) { - printf("invalid tx_out.%d\n",msg->tx_out); - return(-1); + len += iguana_rwvout(rwflag,mem,&serialized[len],&msg->vouts[i]); + if ( len > maxsize ) + { + printf("invalid tx_out.%d len.%d vs maxsize.%d\n",msg->tx_out,len,maxsize); + return(-1); + } } len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->lock_time),&msg->lock_time); if ( isvpncoin != 0 ) @@ -431,6 +456,18 @@ int32_t iguana_gentxarray(struct iguana_info *coin,struct OS_memspace *mem,struc { if ( (n= iguana_rwtx(0,mem,&data[len],&tx[i],recvlen - len,&tx[i].txid,coin->chain->hastimestamp,strcmp(coin->symbol,"VPN")==0)) < 0 ) break; + if ( 0 && bits256_cmp(tx[i].txid,bits256_conv("091c99b7b7f9b83ad2385c45b342ed5dd57035d15ff812262a3ceb3f1b291a5a")) == 0 ) + { + int32_t j; for (j=0; len+jchain->hastimestamp,strcmp(coin->symbol,"VPN")==0)) < 0 ) + { + + } + debugtest = 0;*/ + } numvouts += tx[i].tx_out; numvins += tx[i].tx_in; len += n; @@ -465,10 +502,65 @@ int32_t iguana_send_hashes(struct iguana_info *coin,char *command,struct iguana_ return(retval); } +int32_t iguana_intvectors(struct iguana_info *coin,struct iguana_peer *addr,int32_t processflag,uint8_t *data,int32_t datalen) +{ + uint32_t type; bits256 *txids=0,*blockhashes=0,hash; int32_t i,n,m,len; uint64_t x; + len = n = m = 0; + len += iguana_rwvarint(0,&data[len],&x); + for (i=0; iipaddr,i,(int32_t)x,(long long)hash.txid,len); + } + else if ( type == MSG_BLOCK ) + { + if ( blockhashes == 0 ) + { + blockhashes = mycalloc('f',(int32_t)x+1,sizeof(*blockhashes)); + n = 1; + } + blockhashes[n++] = hash; + } + else if ( type == MSG_FILTERED_BLOCK ) + printf(" %d of %d: merkle.%llx\n",i,(int32_t)x,(long long)hash.txid); + else printf("what type is %d\n",type); + } + if ( n > 0 ) + { + if ( n != x+1 ) + { + printf("n.%d != x.%d -> realloc blockhashes\n",n,(int32_t)x+1); + blockhashes = myrealloc('f',blockhashes,(int32_t)((x+1)*sizeof(*blockhashes)),n*sizeof(*blockhashes)); + } // else printf("n.%d == x.%d\n",n,(int32_t)x); + if ( processflag != 0 ) + iguana_gotblockhashesM(coin,addr,blockhashes,n), blockhashes = 0; + } + if ( m > 0 ) + { + if ( m != x ) + txids = myrealloc('t',txids,(int32_t)((x+1)*sizeof(*txids)),(m+1)*sizeof(*txids)); + if ( processflag != 0 ) + iguana_gottxidsM(coin,addr,txids,m), txids = 0; + } + if ( txids != 0 ) + myfree(txids,sizeof(*txids) * (x+1)); + if ( blockhashes != 0 ) + myfree(blockhashes,sizeof(*blockhashes) * (x+1)); + return(len); + //printf("intvectors.%c recvlen.%d\n",intvectors,recvlen); +} + int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struct OS_memspace *rawmem,struct OS_memspace *txmem,struct OS_memspace *hashmem,struct iguana_msghdr *H,uint8_t *data,int32_t recvlen) { - uint8_t serialized[512]; char *retstr; - int32_t i,retval,delay,srvmsg,bloom,intvectors,len= -100; uint64_t nonce,x; uint32_t type; bits256 hash2; + uint8_t serialized[16384]; char *retstr; + int32_t i,retval,ishost,delay,srvmsg,bloom,sendlen=0,intvectors,len= -100; uint64_t nonce,x; bits256 hash2; bloom = intvectors = srvmsg = -1; if ( addr != 0 ) { @@ -476,7 +568,7 @@ int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struc strcpy(addr->lastcommand,H->command); } retval = 0; - //printf("iguana_msgparser %s parse.(%s)\n",addr->ipaddr,H->command); + //printf("iguana_msgparser from (%s) parse.(%s) len.%d\n",addr->ipaddr,H->command,recvlen); if ( strncmp(H->command,"SuperNET",strlen("SuperNET")) == 0 ) { addr->supernet = 1; @@ -489,94 +581,144 @@ int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struc } //printf("GOT.(%s) [%s] len.%d from %s -> (%s)\n",H->command,data,recvlen,addr->ipaddr,retstr==0?"null":retstr); } - else if ( strcmp(H->command,"version") == 0 ) + else if ( (ishost= (strcmp(H->command,"getblocks") == 0)) || strcmp(H->command,"block") == 0 ) { - struct iguana_msgversion recvmv; if ( addr != 0 ) { - len = iguana_rwversion(0,data,&recvmv,addr->ipaddr,recvlen); - if ( len <= recvlen ) - iguana_gotversion(coin,addr,&recvmv); - //printf("deser.(%s) len.%d recvlen.%d\n",recvmv.H.command,len,recvlen); - addr->msgcounts.version++; + if ( ishost == 0 ) + { + struct iguana_txblock txdata; + addr->msgcounts.block++; + iguana_memreset(rawmem), iguana_memreset(txmem); + memset(&txdata,0,sizeof(txdata)); + if ( (len= iguana_gentxarray(coin,rawmem,&txdata,&len,data,recvlen)) == recvlen ) + iguana_gotblockM(coin,addr,&txdata,rawmem->ptr,H,data,recvlen); + else printf("parse error block txn_count.%d, len.%d vs recvlen.%d from.(%s)\n",txdata.block.RO.txn_count,len,recvlen,addr->ipaddr); + } else len = iguana_peergetrequest(coin,addr,data,recvlen,1); } } - else if ( strcmp(H->command,"verack") == 0 ) + else if ( (ishost= (strcmp(H->command,"getdata") == 0)) || strcmp(H->command,"inv") == 0 ) { if ( addr != 0 ) { - iguana_gotverack(coin,addr); - addr->msgcounts.verack++; + if ( ishost != 0 ) + { + addr->msgcounts.getdata++; + len = iguana_peerdatarequest(coin,addr,data,recvlen); + } + else + { + intvectors = 'I', addr->msgcounts.inv++; + len = iguana_intvectors(coin,addr,1,data,recvlen); + } } - len = 0; } - else if ( strcmp(H->command,"ConnectTo") == 0 ) + else if ( (ishost= (strcmp(H->command,"getheaders") == 0)) || strcmp(H->command,"headers") == 0 ) { - iguana_queue_send(coin,addr,0,serialized,"getaddr",0,0,0); - len = 6; + struct iguana_msgblock msg; struct iguana_block *blocks; uint32_t n=0; + len = 0; + if ( ishost == 0 ) + { + len = iguana_rwvarint32(0,data,&n); + if ( n <= IGUANA_MAXINV ) + { + blocks = mycalloc('i',1,sizeof(*blocks) * n); + for (i=0; imsgcounts.headers++; + } else printf("got unexpected n.%d for headers\n",n); + } else len = iguana_peergetrequest(coin,addr,data,recvlen,0); } - else if ( strcmp(H->command,"ping") == 0 ) + else if ( (ishost= (strcmp(H->command,"version") == 0)) || strcmp(H->command,"verack") == 0 ) { - if ( recvlen == sizeof(uint64_t) && addr != 0 ) + if ( addr != 0 ) { - len = iguana_rwnum(0,data,sizeof(uint64_t),&nonce); - if ( addr != 0 ) + if ( ishost != 0 ) { - //printf("%u got nonce.%llx from %s\n",(uint32_t)time(NULL),(long long)nonce,addr->ipaddr); - iguana_gotping(coin,addr,nonce,data); - addr->msgcounts.ping++; + struct iguana_msgversion recvmv; + len = iguana_rwversion(0,data,&recvmv,addr->ipaddr,recvlen); + if ( len <= recvlen ) + iguana_gotversion(coin,addr,&recvmv); + addr->msgcounts.version++; + } + else + { + iguana_gotverack(coin,addr); + addr->msgcounts.verack++; + len = 0; } - iguana_queue_send(coin,addr,0,serialized,"getaddr",0,0,0); } } - else if ( strcmp(H->command,"pong") == 0 ) + else if ( (ishost= (strcmp(H->command,"ping") == 0)) || strcmp(H->command,"pong") == 0 ) { len = 0; - if ( recvlen == sizeof(uint64_t) ) + if ( recvlen == sizeof(uint64_t) && addr != 0 ) { len = iguana_rwnum(0,data,sizeof(uint64_t),&nonce); - iguana_gotpong(coin,addr,nonce); - } else printf("unexpected pong recvlen.%d\n",recvlen); - if ( len == recvlen && addr != 0 ) - addr->msgcounts.pong++; - iguana_queue_send(coin,addr,0,serialized,"getaddr",0,0,0); + if ( addr != 0 ) + { + //printf("%u got nonce.%llx from %s\n",(uint32_t)time(NULL),(long long)nonce,addr->ipaddr); + if ( ishost != 0 ) + { + iguana_gotping(coin,addr,nonce,data); + addr->msgcounts.ping++; + } + else + { + iguana_gotpong(coin,addr,nonce); + addr->msgcounts.pong++; + } + iguana_queue_send(coin,addr,0,serialized,"getaddr",0,0,0); + } + } } - else if ( strcmp(H->command,"addr") == 0 ) + else if ( (ishost= (strcmp(H->command,"getaddr") == 0)) || strcmp(H->command,"addr") == 0 ) { struct iguana_msgaddress A; - len = iguana_rwvarint(0,data,&x); - for (i=0; iprotover); - iguana_gotaddr(coin,addr,&A); - } - if ( len == recvlen && addr != 0 ) + if ( addr != 0 ) { - addr->lastgotaddr = (uint32_t)time(NULL); - addr->msgcounts.addr++; + if ( ishost == 0 ) + { + len = iguana_rwvarint(0,data,&x); + for (i=0; iprotover); + iguana_gotaddr(coin,addr,&A); + } + if ( len == recvlen && addr != 0 ) + { + addr->lastgotaddr = (uint32_t)time(NULL); + addr->msgcounts.addr++; + } + } + else + { + len = 0; + if ( (sendlen= iguana_peeraddrrequest(coin,addr,addr->blockspace,sizeof(addr->blockspace))) > 0 ) + retval = iguana_queue_send(coin,addr,0,addr->blockspace,"addr",sendlen,0,0); + addr->msgcounts.getaddr++; + } } //printf("%s -> addr recvlen.%d num.%d\n",addr->ipaddr,recvlen,(int32_t)x); } - else if ( strcmp(H->command,"headers") == 0 ) + else if ( strcmp(H->command,"notfound") == 0 ) { - struct iguana_msgblock msg; struct iguana_block *blocks; uint32_t n; - len = iguana_rwvarint32(0,data,&n); - if ( n <= IGUANA_MAXINV ) - { - blocks = mycalloc('i',1,sizeof(*blocks) * n); - for (i=0; imsgcounts.headers++; - } else printf("got unexpected n.%d for headers\n",n); - //printf("GOT HEADERS n.%d len.%d\n",n,len); + printf("%s SERVER notfound\n",addr->ipaddr); + intvectors = 'N', addr->msgcounts.notfound++; + len = iguana_intvectors(coin,addr,1,data,recvlen); + } + else if ( strcmp(H->command,"mempool") == 0 ) + { + printf("%s SERVER mempool\n",addr->ipaddr); + srvmsg = 'M', addr->msgcounts.mempool++; } else if ( strcmp(H->command,"tx") == 0 ) { @@ -588,16 +730,10 @@ int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struc printf("tx recvlen.%d vs len.%d\n",recvlen,len); addr->msgcounts.tx++; } - else if ( strcmp(H->command,"block") == 0 ) + else if ( strcmp(H->command,"ConnectTo") == 0 ) { - struct iguana_txblock txdata; - if ( addr != 0 ) - addr->msgcounts.block++; - iguana_memreset(rawmem), iguana_memreset(txmem);//, iguana_memreset(hashmem); - memset(&txdata,0,sizeof(txdata)); - if ( (len= iguana_gentxarray(coin,rawmem,&txdata,&len,data,recvlen)) == recvlen ) - iguana_gotblockM(coin,addr,&txdata,rawmem->ptr,H,data,recvlen); - else printf("parse error block txn_count.%d, len.%d vs recvlen.%d\n",txdata.block.RO.txn_count,len,recvlen); + iguana_queue_send(coin,addr,0,serialized,"getaddr",0,0,0); + len = 6; } else if ( strcmp(H->command,"reject") == 0 ) { @@ -619,29 +755,7 @@ int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struc } else if ( addr != 0 ) { - if ( strcmp(H->command,"inv") == 0 ) - intvectors = 'I', addr->msgcounts.inv++; - else if ( strcmp(H->command,"notfound") == 0 ) // for servers - intvectors = 'N', addr->msgcounts.notfound++; - else if ( strcmp(H->command,"getdata") == 0 ) // for servers - { - intvectors = srvmsg = 'D', addr->msgcounts.getdata++; - } - else if ( strcmp(H->command,"getblocks") == 0 ) // for servers - { - srvmsg = 'B', addr->msgcounts.getblocks++; - } - else if ( strcmp(H->command,"getheaders") == 0 ) // for servers - { - srvmsg = 'H', addr->msgcounts.getheaders++; - } - else if ( strcmp(H->command,"getaddr") == 0 ) - { - srvmsg = 'A', addr->msgcounts.getaddr++; - } - else if ( strcmp(H->command,"mempool") == 0 ) - srvmsg = 'M', addr->msgcounts.mempool++; - else if ( strcmp(H->command,"filterload") == 0 ) // for bloom + if ( strcmp(H->command,"filterload") == 0 ) // for bloom bloom = 'L', addr->msgcounts.filterload++; else if ( strcmp(H->command,"filteradd") == 0 ) // for bloom bloom = 'A', addr->msgcounts.filteradd++; @@ -652,62 +766,6 @@ int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struc } if ( bloom >= 0 || srvmsg >= 0 ) len = recvlen; // just mark as valid - if ( intvectors >= 0 ) - { - bits256 *txids=0,*blockhashes=0,hash; int32_t n,m; - len = n = m = 0; - len += iguana_rwvarint(0,&data[len],&x); - for (i=0; iipaddr,intvectors,i,(int32_t)x,(long long)hash.txid,len); - } - else if ( type == MSG_BLOCK ) - { - if ( blockhashes == 0 ) - { - blockhashes = mycalloc('f',(int32_t)x+1,sizeof(*blockhashes)); - n = 1; - } - blockhashes[n++] = hash; - } - else if ( type == MSG_FILTERED_BLOCK ) - printf("iv.%d %d of %d: merkle.%llx\n",intvectors,i,(int32_t)x,(long long)hash.txid); - else printf("what type is %d\n",type); - } - if ( intvectors == 'I' ) - { - if ( n > 0 ) - { - if ( n != x+1 ) - { - printf("n.%d != x.%d -> realloc blockhashes\n",n,(int32_t)x+1); - blockhashes = myrealloc('f',blockhashes,(int32_t)((x+1)*sizeof(*blockhashes)),n*sizeof(*blockhashes)); - } // else printf("n.%d == x.%d\n",n,(int32_t)x); - if ( 1 ) - iguana_gotblockhashesM(coin,addr,blockhashes,n), blockhashes = 0; - else iguana_send_hashes(coin,"getblocks",addr,blockhashes[0],&blockhashes[1],n); - } - if ( m > 0 ) - { - if ( m != x ) - txids = myrealloc('t',txids,(int32_t)((x+1)*sizeof(*txids)),(m+1)*sizeof(*txids)); - iguana_gottxidsM(coin,addr,txids,m), txids = 0; - } - } - if ( txids != 0 ) - myfree(txids,sizeof(*txids) * (x+1)); - if ( blockhashes != 0 ) - myfree(blockhashes,sizeof(*blockhashes) * (x+1)); - //printf("intvectors.%c recvlen.%d\n",intvectors,recvlen); - } if ( len != recvlen && len != recvlen-1 && len != recvlen-2 ) { //printf("error.(%s) (%s): len.%d != recvlen.%d\n",H->command,addr->ipaddr,len,recvlen); diff --git a/iguana/iguana_passport.c b/iguana/iguana_passport.c new file mode 100755 index 000000000..40c568684 --- /dev/null +++ b/iguana/iguana_passport.c @@ -0,0 +1,99 @@ +/****************************************************************************** + * 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" + +/* + Asset Passport System - first draft spec + + Asset Export - destination blockchain and address, optional BTC sync + Asset Import - source blockchain txid/vout or BTCD txid/vout + +Assets can be exported from any blockchain that supports a burn transaction with an attachment. This attachment needs to have a destination blockchain and address. In case a blockchain cannot support a combined burn with attachment, the burn txid can be added to the export payload and this combined data signed using the source blockchain's signing method to create a BTCD 'APS' OP_RETURN + +While it is not expected that there will be more than 256 such blockchains, by using the bitcoin varint we can encode an arbitrary number of destination blockchains using one byte, until we need to expand. For now the following one byte codes represent the destination blockchain: + + 'b' -> bitcoin/BitcoinDark (BTC) + 'c' -> colored coins + 'e' -> ethereum (ETH) + 'n' -> NXT + 'o' -> open assets + 'w' -> WAVES + 'x' -> counterparty (XCP) + '?' -> please contact jl777 to have a new code for asset supporting blockchain added. + + When 0xfc slots are filled, the code (0xfd + 2 bytes) will be used. It is safe to assume there wont be more than 65534 supporting blockchains, but codes 0xfe and 0xff will be reserved just in case + + The destination address is the 20 byte rmd160 of the sha256 of the 256 bit privkey, basically the precursor to all bitcoin type of addresses in a coin agnostic format, so this handles all the blockchains that use a bitcoin type of addressing. For blockchains that do not, the method to map its privkeys to a 256 bit privkey needs to be defined. Then the standard rmd160(sha256(mapped privkey)) will be the address + +If many exports from multiple blockchains are done all at the same time, it might be desireable to create an ordering of the exports. To facilitate this, the lower 64-bits of a recent BTC blockhash can be added. Any time sequence resolution will use the height of the first BTC blockhash that matches, scanning backward from the likely starting point based on the source blockchain's timestamp. In order to compensate for clock drift, it is advised to select a BTC block that is 2 blocks in the past. In the event there are multiple exports still tied, the lower 64bits of the txids will be used for a tiebreak. In the event there are still multiple exports tied, then the blockchain code from above will be used. In the event there are multiple exports from the same blockchain that are still tied, then that local blockchain's transaction ordering will be used. + +By encoding the above 21 (or 28) bytes into the existing blockchain with the burning of the asset on that blockchain, it no longer exists on the source blockchain and it has a unique destination blockchain. + +Requiring all blockchains to be monitoring all the other blockchains creates an N*N complexity where each blockchain needs to be able to read all the other blockchains. In order to simplify this, the BTCD blockchain can be used to provide a single blockchain that can be accessed via SuperNET API locally or remotely to retrieve a list of asset exports. To facilitate this a BTCD 'APS' OP_RETURN needs to be created by the client software: + + OP_RETURN + 'A' + 'P' + 'S' + <21 or 28 bytes> + + + + + -> contents to be verified against the <21 or 28 bytes> + -> only needed if original and source blockchain are different + -> to be verified with the signer's pubkey of the blockchain txid signer + + + Asset Import + Importing assets creates a rather troublesome issue, in that to make it fully automated, all blockchains would need to monitor all the other blockchains for valid Asset Exports and then also to properly issue newly created assets to match. Since some blockchains are not able to issue more assets after the initial issuance, there needs to be a way for a reserve amount of assets to be transfered on demand. However, keeping this reserve totally blockchain controlled could be problematic for some blockchains, so provision for the asset issuer to sign a transfer for valid exports is needed. + + Which leads to the following simplification of the process. The asset issuer needs to run a special automated process that monitor's for Asset Exports and when it is received, to send out the appropriate new asset on the destination blockchain. This allows the asset issuer to create appropriate assets on each blockchain and can encapsulate whether new assets are created dynamically, or transferred from a reserve account. When an asset is created for the APS on a blockchain, its specifics should be recorded on the BTCD APS OP_RETURN by the asset issuer: + + OP_RETURN + 'A' + 'P' + 'S' + + + + + + + + -> to be verified with the issuer's pubkey + + + When the matching Asset Import is completed for an Asset Export, this needs to be recorded with a BTCD APS: + + OP_RETURN + 'A' + 'P' + 'S' + + + + + -> to be verified with the issuer's pubkey + + + + All of the BTCD APS OP_RETURNS can have security added to them by generating a matched BTC APS OP_RETURN with the SHA256 of the contents of the BTCD APS (including the signature) + + In order to simplify signature validation, all signatures will use secp256k1 signatures of the double sha256 hash of the contents. + +Given the above set of APS OP_RETURNS, the SuperNET passport API will provide aggregate information on the global assets, such as total issued, circulation, assetid mappings, etc + */ diff --git a/iguana/iguana_payments.c b/iguana/iguana_payments.c new file mode 100755 index 000000000..746950e34 --- /dev/null +++ b/iguana/iguana_payments.c @@ -0,0 +1,818 @@ +/****************************************************************************** + * 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" + +char *iguana_APIrequest(struct iguana_info *coin,bits256 blockhash,bits256 txid,int32_t seconds) +{ + int32_t i,len; char *retstr = 0; uint8_t serialized[1024]; char str[65]; + coin->APIblockhash = blockhash; + coin->APItxid = txid; + printf("request block.(%s) txid.%llx\n",bits256_str(str,blockhash),(long long)txid.txid); + if ( (len= iguana_getdata(coin,serialized,MSG_BLOCK,&blockhash,1)) > 0 ) + { + for (i=0; iAPIblockstr != 0 ) + { + retstr = coin->APIblockstr; + coin->APIblockstr = 0; + memset(&coin->APIblockhash,0,sizeof(coin->APIblockhash)); + memset(&coin->APItxid,0,sizeof(coin->APItxid)); + return(retstr); + } + sleep(1); + } + } + return(0); +} + +bits256 iguana_str2priv(struct supernet_info *myinfo,struct iguana_info *coin,char *str) +{ + bits256 privkey; int32_t n; uint8_t addrtype; struct iguana_waccount *wacct=0; struct iguana_waddress *waddr; + memset(&privkey,0,sizeof(privkey)); + if ( str != 0 ) + { + n = (int32_t)strlen(str) >> 1; + if ( n == sizeof(bits256) && is_hexstr(str,sizeof(bits256)) > 0 ) + decode_hex(privkey.bytes,sizeof(privkey),str); + else if ( bitcoin_wif2priv(&addrtype,&privkey,str) != sizeof(bits256) ) + { + if ( (waddr= iguana_waddresssearch(myinfo,coin,&wacct,str)) != 0 ) + privkey = waddr->privkey; + else memset(privkey.bytes,0,sizeof(privkey)); + } + } + return(privkey); +} + +int32_t iguana_pubkeyget(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t *pubkey33,char *str) +{ + bits256 privkey,pubkey; uint8_t pubkeydata[128]; int32_t len,plen= -1; struct iguana_waccount *wacct; struct iguana_waddress *waddr; + len = (int32_t)strlen(str); + if ( is_hexstr(str,len) == 0 ) + { + if ( (waddr= iguana_waddresssearch(myinfo,coin,&wacct,str)) != 0 ) + { + if ( (plen= bitcoin_pubkeylen(waddr->pubkey)) > 0 ) + memcpy(pubkeydata,waddr->pubkey,plen); + } + } + else + { + decode_hex(pubkeydata,len,str); + plen = bitcoin_pubkeylen(pubkeydata); + } + if ( plen <= 0 ) + { + privkey = iguana_str2priv(myinfo,coin,str); + if ( bits256_nonz(privkey) == 0 ) + return(-1); + else + { + pubkey = bitcoin_pubkey33(myinfo->ctx,pubkeydata,privkey); + if ( bits256_nonz(pubkey) == 0 ) + return(-1); + } + } + if ( (plen= bitcoin_pubkeylen(pubkeydata)) > 0 ) + memcpy(pubkey33,pubkeydata,plen); + return(0); +} + +cJSON *iguana_p2shjson(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *retjson,struct iguana_waddress *waddr) +{ + char str[4096]; uint8_t type; struct iguana_waccount *wacct; bits256 debugtxid; struct vin_info V; cJSON *privkeys,*pubkeys,*addresses; int32_t i,plen; + if ( retjson == 0 ) + retjson = cJSON_CreateObject(); + init_hexbytes_noT(str,waddr->redeemScript,waddr->scriptlen); + jaddstr(retjson,"redeemScript",str); + memset(debugtxid.bytes,0,sizeof(debugtxid)); + if ( (type= iguana_calcrmd160(coin,0,&V,waddr->redeemScript,waddr->scriptlen, debugtxid,-1,0xffffffff)) >= 0 ) + { + privkeys = cJSON_CreateArray(); + pubkeys = cJSON_CreateArray(); + addresses = cJSON_CreateArray(); + for (i=0; iwifstr[0] != 0 ) + jaddistr(privkeys,waddr->wifstr); + else jaddistr(privkeys,""); + if ( (plen= bitcoin_pubkeylen(V.signers[i].pubkey)) > 0 ) + { + init_hexbytes_noT(str,V.signers[i].pubkey,plen); + jaddistr(pubkeys,str); + } else jaddistr(pubkeys,""); + jaddistr(addresses,V.signers[i].coinaddr); + } + jaddstr(retjson,"result",V.coinaddr); + jaddnum(retjson,"M",V.M); + jaddnum(retjson,"N",V.N); + jadd(retjson,"pubkeys",pubkeys); + jadd(retjson,"privkeys",privkeys); + jadd(retjson,"addresses",addresses); + } + return(retjson); +} + +cJSON *iguana_scriptobj(struct iguana_info *coin,uint8_t rmd160[20],char *coinaddr,char *asmstr,uint8_t *script,int32_t scriptlen) +{ + struct vin_info V; int32_t i,plen,asmtype; char pubkeystr[130],rmdstr[41]; cJSON *addrobj,*scriptobj=cJSON_CreateObject(); + if ( (asmtype= iguana_calcrmd160(coin,asmstr,&V,script,scriptlen,rand256(0),1,0xffffffff)) >= 0 ) + { + if ( asmstr != 0 && asmstr[0] != 0 ) + jaddstr(scriptobj,"asm",asmstr); + jaddnum(scriptobj,"iguanatype",asmtype); + jaddnum(scriptobj,"scriptlen",scriptlen); + jaddnum(scriptobj,"reqSigs",V.M); + if ( (plen= bitcoin_pubkeylen(V.signers[0].pubkey)) > 0 ) + { + init_hexbytes_noT(pubkeystr,V.signers[0].pubkey,plen); + jaddstr(scriptobj,"pubkey",pubkeystr); + init_hexbytes_noT(rmdstr,V.signers[0].rmd160,20); + jaddstr(scriptobj,"rmd160",rmdstr); + } + addrobj = cJSON_CreateArray(); + for (i=0; i [comment] [comment-to] is a real and is rounded to 8 decimal places. Returns the transaction ID if successful. Y + if ( coinaddr != 0 && coinaddr[0] != 0 && satoshis != 0 ) + { + if ( iguana_addressvalidate(coin,&addrtype,rmd160,coinaddr) < 0 ) + return(clonestr("{\"error\":\"invalid coin address\"}")); + waddrs = (struct iguana_waddress **)coin->blockspace; + numwaddrs = iguana_unspentslists(myinfo,coin,waddrs,(int32_t)(sizeof(coin->blockspace)/sizeof(*waddrs)),satoshis,minconf,0); + if ( numwaddrs > 0 ) + { + unspents = (uint64_t *)((long)coin->blockspace + sizeof(*waddrs)*numwaddrs); + for (i=0; inumunspents > 0 ) + { + for (j=0; jnumunspents; j++) + printf("([%d].u%u) ",(uint32_t)(unspents[i]>>32),(uint32_t)unspents[i]); + printf("(%s %.8f)\n",waddr->coinaddr,dstr(waddr->balance)); + } + } + } + printf("need to generate send %.8f to %s [%s] [%s] using numaddrs.%d numunspents.%d\n",dstr(satoshis),coinaddr,comment!=0?comment:"",comment2!=0?comment2:"",numwaddrs,numunspents); + } + return(clonestr("{\"error\":\"need address and amount\"}")); +} + +#include "../includes/iguana_apidefs.h" +#include "../includes/iguana_apideclares.h" + +STRING_AND_INT(bitcoinrpc,sendrawtransaction,rawtx,allowhighfees) +{ + cJSON *retjson = cJSON_CreateObject(); char txidstr[65]; bits256 txid; uint8_t *serialized; struct iguana_peer *addr; int32_t i,len = (int32_t)strlen(rawtx) >> 1; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( coin->peers.numranked >= 8 ) + { + serialized = calloc(1,sizeof(struct iguana_msghdr) + len); + decode_hex(&serialized[sizeof(struct iguana_msghdr)],len,rawtx); + for (i=0; i<8; i++) + { + if ( (addr= coin->peers.ranked[i]) != 0 && addr->dead == 0 && addr->usock >= 0 ) + iguana_queue_send(coin,addr,0,serialized,"tx",len,0,0); + } + free(serialized); + txid = bits256_doublesha256(txidstr,&serialized[sizeof(struct iguana_msghdr)],len); + jaddstr(retjson,"result",txidstr); + } else jaddstr(retjson,"error","no peers"); + return(jprint(retjson,1)); +} + +STRING_ARG(bitcoinrpc,submitblock,rawbytes) +{ + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + cJSON *retjson = cJSON_CreateObject(); + // send to all peers + return(jprint(retjson,1)); +} + +ZERO_ARGS(bitcoinrpc,makekeypair) +{ + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + bits256 privkey; char str[67]; cJSON *retjson = cJSON_CreateObject(); + privkey = rand256(1); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"privkey",bits256_str(str,privkey)); + jadd(retjson,"rosetta",SuperNET_rosettajson(privkey,1)); + return(jprint(retjson,1)); +} + +STRING_ARG(bitcoinrpc,validatepubkey,pubkeystr) +{ + uint8_t rmd160[20],pubkey[65],addrtype = 0; int32_t plen; char coinaddr[128],*str; cJSON *retjson; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + plen = (int32_t)strlen(pubkeystr) >> 1; + if ( plen >= 33 && plen <= 65 && coin != 0 && coin->chain != 0 ) + { + addrtype = coin->chain->pubtype; + decode_hex(pubkey,plen,pubkeystr); + if ( (str= bitcoin_address(coinaddr,addrtype,pubkey,plen)) != 0 ) + { + if ( iguana_addressvalidate(coin,&addrtype,rmd160,coinaddr) < 0 ) + return(clonestr("{\"error\":\"invalid coin address\"}")); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"pubkey",pubkeystr); + jaddstr(retjson,"address",coinaddr); + jaddstr(retjson,"coin",coin->symbol); + return(jprint(retjson,1)); + } + } + return(clonestr("{\"error\":\"invalid pubkey\"}")); +} + +STRING_ARG(bitcoinrpc,decodescript,scriptstr) +{ + int32_t scriptlen; uint8_t script[IGUANA_MAXSCRIPTSIZE],rmd160[20]; char coinaddr[128],asmstr[IGUANA_MAXSCRIPTSIZE*2+1]; cJSON *scriptobj,*retjson = cJSON_CreateObject(); + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( scriptstr != 0 && coin != 0 && (scriptlen= (int32_t)strlen(scriptstr)>>1) < sizeof(script) ) + { + decode_hex(script,scriptlen,scriptstr); + if ( (scriptobj= iguana_scriptobj(coin,rmd160,coinaddr,asmstr,script,scriptlen)) != 0 ) + jadd(retjson,"result",scriptobj); + } + return(jprint(retjson,1)); +} + +INT_ARRAY_STRING(bitcoinrpc,createmultisig,M,pubkeys,ignore) +{ + cJSON *retjson,*pkjson,*addresses; uint8_t script[2048],p2sh_rmd160[20]; char pubkeystr[256],msigaddr[64],*pkstr,scriptstr[sizeof(script)*2+1]; struct vin_info V; int32_t i,plen,len,n = cJSON_GetArraySize(pubkeys); + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( n < 0 || n > 16 || M < 0 || M > n ) + return(clonestr("{\"error\":\"illegal number of pubkeys\"}")); + memset(&V,0,sizeof(V)); + V.M = M, V.N = n; + pkjson = cJSON_CreateArray(); + addresses = cJSON_CreateArray(); + for (i=0; ichain->pubtype,V.signers[i].pubkey,plen); + jaddistr(addresses,V.signers[i].coinaddr); + init_hexbytes_noT(pubkeystr,V.signers[i].pubkey,plen); + jaddistr(pkjson,pubkeystr); + } else break; + } + retjson = cJSON_CreateObject(); + if ( i == n ) + { + len = bitcoin_MofNspendscript(p2sh_rmd160,script,0,&V); + bitcoin_address(msigaddr,coin->chain->p2shtype,p2sh_rmd160,sizeof(p2sh_rmd160)); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"address",msigaddr); + init_hexbytes_noT(scriptstr,script,len); + jaddstr(retjson,"redeemScript",scriptstr); + jaddnum(retjson,"M",M); + jaddnum(retjson,"N",n); + jadd(retjson,"pubkeys",pkjson); + jadd(retjson,"addresses",addresses); + } + else + { + jaddstr(retjson,"error","couldnt get all pubkeys"); + free_json(pkjson); + } + return(jprint(retjson,1)); +} + +INT_ARRAY_STRING(bitcoinrpc,addmultisigaddress,M,pubkeys,account) // +{ + cJSON *retjson,*tmpjson,*setjson=0; char *retstr,*str=0,*msigaddr,*redeemScript; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + myinfo->expiration++; + if ( (retstr= bitcoinrpc_createmultisig(IGUANA_CALLARGS,M,pubkeys,account)) != 0 ) + { + //printf("CREATEMULTISIG.(%s)\n",retstr); + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (msigaddr= jstr(retjson,"address")) != 0 ) + { + if ( (redeemScript= jstr(retjson,"redeemScript")) == 0 || (str= setaccount(myinfo,coin,0,account,msigaddr,redeemScript)) == 0 || (setjson= cJSON_Parse(str)) == 0 || jobj(setjson,"error") != 0 ) + { + if ( jobj(retjson,"result") != 0 ) + jdelete(retjson,"result"); + if ( jobj(retjson,"error") == 0 ) + jaddstr(retjson,"error","couldnt add multisig address to account"); + } + else + { + tmpjson = cJSON_CreateObject(); + jaddstr(tmpjson,"result",msigaddr); + free_json(retjson); + free(retstr); + retjson = tmpjson; + } + } + if ( setjson != 0 ) + free_json(setjson); + if ( str != 0 ) + free(str); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"couldnt parse retstr from createmultisig\"}")); + } else return(clonestr("{\"error\":\"no retstr from createmultisig\"}")); +} + +HASH_AND_TWOINTS(bitcoinrpc,gettxout,txid,vout,mempool) +{ + uint8_t script[IGUANA_MAXSCRIPTSIZE],rmd160[20],pubkey33[33]; char coinaddr[128],asmstr[IGUANA_MAXSCRIPTSIZE*2+1]; struct iguana_bundle *bp; int32_t minconf,scriptlen,unspentind,height,spentheight; int64_t RTspend; struct iguana_ramchaindata *rdata; struct iguana_pkhash *P; struct iguana_txid *T; struct iguana_unspent *U; struct iguana_ramchain *ramchain; cJSON *scriptobj,*retjson = cJSON_CreateObject(); + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( coin != 0 ) + { + minconf = (mempool != 0) ? 0 : 1; + if ( (unspentind= iguana_unspentindfind(coin,0,0,0,0,&height,txid,vout,coin->bundlescount-1)) != 0 ) + { + if ( height >= 0 && height < coin->longestchain && (bp= coin->bundles[height / coin->chain->bundlesize]) != 0 ) + { + ramchain = (bp == coin->current) ? &coin->RTramchain : &bp->ramchain; + if ( (rdata= ramchain->H.data) != 0 ) + { + U = RAMCHAIN_PTR(rdata,Uoffset); + P = RAMCHAIN_PTR(rdata,Poffset); + T = RAMCHAIN_PTR(rdata,Toffset); + //U = (void *)(long)((long)rdata + rdata->Uoffset); + //P = (void *)(long)((long)rdata + rdata->Poffset); + //T = (void *)(long)((long)rdata + rdata->Toffset); + RTspend = 0; + if ( iguana_spentflag(coin,&RTspend,&spentheight,ramchain,bp->hdrsi,unspentind,height,minconf,coin->longestchain,U[unspentind].value) == 0 ) + { + jaddbits256(retjson,"bestblock",coin->blocks.hwmchain.RO.hash2); + jaddnum(retjson,"bestheight",coin->blocks.hwmchain.height); + jaddnum(retjson,"height",height); + jaddnum(retjson,"confirmations",coin->blocks.hwmchain.height - height + 1); + jaddnum(retjson,"value",dstr(U[unspentind].value)); + memset(rmd160,0,sizeof(rmd160)); + memset(pubkey33,0,sizeof(pubkey33)); + memset(coinaddr,0,sizeof(coinaddr)); + if ( (scriptlen= iguana_voutscript(coin,bp,script,0,&U[unspentind],&P[U[unspentind].pkind],vout)) > 0 ) + { + if ( (scriptobj= iguana_scriptobj(coin,rmd160,coinaddr,asmstr,script,scriptlen)) != 0 ) + jadd(retjson,"scriptPubKey",scriptobj); + } + jadd(retjson,"iguana",iguana_unspentjson(myinfo,coin,bp->hdrsi,unspentind,T,&U[unspentind],rmd160,coinaddr,pubkey33)); + if ( (height % coin->chain->bundlesize) == 0 && vout == 0 ) + jadd(retjson,"coinbase",jtrue()); + else jadd(retjson,"coinbase",jfalse()); + } + else + { + jaddstr(retjson,"error","already spent"); + jaddnum(retjson,"spentheight",spentheight); + jaddnum(retjson,"unspentind",unspentind); + } + } + } + } + } + return(jprint(retjson,1)); +} + +bits256 iguana_messagehash2(char *message,char *messagemagic) +{ + int32_t n,len; uint8_t *messagebuf; bits256 hash2; + n = (int32_t)strlen(message) >> 1; + len = (int32_t)strlen(messagemagic); + if ( message[0] == '0' && message[1] == 'x' && is_hexstr(message+2,n-2) > 0 ) + { + messagebuf = malloc(n-2 + len); + memcpy(messagebuf,messagemagic,len); + decode_hex(messagebuf+len,n-2,message+2); + n--; + } + else + { + n <<= 1; + messagebuf = malloc(n + len + 1); + memcpy(messagebuf,messagemagic,len); + strcpy((void *)&messagebuf[len],message); + //printf("MESSAGE.(%s)\n",(void *)messagebuf); + } + n += len; + hash2 = bits256_doublesha256(0,messagebuf,n); + //for (i=0; iexpiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + if ( coin != 0 ) + { + privkey = iguana_str2priv(myinfo,coin,address); + if ( bits256_nonz(privkey) != 0 ) + { + hash2 = iguana_messagehash2(message,coin->chain->messagemagic); + if ( (siglen= bitcoin_sign(coin->ctx,coin->symbol,sig,hash2,privkey,1)) > 0 ) + { + sigstr[0] = sig65str[0] = 0; + len = nn_base64_encode(sig,siglen,sig65str,sizeof(sig65str)); + sig65str[len] = 0; + jaddstr(retjson,"result",sig65str); + } + } else jaddstr(retjson,"error","invalid address (can be wif, wallet address or privkey hex)"); + } + return(jprint(retjson,1)); +} + +THREE_STRINGS(bitcoinrpc,verifymessage,address,sig,message) +{ + int32_t len,plen; uint8_t sigbuf[256],pubkey[65]; char str[4096]; bits256 hash2; cJSON *retjson = cJSON_CreateObject(); + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( strlen(sig) < sizeof(sigbuf)*8/6 ) + { + len = (int32_t)strlen(sig); + len = nn_base64_decode(sig,len,sigbuf,sizeof(sigbuf)); + //int32_t i; for (i=0; ichain->messagemagic); + if ( bitcoin_recoververify(myinfo->ctx,coin->symbol,sigbuf,hash2,pubkey) == 0 ) + jadd(retjson,"result",jtrue()); + else jadd(retjson,"result",jfalse()); + jaddstr(retjson,"coin",coin->symbol); + jaddstr(retjson,"address",address); + jaddstr(retjson,"message",message); + if ( (plen= bitcoin_pubkeylen(pubkey)) > 0 ) + { + init_hexbytes_noT(str,pubkey,plen); + jaddstr(retjson,"pubkey",str); + } + init_hexbytes_noT(str,sigbuf,len); + jaddstr(retjson,"sighex",str); + jaddbits256(retjson,"messagehash",hash2); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"sig is too long\"}")); +} + +HASH_AND_INT(bitcoinrpc,getrawtransaction,txid,verbose) +{ + struct iguana_txid *tx,T; char *txbytes; bits256 checktxid; int32_t len,height; cJSON *retjson,*txobj; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( (tx= iguana_txidfind(coin,&height,&T,txid,coin->bundlescount-1)) != 0 ) + { + retjson = cJSON_CreateObject(); + if ( (len= iguana_ramtxbytes(coin,coin->blockspace,sizeof(coin->blockspace),&checktxid,tx,height,0,0,0)) > 0 ) + { + txbytes = calloc(1,len*2+1); + init_hexbytes_noT(txbytes,coin->blockspace,len); + if ( verbose != 0 ) + { + txobj = bitcoin_hex2json(coin,&checktxid,0,txbytes); + free(txbytes); + if ( txobj != 0 ) + return(jprint(txobj,1)); + } + jaddstr(retjson,"result",txbytes); + printf("txbytes.(%s) len.%d (%s)\n",txbytes,len,jprint(retjson,0)); + free(txbytes); + return(jprint(retjson,1)); + } + else if ( height >= 0 ) + { + if ( coin->APIblockstr != 0 ) + jaddstr(retjson,"error","already have pending request"); + else + { + int32_t datalen; uint8_t *data; char *blockstr; bits256 blockhash; + blockhash = iguana_blockhash(coin,height); + if ( (blockstr= iguana_APIrequest(coin,blockhash,txid,2)) != 0 ) + { + datalen = (int32_t)(strlen(blockstr) >> 1); + data = malloc(datalen); + decode_hex(data,datalen,blockstr); + if ( (txbytes= iguana_txscan(coin,verbose != 0 ? retjson : 0,data,datalen,txid)) != 0 ) + { + jaddstr(retjson,"result",txbytes); + jaddbits256(retjson,"blockhash",blockhash); + jaddnum(retjson,"height",height); + free(txbytes); + } else jaddstr(retjson,"error","cant find txid in block"); + free(blockstr); + free(data); + } else jaddstr(retjson,"error","cant find blockhash"); + return(jprint(retjson,1)); + } + } else printf("height.%d\n",height); + } + return(clonestr("{\"error\":\"cant find txid\"}")); +} + +STRING_ARG(bitcoinrpc,decoderawtransaction,rawtx) +{ + cJSON *txobj = 0; bits256 txid; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( rawtx != 0 && rawtx[0] != 0 ) + { + if ( (strlen(rawtx) & 1) != 0 ) + return(clonestr("{\"error\":\"rawtx hex has odd length\"}")); + txobj = bitcoin_hex2json(coin,&txid,0,rawtx); + //char str[65]; printf("got txid.(%s)\n",bits256_str(str,txid)); + } + if ( txobj == 0 ) + txobj = cJSON_CreateObject(); + return(jprint(txobj,1)); +} + +HASH_ARG(bitcoinrpc,gettransaction,txid) +{ + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + return(bitcoinrpc_getrawtransaction(IGUANA_CALLARGS,txid,1)); +} + +cJSON *iguana_createvins(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *txobj,cJSON *vins) +{ + int32_t i,n,vout,p2shlen=0,spendlen=0,unspentind,height; uint64_t satoshis; char coinaddr[128],pubkeystr[256],scriptstr[IGUANA_MAXSCRIPTSIZE*2],*str,*hexstr; cJSON *pubkeys,*item,*obj,*newvin,*newvins; uint32_t sequenceid; bits256 txid; uint8_t spendscript[IGUANA_MAXSCRIPTSIZE],redeemscript[IGUANA_MAXSCRIPTSIZE]; struct iguana_waccount *wacct; struct iguana_waddress *waddr; + newvins = cJSON_CreateArray(); + if ( (n= cJSON_GetArraySize(vins)) > 0 ) + { + for (i=0; i 0 ) + { + spendlen = (int32_t)strlen(str) >> 1; + decode_hex(spendscript,spendlen,str); + } + else if ( ((obj= jobj(item,"scriptPub")) != 0 || (obj= jobj(item,"scriptPubkey")) != 0) && (hexstr= jstr(obj,"hex")) != 0 ) + { + spendlen = (int32_t)strlen(hexstr) >> 1; + decode_hex(spendscript,spendlen,hexstr); + } + if ( (unspentind= iguana_unspentindfind(coin,coinaddr,spendscript,&spendlen,&satoshis,&height,txid,vout,coin->bundlescount-1)) > 0 ) + { + printf("[%d] unspentind.%d (%s) spendlen.%d %.8f\n",height/coin->chain->bundlesize,unspentind,coinaddr,spendlen,dstr(satoshis)); + if ( coinaddr[0] != 0 && (waddr= iguana_waddresssearch(myinfo,coin,&wacct,coinaddr)) != 0 ) + { + init_hexbytes_noT(pubkeystr,waddr->pubkey,bitcoin_pubkeylen(waddr->pubkey)); + jaddistr(pubkeys,pubkeystr); + } + } + if ( spendlen > 0 ) + { + init_hexbytes_noT(scriptstr,spendscript,spendlen); + jaddstr(newvin,"scriptPub",scriptstr); + } + if ( (str= jstr(item,"redeemScript")) != 0 ) + { + p2shlen = (int32_t)strlen(str) >> 1; + decode_hex(redeemscript,p2shlen,str); + init_hexbytes_noT(scriptstr,redeemscript,p2shlen); + jaddstr(newvin,"redeemScript",scriptstr); + } + if ( jobj(item,"sequence") != 0 ) + sequenceid = juint(item,"sequence"); + else sequenceid = 0xffffffff; + jaddnum(newvin,"sequence",sequenceid); + bitcoin_txinput(coin,txobj,txid,vout,sequenceid,spendscript,spendlen,redeemscript,p2shlen,0,0); + jadd(newvin,"pubkeys",pubkeys); + jaddi(newvins,newvin); + } + } + return(newvins); +} + +ARRAY_OBJ_INT(bitcoinrpc,createrawtransaction,vins,vouts,locktime) +{ + bits256 txid; int32_t offset,spendlen=0,n; uint8_t addrtype,rmd160[20],spendscript[IGUANA_MAXSCRIPTSIZE]; uint64_t satoshis; char *hexstr,*field,*txstr; cJSON *txobj,*item,*obj,*retjson = cJSON_CreateObject(); + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( coin != 0 && (txobj= bitcoin_txcreate(coin,locktime)) != 0 ) + { + iguana_createvins(myinfo,coin,txobj,vins); + if ( (n= cJSON_GetArraySize(vouts)) > 0 ) + { + if ( (item= vouts->child) != 0 && n == 1 ) + item = item->child; + while ( item != 0 ) + { + if ( (field= jfieldname(item)) != 0 ) + { + if ( strcmp(field,"data") == 0 ) + { + if ( (hexstr= jstr(item,"data")) != 0 ) + { + spendlen = (int32_t)strlen(hexstr) >> 1; + offset = 0; + if ( is_hexstr(hexstr,spendlen) > 0 ) + { + decode_hex(spendscript+4,spendlen,hexstr); + spendscript[3] = SCRIPT_OPRETURN; + spendlen++; + /* 1-75 0x01-0x4b (special) data The next opcode bytes is data to be pushed onto the stack + OP_PUSHDATA1 76 0x4c (special) data The next byte contains the number of bytes to be pushed onto the stack. + OP_PUSHDATA2 77 0x4d*/ + if ( spendlen < 76 ) + { + spendscript[2] = spendlen; + offset = 2; + spendlen++; + } + else if ( spendlen <= 0xff ) + { + spendscript[2] = spendlen; + spendscript[1] = 0x4c; + offset = 1; + spendlen += 2; + } + else if ( spendlen <= 0xffff ) + { + spendscript[2] = ((spendlen >> 8) & 0xff); + spendscript[1] = (spendlen & 0xff); + spendscript[0] = 0x4d; + offset = 0; + spendlen += 3; + } + else continue; + if ( (obj= jobj(item,"amount")) != 0 ) + satoshis = jdouble(obj,0) * SATOSHIDEN; + else satoshis = 0; + bitcoin_txoutput(coin,txobj,spendscript+offset,spendlen,satoshis); + } + } + break; + } + else + { + if ( bitcoin_addr2rmd160(&addrtype,rmd160,field) == sizeof(rmd160) ) + { + spendlen = bitcoin_standardspend(spendscript,0,rmd160); + satoshis = jdouble(item,0) * SATOSHIDEN; + bitcoin_txoutput(coin,txobj,spendscript,spendlen,satoshis); + } + } + } + item = item->next; + } + } + if ( (txstr= bitcoin_json2hex(myinfo,coin,&txid,txobj,0)) != 0 ) + { + jaddstr(retjson,"result",txstr); + free(txstr); + } + } + return(jprint(retjson,1)); +} + +TWOINTS_AND_ARRAY(bitcoinrpc,listunspent,minconf,maxconf,array) +{ + int32_t numrmds,numunspents=0; uint8_t *rmdarray; cJSON *retjson = cJSON_CreateArray(); + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( minconf == 0 ) + minconf = 1; + if ( maxconf == 0 ) + maxconf = 9999999; + rmdarray = iguana_rmdarray(coin,&numrmds,array,0); + iguana_unspents(myinfo,coin,retjson,minconf,maxconf,rmdarray,numrmds,0,0,&numunspents); + if ( rmdarray != 0 ) + free(rmdarray); + return(jprint(retjson,1)); +} + +INT_AND_ARRAY(bitcoinrpc,lockunspent,flag,array) +{ + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + cJSON *retjson = cJSON_CreateObject(); + return(jprint(retjson,1)); +} + +ZERO_ARGS(bitcoinrpc,listlockunspent) +{ + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + cJSON *retjson = cJSON_CreateObject(); + return(jprint(retjson,1)); +} + +DOUBLE_ARG(bitcoinrpc,settxfee,amount) +{ + cJSON *retjson; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + myinfo->expiration++; + coin->txfee_perkb = amount * SATOSHIDEN; + retjson = cJSON_CreateObject(); + jadd(retjson,"result",jtrue()); + return(jprint(retjson,1)); +} + +S_D_SS(bitcoinrpc,sendtoaddress,address,amount,comment,comment2) +{ + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + myinfo->expiration++; + iguana_unspentset(myinfo,coin); + return(sendtoaddress(myinfo,coin,address,amount * SATOSHIDEN,comment,comment2,coin->minconfirms,0)); +} + +SS_D_I_SS(bitcoinrpc,sendfrom,fromaccount,toaddress,amount,minconf,comment,comment2) +{ + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + myinfo->expiration++; + iguana_unspentset(myinfo,coin); + return(sendtoaddress(myinfo,coin,toaddress,amount * SATOSHIDEN,comment,comment2,minconf,fromaccount)); +} + +S_A_I_S(bitcoinrpc,sendmany,fromaccount,payments,minconf,comment) +{ + cJSON *retjson,*item; int32_t i,n; char *coinaddr,*str; int64_t required,val; double amount; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + myinfo->expiration++; + iguana_unspentset(myinfo,coin); + n = cJSON_GetArraySize(payments); + item = payments->child; + for (required=i=0; istring) != 0 ) + { + amount = jdouble(item,0); + val = amount * SATOSHIDEN; + printf("(%s %.8f) ",coinaddr,dstr(val)); + if ( (str= sendtoaddress(myinfo,coin,coinaddr,val,comment,"",minconf,fromaccount)) != 0 ) + { + free(str); + } + required += val; + } + item = item->next; + } + printf("required %.8f\n",dstr(required)); + retjson = cJSON_CreateObject(); + return(jprint(retjson,1)); +} + +#include "../includes/iguana_apiundefs.h" diff --git a/iguana/iguana_peers.c b/iguana/iguana_peers.c index 319855260..74243e12f 100755 --- a/iguana/iguana_peers.c +++ b/iguana/iguana_peers.c @@ -18,7 +18,25 @@ #define _iguana_hashfind(coin,ipbits) _iguana_hashset(coin,ipbits,-1) struct iguana_iAddr *iguana_iAddrhashfind(struct iguana_info *coin,uint64_t ipbits,int32_t createflag); -struct iguana_iAddr *_iguana_hashset(struct iguana_info *coin,uint64_t ipbits,int32_t itemind) +int32_t iguana_validatehdr(char *symbol,struct iguana_msghdr *H) +{ + 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); +} + +struct iguana_iAddr *_iguana_hashset(struct iguana_info *coin,uint32_t ipbits,int32_t itemind) { struct iguana_iAddr *ptr = 0; int32_t allocsize; char str[65]; struct OS_memspace *mem = 0; expand_ipbits(str,ipbits); @@ -33,7 +51,7 @@ struct iguana_iAddr *_iguana_hashset(struct iguana_info *coin,uint64_t ipbits,in ptr = iguana_memalloc(mem,allocsize,1); else ptr = mycalloc('t',1,allocsize); if ( ptr == 0 ) - printf("fatal alloc error in hashset\n"), exit(-1); + printf("fatal alloc errorA in hashset\n"), exit(-1); //printf("ptr.%p allocsize.%d key.%p keylen.%d itemind.%d\n",ptr,allocsize,key,keylen,itemind); ptr->hh.itemind = itemind; ptr->ipbits = ipbits; @@ -61,15 +79,15 @@ struct iguana_iAddr *iguana_iAddrhashset(struct iguana_info *coin,struct iguana_ return(0); } portable_mutex_lock(&coin->peers_mutex); - if ( (item= _iguana_hashfind(coin,iA->ipbits)) == 0 ) + if ( (item= _iguana_hashfind(coin,(uint32_t)iA->ipbits)) == 0 ) { tmp = mycalloc('i',1,sizeof(*iA)); *tmp = *iA; iA = tmp; if ( ind <= 0 ) ind = coin->numiAddrs + 1; - //printf("coin->iAddrs.%p call set.(%x) ind.%d\n",coin->iAddrs,iA->ipbits,iA->ind); - if ( (item= _iguana_hashset(coin,iA->ipbits,ind)) != 0 && item->hh.itemind == coin->numiAddrs+1 ) + printf("coin->iAddrs.%p call set.(%x) ind.%d\n",coin->iAddrs,(uint32_t)iA->ipbits,ind); + if ( (item= _iguana_hashset(coin,(uint32_t)iA->ipbits,ind)) != 0 && item->hh.itemind == coin->numiAddrs+1 ) { *item = *iA; iA = item; @@ -93,11 +111,11 @@ struct iguana_iAddr *iguana_iAddrhashfind(struct iguana_info *coin,uint64_t ipbi portable_mutex_lock(&coin->peers_mutex); if ( ipbits != 0 ) { - if ( (item= _iguana_hashfind(coin,ipbits)) == 0 && createflag != 0 ) + if ( (item= _iguana_hashfind(coin,(uint32_t)ipbits)) == 0 && createflag != 0 ) { ind = coin->numiAddrs + 1; - _iguana_hashset(coin,ipbits,ind); - if ( (item= _iguana_hashfind(coin,ipbits)) != 0 ) + _iguana_hashset(coin,(uint32_t)ipbits,ind); + if ( (item= _iguana_hashfind(coin,(uint32_t)ipbits)) != 0 ) coin->numiAddrs++; } } @@ -107,9 +125,8 @@ struct iguana_iAddr *iguana_iAddrhashfind(struct iguana_info *coin,uint64_t ipbi uint32_t iguana_rwiAddrind(struct iguana_info *coin,int32_t rwflag,struct iguana_iAddr *iA,uint32_t ind) { - FILE *fp; char fname[512],hexstr[65]; int32_t i,n,m,retval = 0; struct iguana_iAddr tmp,*ptr; - sprintf(fname,"DB/%s/peers.dat",coin->symbol); - OS_compatible_path(fname); + FILE *fp; char fname[512],hexstr[65],ipaddr[64]; uint32_t ipbits; int32_t i,n,m,retval = 0; struct iguana_iAddr tmp,*ptr; + sprintf(fname,"%s/%s_peers.dat",GLOBAL_DBDIR,coin->symbol), OS_compatible_path(fname); if ( rwflag < 0 || iA == 0 ) { coin->numiAddrs = 0; @@ -117,33 +134,41 @@ uint32_t iguana_rwiAddrind(struct iguana_info *coin,int32_t rwflag,struct iguana { fseek(fp,0,SEEK_END); n = (int32_t)(ftell(fp) / sizeof(*iA)); - for (i=m=0; ipeers_mutex); - HASH_FIND(hh,coin->iAddrs,&tmp.ipbits,sizeof(tmp.ipbits),ptr); + ipbits = (uint32_t)tmp.ipbits; + HASH_FIND(hh,coin->iAddrs,&ipbits,sizeof(ipbits),ptr); if ( ptr == 0 ) { ptr = mycalloc('t',1,sizeof(*ptr)); if ( ptr == 0 ) - printf("fatal alloc error in hashset\n"), exit(-1); + printf("fatal alloc errorB in hashset\n"), exit(-1); ptr->hh.itemind = m; ptr->ipbits = tmp.ipbits; - HASH_ADD(hh,coin->iAddrs,ipbits,sizeof(tmp.ipbits),ptr); - if ( i != m ) - { - tmp.hh.itemind = m; - fseek(fp,m*sizeof(tmp),SEEK_SET); - fwrite(&tmp,1,sizeof(tmp),fp); - } - //printf("m.%d %x\n",m,tmp.ipbits); + HASH_ADD(hh,coin->iAddrs,ipbits,sizeof(ipbits),ptr); + tmp.hh.itemind = m; + tmp.status = 0; + fseek(fp,m*sizeof(tmp),SEEK_SET); + fwrite(&tmp,1,sizeof(tmp),fp); + expand_ipbits(hexstr,ipbits); + //printf("create rwiAddrind m.%-4d %08x %s status.%d\n",m,(uint32_t)tmp.ipbits,hexstr,tmp.status); m++; coin->numiAddrs = m; - expand_ipbits(hexstr,tmp.ipbits); iguana_possible_peer(coin,hexstr); } + else + { + expand_ipbits(hexstr,ipbits); + //printf("peer.%d status.%d ipbits.%x\n",i,tmp.status,(uint32_t)ipbits); + tmp.status = 0; + fseek(fp,i * sizeof(tmp),SEEK_SET); + if ( fwrite(&tmp,1,sizeof(tmp),fp) != sizeof(tmp) ) + printf("error writing peer.%d\n",i); + } portable_mutex_unlock(&coin->peers_mutex); } } @@ -164,22 +189,38 @@ uint32_t iguana_rwiAddrind(struct iguana_info *coin,int32_t rwflag,struct iguana printf("iAddr: error loading.[%d]\n",ind); else { + iA->status = 0; if ( (iA= iguana_iAddrhashset(coin,iA,ind)) != 0 ) { retval = iA->hh.itemind+1; - //printf("r %p ipbits.%x ind.%d saved iA->ind.%d retval.%d\n",iA,iA->ipbits,ind,iA->hh.itemind,retval); + //printf("r %p status.%d ipbits.%x ind.%d saved iA->ind.%d retval.%d\n",iA,iA->status,(uint32_t)iA->ipbits,ind,iA->hh.itemind,retval); } } - } else printf("iAddr: error seeking.[%d] %ld vs %ld\n",ind,ftell(fp),ind * sizeof(*iA)); + } else printf("iAddr: error seeking.[%d] %ld vs %d\n",ind,ftell(fp),(int32_t)(ind * sizeof(*iA))); fclose(fp); } } else { if ( (fp= fopen(fname,"rb+")) == 0 ) - fp = fopen(fname,"wb"); + { + if ( (fp= fopen(fname,"wb")) == 0 ) + { + printf("iguana_rwAddrind: couldnt create.(%s)\n",fname); + return(-1); + } + } if ( fp != 0 ) { + ipbits = (uint32_t)iA->ipbits; + HASH_FIND(hh,coin->iAddrs,&ipbits,sizeof(ipbits),ptr); + if ( ptr != 0 && ptr->hh.itemind != ind ) + { + printf("mismatch iAddr ind.%d != %d\n",ptr->hh.itemind,ind); + ind = ptr->hh.itemind; + } + if ( ind <= 0 ) + ind = coin->numiAddrs++; fseek(fp,ind * sizeof(*iA),SEEK_SET); if ( ftell(fp) == ind * sizeof(*iA) ) { @@ -191,12 +232,18 @@ uint32_t iguana_rwiAddrind(struct iguana_info *coin,int32_t rwflag,struct iguana if ( (iA= iguana_iAddrhashset(coin,iA,ind)) != 0 ) { retval = iA->hh.itemind+1; - //printf("W %p ipbits.%x ind.%d saved iA->ind.%d retval.%d\n",iA,iA->ipbits,ind,iA->hh. itemind,retval); + expand_ipbits(ipaddr,iA->ipbits); + //printf("%s status.%d lastkilled.%u ipbits.%x ind.%d saved iA->ind.%d retval.%d numiAddrs.%d\n",ipaddr,iA->status,iA->lastkilled,(uint32_t)ipbits,ind,iA->hh.itemind,retval,coin->numiAddrs); } } - } else printf("iAddr: error seeking.[%d] %ld vs %ld\n",ind,ftell(fp),ind * sizeof(*iA)); + } else printf("iAddr: error seeking.[%d] %ld vs %d\n",ind,ftell(fp),(int32_t)(ind * sizeof(*iA))); fclose(fp); - } else printf("error creating.(%s)\n",fname); + } + else + { + printf("iguana_rwAddrind: couldnt create.(%s)\n",fname); + return(-1); + } } return(retval); } @@ -247,8 +294,8 @@ void iguana_iAkill(struct iguana_info *coin,struct iguana_peer *addr,int32_t mar } else printf("killconnection cant get ind for ipaddr.%s\n",addr->ipaddr); memset(addr,0,sizeof(*addr)); addr->usock = -1; - if ( rank > 0 ) - iguana_possible_peer(coin,ipaddr); + //if ( rank > 0 ) + // iguana_possible_peer(coin,ipaddr); } int32_t iguana_socket(int32_t bindflag,char *hostname,uint16_t port) @@ -302,7 +349,9 @@ int32_t iguana_socket(int32_t bindflag,char *hostname,uint16_t port) if ( result != 0 ) { if ( errno != ECONNRESET && errno != ENOTCONN && errno != ECONNREFUSED && errno != ETIMEDOUT && errno != EHOSTUNREACH ) - printf("%s(%s) port.%d failed: %s sock.%d. errno.%d\n",bindflag!=0?"bind":"connect",hostname,port,strerror(errno),sock,errno); + { + //printf("%s(%s) port.%d failed: %s sock.%d. errno.%d\n",bindflag!=0?"bind":"connect",hostname,port,strerror(errno),sock,errno); + } if ( sock >= 0 ) closesocket(sock); return(-1); @@ -315,7 +364,7 @@ int32_t iguana_socket(int32_t bindflag,char *hostname,uint16_t port) if ( errno == EADDRINUSE ) { sleep(1); - printf("ERROR BINDING PORT.%d. will exit. wait up to a minute and try again. dont worry, this is normal\n",port); + printf("ERROR BINDING PORT.%d. this is normal tcp timeout, unless another process is using port\n",port); sleep(3); printf("%s(%s) port.%d try again: %s sock.%d. errno.%d\n",bindflag!=0?"bind":"connect",hostname,port,strerror(errno),sock,errno); if ( bindflag == 1 ) @@ -324,7 +373,7 @@ int32_t iguana_socket(int32_t bindflag,char *hostname,uint16_t port) return(-1); } sleep(13); - continue; + //continue; } if ( errno != ECONNRESET && errno != ENOTCONN && errno != ECONNREFUSED && errno != ETIMEDOUT && errno != EHOSTUNREACH ) { @@ -371,7 +420,7 @@ int32_t iguana_send(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *s } else if ( addr->msgcounts.verack == 0 && (strcmp((char *)&serialized[4],"version") != 0 && strcmp((char *)&serialized[4],"ConnectTo") != 0 && strcmp((char *)&serialized[4],"verack") != 0) != 0 ) { - printf("skip.(%s) since no verack yet\n",(char *)&serialized[4]); + //printf("skip.(%s) since no verack yet\n",(char *)&serialized[4]); return(-1); } if ( strcmp((char *)&serialized[4],"ping") == 0 ) @@ -415,7 +464,8 @@ int32_t iguana_queue_send(struct iguana_info *coin,struct iguana_peer *addr,int3 exit(-1); return(-1); } - datalen = iguana_sethdr((void *)serialized,coin->chain->netmagic,cmd,&serialized[sizeof(struct iguana_msghdr)],len); + if ( (datalen= iguana_sethdr((void *)serialized,coin->chain->netmagic,cmd,&serialized[sizeof(struct iguana_msghdr)],len)) < 0 ) + return(-1); if ( strcmp("getaddr",cmd) == 0 && time(NULL) < addr->lastgotaddr+300 ) return(0); //if ( strcmp("version",cmd) == 0 ) @@ -468,15 +518,14 @@ void iguana_parsebuf(struct iguana_info *coin,struct iguana_peer *addr,struct ig { struct iguana_msghdr checkH; memset(&checkH,0,sizeof(checkH)); - iguana_sethdr(&checkH,coin->chain->netmagic,H->command,buf,len); - if ( memcmp(&checkH,H,sizeof(checkH)) == 0 ) + if ( iguana_sethdr(&checkH,coin->chain->netmagic,H->command,buf,len) > 0 && memcmp(&checkH,H,sizeof(checkH)) == 0 ) { if ( strcmp(H->command,"block") == 0 || strcmp(H->command,"tx") == 0 ) { if ( addr->RAWMEM.ptr == 0 ) - iguana_meminit(&addr->RAWMEM,addr->ipaddr,0,IGUANA_MAXPACKETSIZE,0); + iguana_meminit(&addr->RAWMEM,addr->ipaddr,0,IGUANA_MAXPACKETSIZE * 2,0); if ( addr->TXDATA.ptr == 0 ) - iguana_meminit(&addr->TXDATA,"txdata",0,IGUANA_MAXPACKETSIZE,0); + iguana_meminit(&addr->TXDATA,"txdata",0,IGUANA_MAXPACKETSIZE * 2,0); if ( addr->HASHMEM.ptr == 0 ) iguana_meminit(&addr->HASHMEM,"HASHPTRS",0,256,0);//IGUANA_MAXPACKETSIZE*16,0); //printf("Init %s memory %p %p %p\n",addr->ipaddr,addr->RAWMEM.ptr,addr->TXDATA.ptr,addr->HASHMEM.ptr); @@ -542,7 +591,7 @@ void _iguana_processmsg(struct iguana_info *coin,int32_t usock,struct iguana_pee printf("invalid header received from (%s)\n",addr->ipaddr); addr->dead = 1; } - printf("%s recv error on hdr errno.%d (%s) -> zombify\n",addr->ipaddr,-recvlen,strerror(-recvlen)); + // printf("%s recv error on hdr errno.%d (%s) -> zombify\n",addr->ipaddr,-recvlen,strerror(-recvlen)); #ifndef IGUANA_DEDICATED_THREADS addr->dead = 1; #endif @@ -558,8 +607,8 @@ void iguana_gotdata(struct iguana_info *coin,struct iguana_peer *addr,int32_t he //iguana_set_iAddrheight(coin,addr->ipbits,height); addr->height = height; } - if ( height > coin->longestchain ) - coin->longestchain = height; + if ( height > 0 && height > coin->longestchain ) + coin->longestchain = (height + coin->longestchain + 1) >> 1; } int32_t iguana_iAddrheight(struct iguana_info *coin,uint64_t ipbits) @@ -589,7 +638,8 @@ void iguana_startconnection(void *arg) printf("iguana_startconnection.%s mismatched coin.%p (%s) vs (%s)\n",addr->ipaddr,coin,coin->symbol,addr->coinstr); return; } - if ( strcmp("127.0.0.1",addr->ipaddr) == 0 && (coin->myservices & NODE_NETWORK) != 0 ) + //printf("MYSERVICES.%llx\n",(long long)coin->myservices); + if ( strcmp("127.0.0.1",addr->ipaddr) == 0 )//&& (coin->myservices & NODE_NETWORK) != 0 ) { iguana_iAkill(coin,addr,0); printf("avoid self-loopback\n"); @@ -604,7 +654,7 @@ void iguana_startconnection(void *arg) if ( addr->usock < 0 || coin->peers.shuttingdown != 0 ) { strcpy(ipaddr,addr->ipaddr); - printf("refused PEER KILLED. for %s:%d usock.%d\n",ipaddr,coin->chain->portp2p,addr->usock); + //printf("refused PEER KILLED. slot.%d for %s:%d usock.%d\n",addr->addrind,ipaddr,coin->chain->portp2p,addr->usock); iguana_iAkill(coin,addr,1); } else @@ -622,7 +672,7 @@ void iguana_startconnection(void *arg) n++; iguana_iAconnected(coin,addr); coin->peers.numconnected++; - printf("PEER CONNECTED.%d:%d of max.%d! %s:%d usock.%d\n",coin->peers.numconnected,n,coin->MAXPEERS,addr->ipaddr,coin->chain->portp2p,addr->usock); + printf("%s.PEER CONNECTED.%d:%d of max.%d! %s:%d usock.%d\n",coin->symbol,coin->peers.numconnected,n,coin->MAXPEERS,addr->ipaddr,coin->chain->portp2p,addr->usock); if ( strcmp("127.0.0.1",addr->ipaddr) == 0 ) coin->peers.localaddr = addr; else if ( coin->peers.numranked == 0 ) @@ -681,6 +731,13 @@ struct iguana_peer *iguana_peerslot(struct iguana_info *coin,uint64_t ipbits,int return(0); } +void iguana_launchpeer(struct iguana_info *coin,char *ipaddr) +{ + struct iguana_peer *addr; uint32_t ipbits = (uint32_t)calc_ipbits(ipaddr); + if ( (addr= iguana_peerslot(coin,ipbits,0)) != 0 ) + iguana_launch(coin,"connection",iguana_startconnection,addr,IGUANA_CONNTHREAD); +} + void *iguana_iAddriterator(struct iguana_info *coin,struct iguana_iAddr *iA) { struct iguana_peer *addr = 0; @@ -688,18 +745,24 @@ void *iguana_iAddriterator(struct iguana_info *coin,struct iguana_iAddr *iA) { //printf("%x\n",iA->ipbits); //portable_mutex_unlock(&coin->peers_mutex); - if ( (addr= iguana_peerslot(coin,iA->ipbits,0)) != 0 )//i < coin->MAXPEERS && i < IGUANA_MAXPEERS && addr != 0 ) + if ( (addr= iguana_peerslot(coin,iA->ipbits,0)) != 0 ) { - //printf("pend.%d status.%d possible peer.(%s).%x threads %d %d %d %d\n",addr->pending,iA->status,addr->ipaddr,addr->ipbits,iguana_numthreads(coin,0),iguana_numthreads(coin,1),iguana_numthreads(coin,2),iguana_numthreads(coin,3)); - if ( addr->pending == 0 && iA->status != IGUANA_PEER_CONNECTING ) + //printf("pend.%d status.%d possible peer.(%s).%x threads %d %d %d %d\n",addr->pending,iA->status,addr->ipaddr,(uint32_t)addr->ipbits,iguana_numthreads(coin,0),iguana_numthreads(coin,1),iguana_numthreads(coin,2),iguana_numthreads(coin,3)); + if ( addr->pending == 0 && iA->status != IGUANA_PEER_CONNECTING && (iA->status != IGUANA_PEER_KILLED || time(NULL) > iA->lastkilled+600) ) { - iA->status = IGUANA_PEER_CONNECTING; - addr->pending = (uint32_t)time(NULL); + //printf("call rwIaddrInd\n"); if ( iguana_rwiAddrind(coin,1,iA,iA->hh.itemind) > 0 ) { //printf("iA.%p iguana_startconnection.(%s) status.%d pending.%d\n",iA,addr->ipaddr,iA->status,addr->pending); + iA->status = IGUANA_PEER_CONNECTING; + addr->pending = (uint32_t)time(NULL); iguana_launch(coin,"connection",iguana_startconnection,addr,IGUANA_CONNTHREAD); - } else printf("error rwiAddrind.%d\n",iA->hh.itemind); + } + else + { + addr->ipbits = 0; + printf("error rwiAddrind.%d\n",iA->hh.itemind); + } } } else printf("no open peer slots left\n"); } @@ -712,9 +775,14 @@ void *iguana_iAddriterator(struct iguana_info *coin,struct iguana_iAddr *iA) uint32_t iguana_possible_peer(struct iguana_info *coin,char *ipaddr) { char checkaddr[64]; uint64_t ipbits; uint32_t now = (uint32_t)time(NULL); int32_t i,n; struct iguana_iAddr *iA; - if ( ipaddr != 0 ) + if ( ipaddr != 0 && ipaddr[0] != 0 ) { - //printf("%p Q possible peer.%s\n",coin,ipaddr); + for (i=n=0; iMAXPEERS; i++) + if ( strcmp(ipaddr,coin->peers.active[i].ipaddr) == 0 ) + { + printf("%s possible peer.(%s) %x already there\n",coin->symbol,ipaddr,(uint32_t)coin->peers.active[i].ipbits); + return(0); + } queue_enqueue("possibleQ",&coin->possibleQ,queueitem(ipaddr),1); return((uint32_t)time(NULL)); } @@ -734,14 +802,14 @@ uint32_t iguana_possible_peer(struct iguana_info *coin,char *ipaddr) { if ( strcmp(ipaddr,coin->peers.active[i].ipaddr) == 0 ) { - printf("(%s) already active\n",ipaddr); + //printf("(%s) already active\n",ipaddr); free_queueitem(ipaddr); return((uint32_t)time(NULL)); } else if ( coin->peers.active[i].ipaddr[0] != 0 ) n++; } - if ( n >= coin->MAXPEERS-(coin->MAXPEERS>>3)-1 ) + if ( n >= coin->MAXPEERS-(coin->MAXPEERS>>3)-1 || coin->peers.numranked >= coin->MAXPEERS ) return((uint32_t)time(NULL)); if ( strncmp("0.0.0",ipaddr,5) != 0 && strcmp("0.0.255.255",ipaddr) != 0 && strcmp("1.0.0.0",ipaddr) != 0 ) { @@ -762,9 +830,9 @@ uint32_t iguana_possible_peer(struct iguana_info *coin,char *ipaddr) printf("error updating status for (%s) ind.%d\n",ipaddr,iA->hh.itemind); iguana_iAddriterator(coin,iA); } else printf("ignore.(%s) lastconnect.%u lastkilled.%u numconnects.%d\n",ipaddr,iA->lastconnect,iA->lastkilled,iA->numconnects); - } else printf("skip.(%s) ind.%d status.%d\n",ipaddr,iA->hh.itemind,iA->status); + } //else printf("skip.(%s) ind.%d status.%d\n",ipaddr,iA->hh.itemind,iA->status); } else printf("cant find (%s) which should have been created\n",ipaddr); - } else printf("reject ipaddr.(%s)\n",ipaddr); + } else printf("reject ipaddr.(%s) vs checkaddr.(%s)\n",ipaddr,checkaddr); } } free_queueitem(ipaddr); @@ -933,11 +1001,57 @@ int64_t iguana_peerallocated(struct iguana_info *coin,struct iguana_peer *addr) } #endif +int32_t iguana_voutsfname(struct iguana_info *coin,int32_t roflag,char *fname,int32_t slotid) +{ + sprintf(fname,"%s/%s%s/vouts/%04d.vouts",GLOBAL_DBDIR,roflag!=0?"ro/":"",coin->symbol,slotid); + return((int32_t)strlen(fname)); +} + +int32_t iguana_vinsfname(struct iguana_info *coin,int32_t roflag,char *fname,int32_t slotid) +{ + if ( roflag != 0 ) + sprintf(fname,"%s/ro/%s/purgeable/%04d.vins",coin->VALIDATEDIR,coin->symbol,slotid); + else sprintf(fname,"%s/%s/%04d.vins",coin->VALIDATEDIR,coin->symbol,slotid); + return((int32_t)strlen(fname)); +} + +int32_t iguana_peerslotinit(struct iguana_info *coin,struct iguana_peer *addr,int32_t slotid,uint64_t ipbits) +{ + char fname[1024]; + addr->ipbits = ipbits; + addr->addrind = slotid; + iguana_voutsfname(coin,0,fname,addr->addrind); + if ( (addr->voutsfp= fopen(fname,"rb+")) != 0 ) + fseek(addr->voutsfp,0,SEEK_END); + else if ( (addr->voutsfp= fopen(fname,"wb+")) == 0 ) + { + printf("cant create.(%s)\n",fname); + return(-1); + } + if ( coin->VALIDATENODE != 0 || coin->RELAYNODE != 0 ) + { + iguana_vinsfname(coin,0,fname,addr->addrind); + if ( (addr->vinsfp= fopen(fname,"rb+")) != 0 ) + fseek(addr->vinsfp,0,SEEK_END); + else if ( (addr->vinsfp= fopen(fname,"wb+")) == 0 ) + { + printf("cant create.(%s)\n",fname); + return(-1); + } + } + return(0); +} + void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) { static uint32_t lastping; - struct pollfd fds; struct iguana_bundlereq *req; uint8_t *buf;//,serialized[64]; - uint32_t ipbits; int32_t bufsize,flag,run,timeout = coin->polltimeout == 0 ? 10 : coin->polltimeout; + struct pollfd fds; struct iguana_bundlereq *req; uint8_t *buf; uint32_t ipbits; + int32_t bufsize,flag,run,timeout = coin->polltimeout == 0 ? 10 : coin->polltimeout; + if ( iguana_peerslotinit(coin,addr,(int32_t)(((long)addr - (long)&coin->peers.active[0]) / sizeof(*addr)),calc_ipbits(addr->ipaddr)) < 0 ) + { + printf("error creating peer's files\n"); + return; + } #ifdef IGUANA_PEERALLOC int32_t i; int64_t remaining; struct OS_memspace *mem[sizeof(addr->SEROUT)/sizeof(*addr->SEROUT)]; for (i=0; iSEROUT)/sizeof(*addr->SEROUT); i++) @@ -952,13 +1066,14 @@ void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) iguana_memreset(mem[i]); } #endif - addr->addrind = (int32_t)(((long)addr - (long)&coin->peers.active[0]) / sizeof(*addr)); + //addr->pubkey = GENESIS_PUBKEY; ipbits = (uint32_t)addr->ipbits; - //addr->pubkey = GENESIS_PUBKEY; vcalc_sha256(0,addr->iphash.bytes,(uint8_t *)&ipbits,sizeof(ipbits)); - char str[65]; printf("start dedicatedloop.%s addrind.%d %s\n",addr->ipaddr,addr->addrind,bits256_str(str,addr->iphash)); + //char str[65]; printf("start dedicatedloop.%s addrind.%d %s\n",addr->ipaddr,addr->addrind,bits256_str(str,addr->iphash)); addr->maxfilehash2 = IGUANA_MAXFILEITEMS; bufsize = IGUANA_MAXPACKETSIZE; + if ( addr->blockspace == 0 ) + addr->blockspace = mycalloc('r',1,bufsize + 8192); buf = mycalloc('r',1,bufsize); if ( strcmp(coin->symbol,"VPN") == 0 ) { @@ -975,11 +1090,11 @@ void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) run = 0; while ( addr->usock >= 0 && addr->dead == 0 && coin->peers.shuttingdown == 0 ) { - if ( 1 && (req= queue_dequeue(&coin->cacheQ,0)) != 0 ) + if ( 0 && (req= queue_dequeue(&coin->cacheQ,0)) != 0 ) { if ( req->datalen != 0 ) { - //char str[65]; printf("CACHE parse[%d] %s %s\n",req->recvlen,req->H.command,bits256_str(str,req->block.RO.hash2)); + //char str[65]; printf("CACHE.%p parse[%d] %s %s\n",req,req->recvlen,req->H.command,bits256_str(str,req->block.RO.hash2)); iguana_parsebuf(coin,addr,&req->H,req->serialized,req->recvlen); } else printf("CACHE error no datalen\n"); coin->cachefreed++; @@ -1034,8 +1149,8 @@ void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) usleep(100000); } else if ( addr->rank != 1 ) - usleep(coin->polltimeout*100 + 1*(rand() % (coin->polltimeout*100))); - else usleep(100); + usleep(coin->polltimeout*5000 + 1*(rand() % (coin->polltimeout*3000))); + else usleep(10000 + coin->backlog); } else run >>= 2; } if ( flag != 0 ) @@ -1063,15 +1178,17 @@ void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) } } } - else if ( coin->isRT != 0 && addr->rank > coin->MAXPEERS && (rand() % 100) == 0 ) + else if ( coin->isRT != 0 && addr->rank > coin->MAXPEERS && (rand() % 10) == 0 ) { - printf("isRT and low rank.%d ",addr->rank); + //printf("isRT and low rank.%d ",addr->rank); addr->dead = 1; } } - printf(">>>>>>>>>>>>>> finish dedicatedloop.%s\n",addr->ipaddr); - //if ( addr->fp != 0 ) - // fclose(addr->fp); + //printf(">>>>>>>>>>>>>> finish %s dedicatedloop.%s\n",coin->symbol,addr->ipaddr); + if ( addr->vinsfp != 0 ) + fclose(addr->vinsfp); + if ( addr->voutsfp != 0 ) + fclose(addr->voutsfp); iguana_iAkill(coin,addr,addr->dead != 0); myfree(buf,bufsize); if ( addr->filehash2 != 0 ) diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index bf218c981..d0eb9b27f 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -21,6 +21,7 @@ //#define HASH_INITIAL_NUM_BUCKETS_LOG2 5 #include "iguana777.h" +#include "exchanges/bitcoin.h" //void iguana_stub(void *ptr,int size) { }//printf("uthash_free ptr.%p %d\n",ptr,size); } #define iguana_hashfind(ramchain,selector,key) iguana_hashsetPT(ramchain,selector,key,0) @@ -45,143 +46,37 @@ struct iguana_kvitem *iguana_hashsetPT(struct iguana_ramchain *ramchain,int32_t { if ( ramchain->hashmem != 0 ) ptr = iguana_memalloc(ramchain->hashmem,allocsize,1); - else ptr = mycalloc('e',1,allocsize); + else + { + ptr = mycalloc('e',1,allocsize); + printf("alloc.%d\n",allocsize); + } if ( ptr == 0 ) - printf("fatal alloc error in hashset\n"), exit(-1); + printf("fatal alloc errorC in hashset\n"), exit(-1); if ( 0 && ramchain->expanded && selector == 'T' ) printf("hashmem.%p selector.%c added.(%s) itemind.%x ptr.%p\n",ramchain->hashmem,selector,str,itemind,ptr); - ptr->hh.itemind = itemind; if ( selector == 'T' ) HASH_ADD_KEYPTR(hh,ramchain->txids,key,keylen,ptr); else HASH_ADD_KEYPTR(hh,ramchain->pkhashes,key,keylen,ptr); - if ( selector == 'T' ) - HASH_FIND(hh,ramchain->txids,key,keylen,tmp); - else HASH_FIND(hh,ramchain->pkhashes,key,keylen,tmp); + ptr->hh.itemind = itemind; //if ( strcmp(str,"0000000000000000000000000000000000000000000000000000000000000000") == 0 ) // printf("added null txid?\n"), getchar(); if ( 0 && ramchain->expanded && selector == 'T' ) printf("selector.%c added.(%s) itemind.%x ptr.%p tmp.%p\n",selector,str,itemind,ptr,tmp); if ( itemind == 0 ) printf("negative itemind\n"), exit(-1); - if ( tmp != ptr ) - { - printf("(%s) hashmem.%p selector.%c %s search error %p != %p itemind.%x\n",str,ramchain->hashmem,selector,str,ptr,tmp,itemind), exit(-1); - } - } - return(ptr); -} - -uint32_t iguana_sparseadd(uint8_t *bits,uint32_t ind,int32_t width,uint32_t tablesize,uint8_t *key,int32_t keylen,uint32_t setind,void *refdata,int32_t refsize) -{ - static long sparsesearches,sparseiters,sparsehits,sparsemax; - static uint8_t masks[8] = { 1, 2, 4, 8, 16, 32, 64, 128 }; - int32_t i,j,x,n,modval; int64_t bitoffset; uint8_t *ptr; - if ( tablesize == 0 ) - { - printf("iguana_sparseadd tablesize zero illegal\n"); - return(0); - } - if ( 0 && setind == 0 ) - { - char str[65]; - for (i=n=0; i> 3]; - modval = (bitoffset & 7); - for (x=j=0; j= 8 ) - ptr++, modval = 0; - x <<= 1; - x |= (*ptr & masks[modval]) >> modval; - } - if ( x != 0 ) - printf("%s ",bits256_str(str,*(bits256 *)(refdata + x*refsize))), n++; - } - printf("tableentries.%d\n",n); - } - bitoffset = (ind * width); - sparsesearches++; - if ( 0 && setind == 0 ) - printf("tablesize.%d width.%d bitoffset.%d\n",tablesize,width,(int32_t)bitoffset); - for (i=0; i= tablesize ) - { - ind = 0; - bitoffset = 0; - } - ptr = &bits[bitoffset >> 3]; - modval = (bitoffset & 7); - if ( 0 && setind == 0 ) - printf("tablesize.%d width.%d bitoffset.%d modval.%d i.%d\n",tablesize,width,(int32_t)bitoffset,modval,i); - for (x=j=0; j= 8 ) - ptr++, modval = 0; - x <<= 1; - x |= (*ptr & masks[modval]) >> modval; - } - if ( 0 && setind == 0 ) - printf("x.%d\n",x); - if ( x == 0 ) + if ( 0 ) { - if ( (x= setind) == 0 ) - return(0); - ptr = &bits[(bitoffset+width-1) >> 3]; - modval = ((bitoffset+width-1) & 7); - for (j=0; j>=1,modval--) + if ( selector == 'T' ) + HASH_FIND(hh,ramchain->txids,key,keylen,tmp); + else HASH_FIND(hh,ramchain->pkhashes,key,keylen,tmp); + if ( tmp != ptr ) { - if ( modval < 0 ) - ptr--, modval = 7; - if ( (x & 1) != 0 ) - *ptr |= masks[modval]; + printf("(%s) hashmem.%p selector.%c %s search error %p != %p itemind.%x\n",str,ramchain->hashmem,selector,str,ptr,tmp,itemind), exit(-1); } - if ( 0 ) - { - for (x=j=0; j sparsemax ) - sparsemax = i; - return(setind); - } - else if ( memcmp((void *)(long)((long)refdata + x*refsize),key,keylen) == 0 ) - { - if ( setind == 0 ) - sparsehits++; - else if ( setind != x ) - printf("sparseadd index collision setind.%d != x.%d\n",setind,x); - return(x); } } - return(0); -} - -uint32_t iguana_sparseaddtx(uint8_t *bits,int32_t width,uint32_t tablesize,bits256 txid,struct iguana_txid *T,uint32_t txidind) -{ - uint32_t ind; - ind = (txid.ulongs[0] ^ txid.ulongs[1] ^ txid.ulongs[2] ^ txid.ulongs[3]) % tablesize; - return(iguana_sparseadd(bits,ind,width,tablesize,txid.bytes,sizeof(txid),txidind,T,sizeof(*T))); -} - -uint32_t iguana_sparseaddpk(uint8_t *bits,int32_t width,uint32_t tablesize,uint8_t rmd160[20],struct iguana_pkhash *P,uint32_t pkind) -{ - uint32_t ind,key2; uint64_t key0,key1; - memcpy(&key0,rmd160,sizeof(key0)); - memcpy(&key1,&rmd160[sizeof(key0)],sizeof(key1)); - memcpy(&key2,&rmd160[sizeof(key0) + sizeof(key1)],sizeof(key2)); - ind = (key0 ^ key1 ^ key2) % tablesize; - return(iguana_sparseadd(bits,ind,width,tablesize,rmd160,20,pkind,P,sizeof(*P))); + return(ptr); } void iguana_blocksetcounters(struct iguana_info *coin,struct iguana_block *block,struct iguana_ramchain * ramchain) @@ -193,74 +88,47 @@ void iguana_blocksetcounters(struct iguana_info *coin,struct iguana_block *block block->RO.firstexternalind = ramchain->externalind; } -struct iguana_txid *iguana_txidfind(struct iguana_info *coin,int32_t *heightp,struct iguana_txid *tx,bits256 txid) -{ - uint8_t *TXbits; struct iguana_txid *T; uint32_t txidind,i,j; - struct iguana_bundle *bp; struct iguana_ramchain *ramchain; struct iguana_block *block; - *heightp = -1; - for (i=0; ibundlescount; i++) - { - if ( (bp= coin->bundles[i]) != 0 && bp->emitfinish > coin->startutc ) - { - ramchain = &bp->ramchain; - if ( ramchain->H.data != 0 ) - { - TXbits = (void *)(long)((long)ramchain->H.data + ramchain->H.data->TXoffset); - T = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Toffset); - //printf("search bp.%p TXbits.%p T.%p %d %d\n",bp,TXbits,T,(int32_t)ramchain->H.data->TXoffset,(int32_t)ramchain->H.data->Toffset); - if ( (txidind= iguana_sparseaddtx(TXbits,ramchain->H.data->txsparsebits,ramchain->H.data->numtxsparse,txid,T,0)) > 0 ) - { - //printf("found txidind.%d\n",txidind); - for (j=0; jn; j++) - if ( (block= bp->blocks[j]) != 0 && txidind >= block->RO.firsttxidind && txidind < block->RO.firsttxidind+block->RO.txn_count ) - break; - *heightp = bp->bundleheight + j; - //printf("found height.%d\n",*heightp); - *tx = T[txidind]; - return(tx); - } - } - } - } - return(0); -} - -struct iguana_pkhash *iguana_pkhashfind(struct iguana_info *coin,struct iguana_pkhash *p,uint8_t rmd160[20]) +int32_t iguana_peerfname(struct iguana_info *coin,int32_t *hdrsip,char *dirname,char *fname,uint32_t ipbits,bits256 hash2,bits256 prevhash2,int32_t numblocks,int32_t dispflag) { - uint8_t *PKbits; struct iguana_pkhash *P; uint32_t pkind,i; struct iguana_bundle *bp; struct iguana_ramchain *ramchain; - for (i=0; ibundlescount; i++) - { - if ( (bp= coin->bundles[i]) != 0 ) - { - ramchain = &bp->ramchain; - PKbits = (void *)(long)((long)ramchain->H.data + ramchain->H.data->PKoffset); - P = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Poffset); - if ( (pkind= iguana_sparseaddpk(PKbits,ramchain->H.data->pksparsebits,ramchain->H.data->numpksparse,rmd160,P,0)) > 0 ) - { - *p = P[pkind]; - return(p); - } - } - } - return(0); -} - -int32_t iguana_peerfname(struct iguana_info *coin,int32_t *hdrsip,char *dirname,char *fname,uint32_t ipbits,bits256 hash2,bits256 prevhash2,int32_t numblocks) -{ - struct iguana_bundle *bp = 0; int32_t bundlei = -2; char str[65]; - *hdrsip = -1; + struct iguana_bundle *bp; int32_t bundlei,subdir; char str[65]; + *hdrsip = -1; ipbits = 0; + fname[0] = 0; //if ( ipbits == 0 ) // printf("illegal ipbits.%d\n",ipbits), getchar(); + bp = 0, bundlei = -2; if ( (bp= iguana_bundlefind(coin,&bp,&bundlei,hash2)) == 0 ) { + bp = 0, bundlei = -2; if ( bits256_nonz(prevhash2) == 0 || (bp= iguana_bundlefind(coin,&bp,&bundlei,prevhash2)) == 0 || bundlei >= coin->chain->bundlesize-1 ) + { + if ( 0 && dispflag != 0 ) + printf("iguana_peerfname error finding.(%s) spec.%p bp.%p\n",bits256_str(str,hash2),bp!=0?bp->speculative:0,bp); return(-2); + } else bundlei++; } hash2 = bp->hashes[0], *hdrsip = bp->hdrsi; + subdir = bp->bundleheight / IGUANA_SUBDIRDIVISOR; if ( numblocks == 1 ) - sprintf(fname,"%s/%s/%s.%u",dirname,coin->symbol,bits256_str(str,hash2),ipbits!=0?ipbits:*hdrsip); - else sprintf(fname,"%s/%s/%s_%d.%u",dirname,coin->symbol,bits256_str(str,hash2),numblocks,ipbits!=0?ipbits:*hdrsip); + { + sprintf(fname,"%s/%s/%d",dirname,coin->symbol,subdir), OS_ensure_directory(fname); + sprintf(fname,"%s/%s/%d/%d",dirname,coin->symbol,subdir,bp->bundleheight), OS_ensure_directory(fname); + if ( bits256_nonz(bp->hashes[bundlei]) != 0 ) + sprintf(fname,"%s/%s/%d/%d/%s_%u.%d",dirname,coin->symbol,subdir,bp->bundleheight,bits256_str(str,bp->hashes[bundlei]),ipbits>1?ipbits:*hdrsip,bundlei); + else + { + printf("no hash for [%d:%d]\n",bp->hdrsi,bundlei); + return(-3); + } + } + else //if ( strncmp(GLOBAL_DBDIR,dirname,strlen(GLOBAL_DBDIR)) == 0 ) + { + sprintf(fname,"%s/%s/%d",dirname,coin->symbol,subdir), OS_ensure_directory(fname); + sprintf(fname,"%s/%s/%d/%s_%d.%u",dirname,coin->symbol,subdir,bits256_str(str,hash2),numblocks,ipbits>1?ipbits:*hdrsip); +//#ifndef __PNACL__ +// sprintf(fname,"%s/%s/%s_%d.%u",dirname,coin->symbol,bits256_str(str,hash2),numblocks,ipbits>1?ipbits:*hdrsip); +//#endif + } //else sprintf(fname,"%s/%s.%u",dirname,bits256_str(str,hash2),bp->bundleheight); OS_compatible_path(fname); return(bundlei); } @@ -268,7 +136,7 @@ int32_t iguana_peerfname(struct iguana_info *coin,int32_t *hdrsip,char *dirname, int32_t iguana_peerfile_exists(struct iguana_info *coin,struct iguana_peer *addr,char *dirname,char *fname,bits256 hash2,bits256 prevhash2,int32_t numblocks) { FILE *fp; int32_t bundlei,hdrsi; - if ( (bundlei= iguana_peerfname(coin,&hdrsi,dirname,fname,addr!=0?(uint32_t)addr->ipbits:0,hash2,prevhash2,numblocks)) >= 0 ) + if ( (bundlei= iguana_peerfname(coin,&hdrsi,dirname,fname,addr!=0?(uint32_t)addr->ipbits:0,hash2,prevhash2,numblocks,1)) >= 0 ) { OS_compatible_path(fname); if ( (fp= fopen(fname,"rb")) == 0 ) @@ -278,42 +146,53 @@ int32_t iguana_peerfile_exists(struct iguana_info *coin,struct iguana_peer *addr return(bundlei); } -#define RAMCHAIN_FUNC struct iguana_ramchain *ramchain,struct iguana_blockRO *B,struct iguana_txid *T,struct iguana_unspent20 *U,struct iguana_spend256 *S,struct iguana_pkhash *P,struct iguana_account *A,bits256 *X,struct iguana_unspent *Ux,struct iguana_spend *Sx,uint8_t *TXbits,uint8_t *PKbits -#define RAMCHAIN_PTRPS struct iguana_ramchain *ramchain,struct iguana_blockRO **B,struct iguana_txid **T,struct iguana_unspent20 **U,struct iguana_spend256 **S,struct iguana_pkhash **P,struct iguana_account **A,bits256 **X,struct iguana_unspent **Ux,struct iguana_spend **Sx,uint8_t **TXbits,uint8_t **PKbits +#define RAMCHAIN_FUNC struct iguana_ramchain *ramchain,struct iguana_blockRO *B,struct iguana_txid *T,struct iguana_unspent20 *U,struct iguana_spend256 *S,struct iguana_pkhash *P,struct iguana_account *A,bits256 *X,struct iguana_unspent *Ux,struct iguana_spend *Sx,uint8_t *TXbits,uint8_t *PKbits,uint8_t *Kspace +#define RAMCHAIN_PTRPS struct iguana_ramchain *ramchain,struct iguana_blockRO **B,struct iguana_txid **T,struct iguana_unspent20 **U,struct iguana_spend256 **S,struct iguana_pkhash **P,struct iguana_account **A,bits256 **X,struct iguana_unspent **Ux,struct iguana_spend **Sx,uint8_t **TXbits,uint8_t **PKbits,uint8_t **Kspace -#define _RAMCHAIN_ARG B,T,U,S,P,A,X,Ux,Sx,TXbits,PKbits +#define _RAMCHAIN_ARG B,T,U,S,P,A,X,Ux,Sx,TXbits,PKbits,Kspace #define RAMCHAIN_ARG ramchain,_RAMCHAIN_ARG #define MAPCHAIN_ARG mapchain,_RAMCHAIN_ARG -#define RAMCHAIN_PTRS ramchain,&B,&T,&U,&S,&P,&A,&X,&Ux,&Sx,&TXbits,&PKbits -#define RAMCHAIN_DECLARE struct iguana_blockRO *B; struct iguana_txid *T; struct iguana_unspent20 *U; struct iguana_spend256 *S; struct iguana_pkhash *P; struct iguana_account *A; bits256 *X; struct iguana_unspent *Ux; struct iguana_spend *Sx; uint8_t *TXbits,*PKbits; +#define MAPCHAIN_PTRS mapchain,&B,&T,&U,&S,&P,&A,&X,&Ux,&Sx,&TXbits,&PKbits,&Kspace + +#define RAMCHAIN_PTRS ramchain,&B,&T,&U,&S,&P,&A,&X,&Ux,&Sx,&TXbits,&PKbits,&Kspace +#define RAMCHAIN_DECLARE struct iguana_blockRO *B; struct iguana_txid *T; struct iguana_unspent20 *U; struct iguana_spend256 *S; struct iguana_pkhash *P; struct iguana_account *A; bits256 *X; struct iguana_unspent *Ux; struct iguana_spend *Sx; uint8_t *TXbits,*PKbits,*Kspace; +#define RAMCHAIN_ZEROES B = 0, Ux = 0, Sx = 0, P = 0, A = 0, X = 0, Kspace = TXbits = PKbits = 0, U = 0, S = 0, T = 0 -#define RAMCHAIN_DESTARG dest,destB,destT,destU,destS,destP,destA,destX,destUx,destSx,destTXbits,destPKbits -#define RAMCHAIN_DESTPTRS dest,&destB,&destT,&destU,&destS,&destP,&destA,&destX,&destUx,&destSx,&destTXbits,&destPKbits -#define RAMCHAIN_DESTDECLARE struct iguana_blockRO *destB; struct iguana_txid *destT; struct iguana_unspent20 *destU; struct iguana_spend256 *destS; struct iguana_pkhash *destP; struct iguana_account *destA; bits256 *destX; struct iguana_unspent *destUx; struct iguana_spend *destSx; uint8_t *destTXbits,*destPKbits; +#define RAMCHAIN_DESTARG dest,destB,destT,destU,destS,destP,destA,destX,destUx,destSx,destTXbits,destPKbits,destKspace +#define RAMCHAIN_DESTPTRS dest,&destB,&destT,&destU,&destS,&destP,&destA,&destX,&destUx,&destSx,&destTXbits,&destPKbits,&destKspace +#define RAMCHAIN_DESTDECLARE struct iguana_blockRO *destB; struct iguana_txid *destT; struct iguana_unspent20 *destU; struct iguana_spend256 *destS; struct iguana_pkhash *destP; struct iguana_account *destA; bits256 *destX; struct iguana_unspent *destUx; struct iguana_spend *destSx; uint8_t *destTXbits,*destPKbits,*destKspace; -uint32_t iguana_ramchain_addtxid(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 txid,int32_t numvouts,int32_t numvins,uint32_t locktime,uint32_t version,uint32_t timestamp) +uint32_t iguana_ramchain_addtxid(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 txid,int32_t numvouts,int32_t numvins,uint32_t locktime,uint32_t version,uint32_t timestamp,int16_t bundlei) { uint32_t txidind; struct iguana_txid *t; struct iguana_kvitem *ptr; + if ( sizeof(*t) != 64 ) + printf("sizeof iguana_txid.%d != 64?\n",(int32_t)sizeof(*t)); txidind = ramchain->H.txidind; t = &T[txidind]; if ( ramchain->H.ROflag != 0 ) { if ( t->txidind != txidind || memcmp(t->txid.bytes,txid.bytes,sizeof(bits256)) != 0 || t->numvouts != numvouts || t->numvins != numvins || t->firstvout != ramchain->H.unspentind || t->firstvin != ramchain->H.spendind || t->locktime != locktime || t->version != version || t->timestamp != timestamp ) { - printf("iguana_ramchain_addtxid: addtxid mismatch (%d %d %d %d %d) vs. (%d %d %d %d %d)\n",t->txidind,t->numvouts,t->numvins,t->firstvout,t->firstvin,txidind,numvouts,numvins,ramchain->H.unspentind,ramchain->H.spendind); - exit(-1); + printf("iguana_ramchain_addtxid.RO: addtxid mismatch (%d %d %d %d %d) vs. (%d %d %d %d %d)\n",t->txidind,t->numvouts,t->numvins,t->firstvout,t->firstvin,txidind,numvouts,numvins,ramchain->H.unspentind,ramchain->H.spendind); + //getchar(); return(0); } } else { - //if ( ramchain->expanded != 0 ) - // printf("T.%p txidind.%d numvouts.%d numvins.%d\n",T,txidind,numvouts,numvins); + if ( 0 && ramchain->expanded != 0 ) + printf("T.%p txidind.%d numvouts.%d numvins.%d\n",T,txidind,numvouts,numvins); t->txidind = txidind, t->txid = txid, t->numvouts = numvouts, t->numvins = numvins; + t->bundlei = bundlei; t->firstvout = ramchain->H.unspentind, t->firstvin = ramchain->H.spendind; t->locktime = locktime, t->version = version, t->timestamp = timestamp; + if ( t->txidind != txidind || t->firstvout != ramchain->H.unspentind || t->firstvin != ramchain->H.spendind || t->bundlei != bundlei ) + { + printf("addtxid error: t->txidind %u != %u txidind || t->firstvout %u != %u ramchain->H.unspentind || t->firstvin %u != %u ramchain->H.spendind || t->bundlei %u != %u bundlei\n",t->txidind,txidind,t->firstvout,ramchain->H.unspentind,t->firstvin,ramchain->H.spendind,t->bundlei,bundlei); + return(0); + } if ( ramchain->expanded != 0 ) - iguana_sparseaddtx(TXbits,ramchain->H.data->txsparsebits,ramchain->H.data->numtxsparse,txid,T,txidind); + iguana_sparseaddtx(TXbits,ramchain->H.data->txsparsebits,ramchain->H.data->numtxsparse,txid,T,txidind,ramchain); //if ( txidind <= 2 ) // printf("%p TXID.[%d] firstvout.%d/%d firstvin.%d/%d\n",t,txidind,ramchain->unspentind,numvouts,ramchain->spendind,numvins); } @@ -324,66 +203,92 @@ uint32_t iguana_ramchain_addtxid(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 printf("iguana_ramchain_addtxid error adding txidind\n"); return(0); } + if ( ptr->hh.itemind != txidind ) + { + printf("iguana_ramchain_addtxid warning: adding txidind.%u vs %u\n",txidind,ptr->hh.itemind); + } } return(txidind); } -uint32_t iguana_ramchain_addpkhash(struct iguana_info *coin,RAMCHAIN_FUNC,uint8_t rmd160[20],int32_t flags,uint32_t unspentind) +uint32_t iguana_ramchain_addpkhash(struct iguana_info *coin,RAMCHAIN_FUNC,uint8_t *rmd160,int32_t pubkeyind,uint32_t unspentind,uint32_t pkind) { - struct iguana_kvitem *ptr; uint32_t pkind = 0; + struct iguana_kvitem *ptr; uint32_t i; if ( ramchain->expanded != 0 && (ptr= iguana_hashfind(ramchain,'P',rmd160)) == 0 ) { - pkind = ramchain->pkind++; if ( ramchain->H.ROflag != 0 ) { - if ( P[pkind].flags != flags || P[pkind].firstunspentind != unspentind || P[pkind].pkind != pkind ) + if ( P[pkind].pkind != pkind ) //unspentind != 0 && (P[pkind].firstunspentind != unspentind || { - printf("iguana_ramchain_addpkhash pkind.%d vs %d error mismatched flags.(%x %x) firstunspentind.%x vs %x\n",pkind,P[pkind].pkind,P[pkind].flags,flags,P[pkind].firstunspentind,unspentind); + printf("iguana_ramchain_addpkhash error mismatched pkind.(%x %x) unspentind.%d\n",pkind,P[pkind].pkind,unspentind); exit(-1); return(0); } if ( memcmp(P[pkind].rmd160,rmd160,sizeof(P[pkind].rmd160)) != 0 ) { - printf("iguana_ramchain_addpkhash error mismatched rmd160\n"); - return(0); + for (i=0; i<20; i++) + printf("%02x",P[pkind].rmd160[i]); + printf(" -> rmd160 pkind.%d\n",pkind); + for (i=0; i<20; i++) + printf("%02x",rmd160[i]); + printf(" vs rmd160\n"); + printf("iguana_ramchain_addpkhash pkind.%d error mismatched rmd160\n",pkind); + //getchar(); + return(pkind); } + //ramchain->pkind = (pkind + 1); } else { - P[pkind].flags = flags; + pkind = ramchain->pkind++; P[pkind].pkind = pkind; - P[pkind].firstunspentind = unspentind; - //printf("%p P[%d] <- firstunspent.%d\n",&P[pkind],pkind,unspentind); + /*if ( P[pkind].firstunspentind == 0 && unspentind != 0 ) + { + P[pkind].firstunspentind = unspentind; + printf("%p P[%d] <- firstunspent.%d\n",&P[pkind],pkind,unspentind); + }*/ memcpy(P[pkind].rmd160,rmd160,sizeof(P[pkind].rmd160)); + //for (i=0; i<20; i++) + // printf("%02x",rmd160[i]); + //printf(" -> rmd160 pkind.%d \n",pkind); if ( ramchain->expanded != 0 ) - iguana_sparseaddpk(PKbits,ramchain->H.data->pksparsebits,ramchain->H.data->numpksparse,rmd160,P,pkind); + iguana_sparseaddpk(PKbits,ramchain->H.data->pksparsebits,ramchain->H.data->numpksparse,rmd160,P,pkind,ramchain); } if ( (ptr= iguana_hashsetPT(ramchain,'P',&P[pkind],pkind)) == 0 ) { - printf("iguana_ramchain_addpkhash error adding pkhash\n"); + printf("iguana_ramchain_addpkhash error adding pkhash pkind.%d\n",pkind); return(0); } } return(pkind); } -uint32_t iguana_ramchain_addunspent20(struct iguana_info *coin,RAMCHAIN_FUNC,uint64_t value,uint8_t *script,int32_t scriptlen,bits256 txid,int32_t vout,uint8_t type) +uint32_t iguana_ramchain_addunspent20(struct iguana_info *coin,struct iguana_peer *addr,RAMCHAIN_FUNC,uint64_t value,uint8_t *script,int32_t scriptlen,bits256 txid,int32_t vout,int8_t type,struct iguana_bundle *bp,uint8_t rmd160[20]) { - //struct iguana_unspent { uint64_t value; uint32_t txidind,pkind,prevunspentind; } __attribute__((packed)); - uint32_t unspentind; struct iguana_unspent20 *u; struct vin_info V; + uint32_t unspentind; struct iguana_unspent20 *u; long scriptpos; struct vin_info V; char asmstr[IGUANA_MAXSCRIPTSIZE*2+1]; unspentind = ramchain->H.unspentind++; u = &U[unspentind]; - if ( scriptlen == -20 ) - memcpy(V.rmd160,script,20); - else + if ( scriptlen > 0 ) { memset(&V,0,sizeof(V)); - type = iguana_calcrmd160(coin,&V,script,scriptlen,txid,vout,0xffffffff); + if ( type < 0 ) + { + type = iguana_calcrmd160(coin,asmstr,&V,script,scriptlen,txid,vout,0xffffffff); + if ( (type == 12 && scriptlen == 0) || (type == 1 && bitcoin_pubkeylen(script+1) <= 0) ) + { + int32_t i; for (i=0; iH.ROflag != 0 ) { - //printf("%p U[%d] txidind.%d pkind.%d\n",u,unspentind,ramchain->txidind,pkind); - if ( u->txidind != ramchain->H.txidind || u->value != value || memcmp(u->rmd160,V.rmd160,sizeof(V.rmd160)) != 0 ) + if ( u->txidind != ramchain->H.txidind || u->value != value || memcmp(u->rmd160,rmd160,sizeof(u->rmd160)) != 0 ) { printf("iguana_ramchain_addunspent20: mismatched values.(%.8f %d) vs (%.8f %d)\n",dstr(u->value),u->txidind,dstr(value),ramchain->H.txidind); return(0); @@ -393,28 +298,95 @@ uint32_t iguana_ramchain_addunspent20(struct iguana_info *coin,RAMCHAIN_FUNC,uin { u->value = value; u->type = type; + memcpy(u->rmd160,rmd160,sizeof(u->rmd160)); + if ( type == IGUANA_SCRIPT_76AC ) + { + static uint64_t totalsize; + totalsize += scriptlen; + char str[65]; + if ( (rand() % 100000) == 0 ) + fprintf(stderr,"IGUANA_SCRIPT_76AC type.%d scriptlen.%d bp.%p %s\n",type,scriptlen,bp,mbstr(str,totalsize)); + } + u->scriptlen = scriptlen; + u->scriptpos = 0; + u->fileid = 0; + if ( scriptlen > 0 && script != 0 ) + { + memset(&V,0,sizeof(V)); + V.spendlen = iguana_scriptgen(coin,&V.M,&V.N,V.coinaddr,V.spendscript,asmstr,u->rmd160,type,(const struct vin_info *)&V,vout); + if ( V.spendlen != scriptlen || memcmp(V.spendscript,script,scriptlen) != 0 ) + { + if ( addr != 0 && addr->voutsfp != 0 ) + { +#ifdef __PNACL__ + static portable_mutex_t mutex; + portable_mutex_lock(&mutex); +#endif + u->fileid = (uint32_t)addr->addrind; + scriptpos = ftell(addr->voutsfp); + if ( (u->scriptpos= (uint32_t)scriptpos) == 0 ) + fputc(0,addr->voutsfp), u->scriptpos++, scriptpos++; + if ( u->scriptpos != scriptpos || fwrite(script,1,scriptlen,addr->voutsfp) != scriptlen ) + printf("error writing vout scriptlen.%d errno.%d or scriptpos.%lld != %u\n",scriptlen,errno,(long long)scriptpos,u->scriptpos); + else addr->dirty[0]++; +#ifdef __PNACL__ + portable_mutex_unlock(&mutex); +#endif + } else printf("addr.%p unspent error fp.%p\n",addr,addr!=0?addr->voutsfp:0); + } + } u->txidind = ramchain->H.txidind; - memcpy(u->rmd160,V.rmd160,sizeof(V.rmd160)); + if ( 0 && vout > 0 ) + { + int32_t i; for (i=0; i<20; i++) + printf("%02x",rmd160[i]); + printf(" rmd160 "); + for (i=0; i<20; i++) + printf("%02x",u->rmd160[i]); + char str[65]; printf(" u->rmd160 type.%d scriptlen.%d:%d (%s).v%d ht.%d\n",u->type,scriptlen,u->scriptlen,bits256_str(str,txid),vout,bp->bundleheight); + } } return(unspentind); } -uint32_t iguana_ramchain_addunspent(struct iguana_info *coin,RAMCHAIN_FUNC,uint64_t value,uint16_t hdrsi,uint8_t *rmd160,uint16_t vout,uint8_t type) +uint32_t iguana_ramchain_addunspent(struct iguana_info *coin,RAMCHAIN_FUNC,uint64_t value,uint16_t hdrsi,uint8_t *rmd160,uint16_t vout,uint8_t type,uint16_t fileid,uint32_t fpos,int32_t scriptlen,int32_t txi) { - uint32_t unspentind; struct iguana_unspent *u; struct iguana_kvitem *ptr; int32_t pkind; + uint32_t unspentind; struct iguana_unspent *u; struct iguana_kvitem *ptr; int32_t i,pkind; + for (i=0; i<20; i++) + if ( rmd160[i] != 0 ) + break; + /*if ( i == 20 && vout > 0 ) + { + printf("iguana_ramchain_addunspent: null rmd160 warning txi.%d vout.%d\n",txi,vout); + //return(0); + }*/ unspentind = ramchain->H.unspentind++; u = &Ux[unspentind]; if ( (ptr= iguana_hashfind(ramchain,'P',rmd160)) == 0 ) - pkind = iguana_ramchain_addpkhash(coin,RAMCHAIN_ARG,rmd160,0,unspentind); + pkind = iguana_ramchain_addpkhash(coin,RAMCHAIN_ARG,rmd160,0,unspentind,u->pkind); else pkind = ptr->hh.itemind; if ( pkind == 0 ) + { + printf("addunspent error getting pkind\n"); return(0); + } + if ( 0 ) + { + printf(" ROflag.%d pkind.%d unspentind.%d vout.%d %.8f script[%d] uoffset.%d %d:%d type.%d A.%p\n",ramchain->H.ROflag,pkind,unspentind,vout,dstr(value),scriptlen,u->scriptpos,ramchain->H.scriptoffset,ramchain->H.data->scriptspace,type,A); + } if ( ramchain->H.ROflag != 0 ) { - //printf("%p U[%d] txidind.%d pkind.%d\n",u,unspentind,ramchain->txidind,pkind); - if ( u->value != value || u->pkind != pkind || u->value != value || u->txidind != ramchain->H.txidind || (pkind != 0 && u->prevunspentind != A[pkind].lastunspentind) || u->vout != vout || u->hdrsi != hdrsi ) + /*if ( Kspace != 0 && ((u->scriptoffset != 0 && scriptlen > 0) || type == IGUANA_SCRIPT_76AC) ) + { + checkscript = iguana_ramchain_scriptdecode(&metalen,&checklen,Kspace,u->type,_script,u->scriptoffset,P[pkind].pubkeyoffset < ramchain->H.scriptoffset ? P[pkind].pubkeyoffset : 0); + if ( checklen != scriptlen || (script != 0 && checkscript != 0 && memcmp(checkscript,script,scriptlen) != 0) ) + { + printf("script mismatch len.%d vs %d or cmp error.%d\n",scriptlen,checklen,(checkscript != 0 && script != 0) ? memcmp(checkscript,script,scriptlen):0); + } //else printf("RO spendscript match.%d\n",scriptlen); + }*/ + if ( u->fileid != fileid || u->scriptpos != fpos || u->scriptlen != scriptlen || u->value != value || u->pkind != pkind || u->value != value || u->txidind != ramchain->H.txidind || (pkind != 0 && u->prevunspentind != A[pkind].lastunspentind) || u->vout != vout || u->hdrsi != hdrsi ) { - printf("iguana_ramchain_addunspent: mismatched values.(%d %.8f %d %d %d %d) vs (%d %.8f %d %d %d %d)\n",u->pkind,dstr(u->value),u->txidind,u->prevunspentind,u->vout,u->hdrsi,pkind,dstr(value),ramchain->H.txidind,A[pkind].lastunspentind,vout,hdrsi); + printf("iguana_ramchain_addunspent: (%d %d %d) vs (%d %d %d) mismatched values.(%d %.8f %d %d %d %d) vs (%d %.8f %d %d %d %d)\n",u->fileid,u->scriptpos,u->scriptlen,fileid,fpos,scriptlen,u->pkind,dstr(u->value),u->txidind,u->prevunspentind,u->vout,u->hdrsi,pkind,dstr(value),ramchain->H.txidind,A[pkind].lastunspentind,vout,hdrsi); exit(-1); return(0); } @@ -422,69 +394,23 @@ uint32_t iguana_ramchain_addunspent(struct iguana_info *coin,RAMCHAIN_FUNC,uint6 else { u->value = value; - u->type = type; + //if ( type == IGUANA_SCRIPT_76AC ) + // pubkeyoffset = P[pkind].pubkeyoffset; + //else pubkeyoffset = 0; u->vout = vout, u->hdrsi = hdrsi; u->txidind = ramchain->H.txidind, u->pkind = pkind; u->prevunspentind = A[pkind].lastunspentind; + u->fileid = fileid; + u->scriptlen = scriptlen; + u->scriptpos = fpos; + u->type = type; } //printf("%p A[%d] last <- U%d\n",&A[pkind],pkind,unspentind); - A[pkind].balance += value; + A[pkind].total += value; A[pkind].lastunspentind = unspentind; return(unspentind); } -uint32_t iguana_ramchain_addspend256(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 prev_hash,int32_t prev_vout,uint8_t *script,int32_t scriptlen,uint32_t sequence)//,int32_t hdrsi,int32_t bundlei) -{ - struct iguana_spend256 *s; uint32_t spendind; - spendind = ramchain->H.spendind++; - s = &S[spendind]; - if ( ramchain->H.ROflag != 0 ) - { - if ( (s->diffsequence == 0 && sequence != 0xffffffff) || (s->diffsequence != 0 && sequence == 0xffffffff) || memcmp(s->prevhash2.bytes,prev_hash.bytes,sizeof(bits256)) != 0 || s->prevout != prev_vout ) //|| s->hdrsi != hdrsi - { - char str[65],str2[65]; printf("check addspend.%d v %d RO value mismatch diffseq.%d seq.%x prev_vout(%d vs %d) %s vs %s\n",spendind,s->spendind,s->diffsequence,sequence,s->prevout,prev_vout,bits256_str(str,s->prevhash2),bits256_str(str2,prev_hash)); - //printf("check addspend.%d vs %d RO value mismatch (%d %d:%d) vs (%d %d:%d)\n",spendind,s->spendind,s->prevout,s->hdrsi,s->bundlei,prev_vout,hdrsi,bundlei); - exit(-1); - return(0); - } - //printf(" READ.%p spendind.%d vs %d prevout.%d hdrsi.%d:%d\n",s,spendind,s->spendind,s->prevout,s->hdrsi,s->bundlei); - } - else - { - if ( sequence != 0xffffffff ) - s->diffsequence = 1; - s->prevhash2 = prev_hash, s->prevout = prev_vout; - //s->hdrsi = hdrsi, s->bundlei = bundlei; - s->spendind = spendind; - //char str[65]; printf("W.%p s.%d vout.%d/%d %d:%d %s\n",s,spendind,s->prevout,prev_vout,s->hdrsi,s->bundlei,bits256_str(str,prev_hash)); - } - return(spendind); -} - -int32_t iguana_ramchain_spendtxid(struct iguana_info *coin,bits256 *txidp,struct iguana_txid *T,int32_t numtxids,bits256 *X,int32_t numexternaltxids,struct iguana_spend *s) -{ - uint32_t ind,external; - memset(txidp,0,sizeof(*txidp)); - //printf("s.%p ramchaintxid vout.%x spendtxidind.%d numexternals.%d isext.%d numspendinds.%d\n",s,s->vout,s->spendtxidind,ramchain->numexternaltxids,s->external,ramchain->numspends); - if ( s->prevout < 0 ) - return(-1); - ind = s->spendtxidind; - external = (ind >> 31) & 1; - ind &= ~(1 << 31); - if ( s->external != 0 && s->external == external && ind < numexternaltxids ) - { - //printf("ind.%d externalind.%d X[%d]\n",ind,ramchain->externalind,ramchain->H.data->numexternaltxids); - *txidp = X[ind]; - return(s->prevout); - } - else if ( s->external == 0 && s->external == external && ind < numtxids ) - { - *txidp = T[ind].txid; - return(s->prevout); - } - return(-2); -} - int32_t iguana_ramchain_txid(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 *txidp,struct iguana_spend *s) { uint32_t ind,external; @@ -509,14 +435,16 @@ int32_t iguana_ramchain_txid(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 *txi return(-2); } -uint32_t iguana_ramchain_addspend(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 prev_hash,int32_t prev_vout,uint32_t sequence)//,int32_t hdrsi,int32_t bundlei) +uint32_t iguana_ramchain_addspend(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 prev_hash,int32_t prev_vout,uint32_t sequence,int32_t hdrsi,uint16_t fileid,uint64_t scriptpos,int32_t vinscriptlen) { - struct iguana_spend *s; struct iguana_kvitem *ptr; bits256 txid; - uint32_t spendind,unspentind,txidind,pkind,external; uint64_t value = 0; + struct iguana_spend *s; struct iguana_kvitem *ptr = 0; bits256 txid; + uint32_t spendind,unspentind,txidind=0,pkind,external=0; uint64_t value = 0; + // uint8_t _script[IGUANA_MAXSCRIPTSIZE]; int32_t metalen,i,checklen; spendind = ramchain->H.spendind++; s = &Sx[spendind]; pkind = unspentind = 0; - if ( (ptr= iguana_hashfind(ramchain,'T',prev_hash.bytes)) == 0 ) + ptr = iguana_hashfind(ramchain,'T',prev_hash.bytes); + if ( prev_vout >= 0 && ptr == 0 ) { external = 1; txidind = ramchain->externalind++; @@ -536,8 +464,12 @@ uint32_t iguana_ramchain_addspend(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 return(0); } txidind |= (1 << 31); - } else txidind = ptr->hh.itemind; - if ( (external= ((txidind >> 31) & 1)) == 0 ) + } + else if ( ptr != 0 ) + txidind = ptr->hh.itemind; + else if ( prev_vout >= 0 ) + printf("unexpected addspend case: null ptr prev.%d [%d] s%u\n",prev_vout,hdrsi,spendind); + if ( prev_vout >= 0 && (external= ((txidind >> 31) & 1)) == 0 ) { if ( txidind > 0 && txidind < ramchain->H.data->numtxids ) { @@ -555,18 +487,65 @@ uint32_t iguana_ramchain_addspend(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 if ( ramchain->H.ROflag != 0 ) { iguana_ramchain_txid(coin,RAMCHAIN_ARG,&txid,s); - if ( (s->diffsequence == 0 && sequence != 0xffffffff) || (s->diffsequence != 0 && sequence == 0xffffffff) || memcmp(txid.bytes,prev_hash.bytes,sizeof(bits256)) != 0 || s->prevout != prev_vout )// || s->hdrsi != hdrsi + if ( s->sequenceid != sequence || memcmp(txid.bytes,prev_hash.bytes,sizeof(bits256)) != 0 || s->prevout != prev_vout ) { - char str[65],str2[65]; printf("ramchain_addspend RO value mismatch diffseq.%d v %x (%d) vs (%d) %s vs %s\n",s->diffsequence,sequence,s->prevout,prev_vout,bits256_str(str,txid),bits256_str(str2,prev_hash)); + char str[65],str2[65]; printf("ramchain_addspend RO value mismatch diffseq.%x v %x (%d) vs (%d) %s vs %s\n",s->sequenceid,sequence,s->prevout,prev_vout,bits256_str(str,txid),bits256_str(str2,prev_hash)); return(0); } + /*if ( (checklen= iguana_vinscriptdecode(coin,ramchain,&metalen,_script,&Kspace[ramchain->H.data->scriptspace],Kspace,s)) != vinscriptlen || (vinscript != 0 && memcmp(_script,vinscript,vinscriptlen) != 0) ) + { + static uint64_t counter; + if ( counter++ < 100 ) + { + for (i=0; iH.scriptoffset += metalen; } else { - if ( sequence != 0xffffffff ) - s->diffsequence = 1; + //for (i=0; isequenceid = sequence; s->external = external, s->spendtxidind = txidind, s->prevout = prev_vout; + s->fileid = fileid; + s->scriptpos = scriptpos; + s->scriptlen = vinscriptlen; + /*static uint64_t good,bad; + if ( 0 && iguana_metascript(coin,RAMCHAIN_ARG,s,vinscript,vinscriptlen,0) < 0 ) + { + static long errlen,err2len; char errbuf[1024]; + errlen += vinscriptlen; + if ( iguana_metascript(coin,RAMCHAIN_ARG,s,vinscript,vinscriptlen,1) < 0 ) + { + err2len += vinscriptlen; + errbuf[0] = 0; + for (i=0; i 138 ) + { + errbuf[0] = 0; + for (i=0; ihdrsi = hdrsi; //s->bundlei = bundlei; //char str[65]; printf("%s set prevout.%d -> %d\n",bits256_str(str,prev_hash),prev_vout,s->prevout); @@ -575,97 +554,276 @@ uint32_t iguana_ramchain_addspend(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 } if ( pkind != 0 ) { - A[pkind].balance -= value; + //A[pkind].balance -= value; //A[pkind].lastspendind = spendind; //if ( P2[pkind].firstspendind == 0 ) // P2[pkind].firstspendind = spendind; } - /*if ( unspentind != 0 ) + return(spendind); +} + +uint32_t iguana_ramchain_addspend256(struct iguana_info *coin,struct iguana_peer *addr,RAMCHAIN_FUNC,bits256 prev_hash,int32_t prev_vout,uint8_t *vinscript,int32_t vinscriptlen,uint32_t sequence,struct iguana_bundle *bp) +{ + struct iguana_spend256 *s; uint32_t spendind; int32_t err; + spendind = ramchain->H.spendind++; + s = &S[spendind]; + if ( ramchain->H.ROflag != 0 ) + { + if ( vinscriptlen != s->vinscriptlen || s->sequenceid != sequence || memcmp(s->prevhash2.bytes,prev_hash.bytes,sizeof(bits256)) != 0 || s->prevout != prev_vout ) //|| s->hdrsi != hdrsi + { + char str[65],str2[65]; printf("check offset %llu (%d %d) addspend.%d v %d RO value mismatch sequenceid.%x seq.%x prev_vout(%d vs %d) %s vs %s\n",(long long)s->scriptpos,vinscriptlen,s->vinscriptlen,spendind,s->spendind,s->sequenceid,sequence,s->prevout,prev_vout,bits256_str(str,s->prevhash2),bits256_str(str2,prev_hash)); + //printf("check addspend.%d vs %d RO value mismatch (%d %d:%d) vs (%d %d:%d)\n",spendind,s->spendind,s->prevout,s->hdrsi,s->bundlei,prev_vout,hdrsi,bundlei); + //exit(-1); + return(0); + } + //printf(" READ.%p spendind.%d vs %d prevout.%d hdrsi.%d:%d\n",s,spendind,s->spendind,s->prevout,s->hdrsi,s->bundlei); + } + else { - if ( U2[unspentind].spendind == 0 ) - U2[unspentind].spendind = spendind; - }*/ + s->sequenceid = sequence; + s->prevhash2 = prev_hash, s->prevout = prev_vout; + s->spendind = spendind; + if ( (s->vinscriptlen= vinscriptlen) > 0 && vinscript != 0 && addr != 0 && addr->vinsfp != 0 && vinscriptlen < IGUANA_MAXSCRIPTSIZE) + { +#ifdef __PNACL__ + static portable_mutex_t mutex; + portable_mutex_lock(&mutex); +#endif + s->fileid = (uint32_t)addr->addrind; + if ( (s->scriptpos= ftell(addr->vinsfp)) == 0 ) + fputc(0,addr->vinsfp), s->scriptpos++; + if ( (err= (int32_t)fwrite(vinscript,1,vinscriptlen,addr->vinsfp)) != vinscriptlen ) + printf("error.%d writing vinscriptlen.%d errno.%d addrind.%d\n",err,vinscriptlen,errno,addr->addrind); + else addr->dirty[1]++; +#ifdef __PNACL__ + portable_mutex_unlock(&mutex); +#endif + } else s->scriptpos = 0; + //else printf("spend256 scriptfpos.%d\n",s->scriptfpos); + //char str[65]; printf("W.%p s.%d vout.%d/%d [%d] %s fpos.%u slen.%d\n",s,spendind,s->prevout,prev_vout,bp->hdrsi,bits256_str(str,prev_hash),s->scriptfpos,s->vinscriptlen); + } return(spendind); } -int64_t iguana_hashmemsize(uint32_t numtxids,uint32_t numunspents,uint32_t numspends,uint32_t numpkinds,uint32_t numexternaltxids) +int64_t iguana_hashmemsize(int64_t numtxids,int64_t numunspents,int64_t numspends,int64_t numpkinds,int64_t numexternaltxids,int64_t scriptspace) { int64_t allocsize = 0; - allocsize += (65536*4 + ((numtxids + numpkinds) * (sizeof(UT_hash_handle)*2)) + (((sizeof(struct iguana_account)) * 2 * numpkinds)) + (2 * numunspents * sizeof(struct iguana_Uextra))); + allocsize += (scriptspace + IGUANA_MAXSCRIPTSIZE + ((numtxids + numpkinds) * (sizeof(UT_hash_handle)*2)) + (((sizeof(struct iguana_account)) * 2 * numpkinds)) + (2 * numunspents * sizeof(struct iguana_spendvector))); + if ( allocsize >= (1LL << 32) ) + { + printf("REALLY big hashmemsize %llu, truncate and hope for best\n",(long long)allocsize); + allocsize = (1LL << 32) - 1; + } //printf("iguana_hashmemsize T.%d U.%d S.%d P.%d X.%d -> %ld\n",numtxids,numunspents,numspends,numpkinds,numexternaltxids,(long)allocsize); return(allocsize); } -void _iguana_ramchain_setptrs(RAMCHAIN_PTRPS,struct iguana_ramchaindata *rdata) +void *_iguana_ramchain_setptrs(RAMCHAIN_PTRPS,struct iguana_ramchaindata *rdata) { - *B = (void *)(long)((long)rdata + (long)rdata->Boffset); - *T = (void *)(long)((long)rdata + (long)rdata->Toffset); + if ( rdata == 0 ) + { + printf("_iguana_ramchain_setptrs: null rdata\n"); + return(0); + } + //printf("rdata.%p\n",rdata); + *B = RAMCHAIN_PTR(rdata,Boffset); + *T = RAMCHAIN_PTR(rdata,Toffset); + //*B = (void *)(long)((long)rdata + (long)rdata->Boffset); + //*T = (void *)(long)((long)rdata + (long)rdata->Toffset); + *Kspace = RAMCHAIN_PTR(rdata,Koffset); + //*Kspace = (void *)(long)((long)rdata + (long)rdata->Koffset); if ( ramchain->expanded != 0 ) { - *Ux = (void *)(long)((long)rdata + (long)rdata->Uoffset); - *Sx = (void *)(long)((long)rdata + (long)rdata->Soffset); - *P = (void *)(long)((long)rdata + (long)rdata->Poffset); - *X = (void *)(long)((long)rdata + (long)rdata->Xoffset); + *Ux = RAMCHAIN_PTR(rdata,Uoffset); + *Sx = RAMCHAIN_PTR(rdata,Soffset); + *P = RAMCHAIN_PTR(rdata,Poffset); + *X = RAMCHAIN_PTR(rdata,Xoffset); + //*Ux = (void *)(long)((long)rdata + (long)rdata->Uoffset); + //*Sx = (void *)(long)((long)rdata + (long)rdata->Soffset); + //*P = (void *)(long)((long)rdata + (long)rdata->Poffset); + //*X = (void *)(long)((long)rdata + (long)rdata->Xoffset); //ramchain->roU2 = (void *)(long)((long)rdata + (long)rdata->U2offset); //ramchain->roP2 = (void *)(long)((long)rdata + (long)rdata->P2offset); - ramchain->roA = (void *)(long)(long)((long)rdata + (long)rdata->Aoffset); + ramchain->creditsA = RAMCHAIN_PTR(rdata,Aoffset); + //ramchain->creditsA = (void *)(long)(long)((long)rdata + (long)rdata->Aoffset); //if ( (*U2= ramchain->U2) == 0 ) // *U2 = ramchain->U2 = ramchain->roU2; //if ( (*P2= ramchain->P2) == 0 ) // *P2 = ramchain->P2 = ramchain->roP2; if ( (*A= ramchain->A) == 0 ) - *A = ramchain->A = ramchain->roA; + *A = ramchain->A = ramchain->creditsA; //printf("T.%p Ux.%p Sx.%p P.%p\n",*T,*Ux,*Sx,*P); - *TXbits = (void *)(long)((long)rdata + (long)rdata->TXoffset); - *PKbits = (void *)(long)((long)rdata + (long)rdata->PKoffset); + *TXbits = RAMCHAIN_PTR(rdata,TXoffset); + *PKbits = RAMCHAIN_PTR(rdata,PKoffset); + //*TXbits = (void *)(long)((long)rdata + (long)rdata->TXoffset); + //*PKbits = (void *)(long)((long)rdata + (long)rdata->PKoffset); *U = 0, *S = 0; } else { - *U = (void *)(long)((long)rdata + (long)rdata->Uoffset); - *S = (void *)(long)((long)rdata + (long)rdata->Soffset); + *U = RAMCHAIN_PTR(rdata,Uoffset); + *S = RAMCHAIN_PTR(rdata,Soffset); + //*U = (void *)(long)((long)rdata + (long)rdata->Uoffset); + //*S = (void *)(long)((long)rdata + (long)rdata->Soffset); *Ux = 0, *Sx = 0, *P = 0, *X = 0, *A = 0, *TXbits = 0, *PKbits = 0; //*U2 = 0, *P2 = 0, } + return(rdata); } -void *iguana_ramchain_offset(void *dest,uint8_t *lhash,FILE *fp,uint64_t fpos,void *srcptr,uint64_t *offsetp,uint64_t len,uint64_t srcsize) +void *iguana_ramchain_offset(char *fname,void *dest,uint8_t *lhash,FILE *fp,uint64_t fpos,void *srcptr,uint64_t *offsetp,uint64_t len,uint64_t srcsize) { - void *destptr = (void *)(long)((long)dest + *offsetp); + long err,startfpos; void *destptr = (void *)(long)((long)dest + *offsetp); if ( (lhash != 0 || fp != 0) && (*offsetp + len) > srcsize ) { printf("ramchain_offset overflow (%p %p) offset.%ld + len.%ld %ld > %ld srcsize\n",fp,lhash,(long)*offsetp,(long)len,(long)(*offsetp + len),(long)srcsize); - exit(-1); + return(destptr); } if ( lhash != 0 ) { //fprintf(stderr,"lhash.%p memptr.%p offset.%ld len.%ld avail.%ld srcsize.%ld\n",lhash,srcptr,(long)*offsetp,(long)len,(long)(srcsize - (*offsetp + len)),(long)srcsize); vcalc_sha256(0,lhash,srcptr,(uint32_t)len); } - else if ( fp != 0 ) - { - if ( fwrite(srcptr,1,len,fp) != len ) - printf("iguana_ramchain_sizefunc: error writing len.%ld to fp.%p\n",(long)len,fp); + else if ( fp != 0 && len > 0 ) + { +#ifdef __PNACL__ + static portable_mutex_t mutex; + portable_mutex_lock(&mutex); +#endif + startfpos = ftell(fp); + err = fwrite(srcptr,1,len,fp); +#ifdef __PNACL__ + portable_mutex_unlock(&mutex); +#endif + if ( err != len ) + { + printf("iguana_ramchain_offset.(%s): error.%ld writing len.%ld to fp.%p errno.%d\n",fname,err,(long)len,fp,errno); + printf("probably out of disk space. please free up space\n"); + fprintf(stderr,"iguana_ramchain_sizefunc.(%s): error.%ld writing len.%ld to fp.%p errno.%d\n",fname,err,(long)len,fp,errno); + fprintf(stderr,"probably out of disk space. please free up space\n"); + fpos = len = 0; + } +#ifdef __PNACL__ + if ( 0 && len > 0 ) + { + int32_t i,c; + fseek(fp,startfpos,SEEK_SET); + for (i=0; iH.data != 0 ) + { + if ( flag == 0 ) + { + ptr = ramchain->fileptr; + for (i=0; ifilesize; i++) + if ( ptr[i] != 0 ) + nonz++; + } + else if ( (flag & 1) != 0 ) + { + //printf("nonz.%d of %d\n",nonz,(int32_t)ramchain->filesize); + X = RAMCHAIN_PTR(ramchain->H.data,Xoffset); + T = RAMCHAIN_PTR(ramchain->H.data,Toffset); + TXbits = RAMCHAIN_PTR(ramchain->H.data,TXoffset); + //X = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Xoffset); + //T = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Toffset); + //TXbits = (void *)(long)((long)ramchain->H.data + ramchain->H.data->TXoffset); + numtxids = ramchain->H.data->numtxids; + numexternal = ramchain->H.data->numexternaltxids; + tlen = (ramchain->H.data->numtxsparse * ramchain->H.data->txsparsebits) >> 3; + for (i=0; iH.data,Uoffset); + //U = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Uoffset); + numunspents = ramchain->H.data->numunspents; + for (i=0; iH.data,Poffset); + PKbits = RAMCHAIN_PTR(ramchain->H.data,PKoffset); + //P = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Poffset); + //PKbits = (void *)(long)((long)ramchain->H.data + ramchain->H.data->PKoffset); + numpkinds = ramchain->H.data->numpkinds; + plen = (ramchain->H.data->numpksparse * ramchain->H.data->pksparsebits) >> 3; + for (i=0; i nonz.%d\n",ramchain->H.data->height,flag,nonz); + return(nonz); +} + +int64_t _iguana_rdata_action(char *fname,FILE *fp,bits256 lhashes[IGUANA_NUMLHASHES],void *destptr,uint64_t fpos,uint32_t expanded,uint32_t numtxids,uint32_t numunspents,uint32_t numspends,uint32_t numpkinds,uint32_t numexternaltxids,uint32_t scriptspace,uint32_t txsparsebits,uint64_t numtxsparse,uint32_t pksparsebits,uint64_t numpksparse,uint64_t srcsize,RAMCHAIN_FUNC,int32_t numblocks) { #define RAMCHAIN_LARG(ind) ((lhashes == 0) ? 0 : lhashes[ind].bytes) -#define SPARSECOUNT(x) ((x) << 2) FILE *fparg = 0; int32_t iter; uint64_t txbits,pkbits,offset = 0; struct iguana_ramchaindata *rdata = destptr; if ( expanded != 0 ) { if( txsparsebits == 0 || numtxsparse == 0 ) { txsparsebits = hcalc_bitsize(numtxids); + /*if ( txsparsebits < 8 ) + txsparsebits = 8; + else if ( txsparsebits < 16 ) + txsparsebits = 16; + else if ( txsparsebits < 32 ) + txsparsebits = 32;*/ numtxsparse = SPARSECOUNT(numtxids); } if ( pksparsebits == 0 || numpksparse == 0 ) { pksparsebits = hcalc_bitsize(numpkinds); + /*if ( pksparsebits < 8 ) + pksparsebits = 8; + else if ( pksparsebits < 16 ) + pksparsebits = 16; + else if ( pksparsebits < 32 ) + pksparsebits = 32;*/ numpksparse = SPARSECOUNT(numpkinds); } txbits = numtxsparse * txsparsebits; pkbits = numpksparse * pksparsebits; @@ -681,38 +839,39 @@ int64_t _iguana_rdata_action(FILE *fp,bits256 lhashes[IGUANA_NUMLHASHES],void *d char str[65]; //if ( fparg != 0 && numblocks > 1 ) // printf("%p B[0] %s -> ",B,bits256_str(str,B[0].hash2)); - B = iguana_ramchain_offset(rdata,RAMCHAIN_LARG(IGUANA_LHASH_BLOCKS),fparg,fpos,B,&offset,(sizeof(struct iguana_blockRO) * numblocks),srcsize); + B = iguana_ramchain_offset(fname,rdata,RAMCHAIN_LARG(IGUANA_LHASH_BLOCKS),fparg,fpos,B,&offset,(sizeof(struct iguana_blockRO) * numblocks),srcsize); if ( 0 && fparg != 0 && numblocks > 1 ) { printf("%s %p\n",bits256_str(str,B[0].hash2),B); - if ( bits256_nonz(B[0].hash2) == 0 ) - getchar(); + //if ( bits256_nonz(B[0].hash2) == 0 ) + // getchar(); } - T = iguana_ramchain_offset(rdata,RAMCHAIN_LARG(IGUANA_LHASH_TXIDS),fparg,fpos,T,&offset,(sizeof(struct iguana_txid) * numtxids),srcsize); + T = iguana_ramchain_offset(fname,rdata,RAMCHAIN_LARG(IGUANA_LHASH_TXIDS),fparg,fpos,T,&offset,(sizeof(struct iguana_txid) * numtxids),srcsize); if ( expanded != 0 ) { U = destptr, S = destptr; - Ux = iguana_ramchain_offset(rdata,RAMCHAIN_LARG(IGUANA_LHASH_UNSPENTS),fparg,fpos,Ux,&offset,(sizeof(struct iguana_unspent) * numunspents),srcsize); - Sx = iguana_ramchain_offset(rdata,RAMCHAIN_LARG(IGUANA_LHASH_SPENDS),fparg,fpos,Sx,&offset,(sizeof(struct iguana_spend) * numspends),srcsize); - P = iguana_ramchain_offset(rdata,RAMCHAIN_LARG(IGUANA_LHASH_PKHASHES),fparg,fpos,P,&offset,(sizeof(struct iguana_pkhash) * numpkinds),srcsize); - //U2 = iguana_ramchain_offset(rdata,RAMCHAIN_LARG(IGUANA_LHASH_SPENTINDS),fparg,fpos,U2,&offset,(sizeof(struct iguana_Uextra) * numunspents),srcsize); - //P2 = 0;//iguana_ramchain_offset(rdata,RAMCHAIN_LARG(IGUANA_LHASH_FIRSTSPENDS),fparg,fpos,P2,&offset,(sizeof(struct iguana_pkextra) * numpkinds),srcsize); - A = iguana_ramchain_offset(rdata,RAMCHAIN_LARG(IGUANA_LHASH_ACCOUNTS),fparg,fpos,A,&offset,(sizeof(struct iguana_account) * numpkinds),srcsize); + Ux = iguana_ramchain_offset(fname,rdata,RAMCHAIN_LARG(IGUANA_LHASH_UNSPENTS),fparg,fpos,Ux,&offset,(sizeof(struct iguana_unspent) * numunspents),srcsize); + Sx = iguana_ramchain_offset(fname,rdata,RAMCHAIN_LARG(IGUANA_LHASH_SPENDS),fparg,fpos,Sx,&offset,(sizeof(struct iguana_spend) * numspends),srcsize); + P = iguana_ramchain_offset(fname,rdata,RAMCHAIN_LARG(IGUANA_LHASH_PKHASHES),fparg,fpos,P,&offset,(sizeof(struct iguana_pkhash) * numpkinds),srcsize); + //U2 = iguana_ramchain_offset(fname,rdata,RAMCHAIN_LARG(IGUANA_LHASH_SPENTINDS),fparg,fpos,U2,&offset,(sizeof(struct iguana_Uextra) * numunspents),srcsize); + //P2 = 0;//iguana_ramchain_offset(fname,rdata,RAMCHAIN_LARG(IGUANA_LHASH_FIRSTSPENDS),fparg,fpos,P2,&offset,(sizeof(struct iguana_pkextra) * numpkinds),srcsize); + A = iguana_ramchain_offset(fname,rdata,RAMCHAIN_LARG(IGUANA_LHASH_ACCOUNTS),fparg,fpos,A,&offset,(sizeof(struct iguana_account) * numpkinds),srcsize); char str[65]; if ( 0 && X != 0 ) printf("%p X[1] -> %s\n",&X[1],bits256_str(str,X[1])); - X = iguana_ramchain_offset(rdata,RAMCHAIN_LARG(IGUANA_LHASH_EXTERNALS),fparg,fpos,X,&offset,(sizeof(bits256) * numexternaltxids),srcsize); - TXbits = iguana_ramchain_offset(rdata,RAMCHAIN_LARG(IGUANA_LHASH_TXBITS),fparg,fpos,TXbits,&offset,hconv_bitlen(txbits),srcsize); - PKbits = iguana_ramchain_offset(rdata,RAMCHAIN_LARG(IGUANA_LHASH_PKBITS),fparg,fpos,PKbits,&offset,hconv_bitlen(pkbits),srcsize); + X = iguana_ramchain_offset(fname,rdata,RAMCHAIN_LARG(IGUANA_LHASH_EXTERNALS),fparg,fpos,X,&offset,(sizeof(bits256) * numexternaltxids),srcsize); + TXbits = iguana_ramchain_offset(fname,rdata,RAMCHAIN_LARG(IGUANA_LHASH_TXBITS),fparg,fpos,TXbits,&offset,hconv_bitlen(txbits),srcsize); + PKbits = iguana_ramchain_offset(fname,rdata,RAMCHAIN_LARG(IGUANA_LHASH_PKBITS),fparg,fpos,PKbits,&offset,hconv_bitlen(pkbits),srcsize); } else { - Ux = destptr, Sx = destptr, P = destptr, A = destptr, X = destptr, TXbits = destptr, PKbits = destptr; //U2 = destptr, P2 = destptr, - U = iguana_ramchain_offset(rdata,RAMCHAIN_LARG(IGUANA_LHASH_UNSPENTS),fparg,fpos,U,&offset,(sizeof(struct iguana_unspent20) * numunspents),srcsize); + Ux = destptr, Sx = destptr, P = destptr, A = destptr, X = destptr, TXbits = destptr, PKbits = destptr, Kspace = destptr; //U2 = destptr, P2 = destptr, + U = iguana_ramchain_offset(fname,rdata,RAMCHAIN_LARG(IGUANA_LHASH_UNSPENTS),fparg,fpos,U,&offset,(sizeof(struct iguana_unspent20) * numunspents),srcsize); if ( 0 && lhashes != 0 ) printf("iter.%d lhashes.%p offset.%ld destptr.%p len.%ld fparg.%p fpos.%ld srcsize.%ld\n",iter,RAMCHAIN_LARG(IGUANA_LHASH_SPENDS),(long)offset,destptr,(long)sizeof(struct iguana_spend256) * numspends,fparg,(long)fpos,(long)srcsize); - S = iguana_ramchain_offset(rdata,RAMCHAIN_LARG(IGUANA_LHASH_SPENDS),fparg,fpos,S,&offset,(sizeof(struct iguana_spend256) * numspends),srcsize); + S = iguana_ramchain_offset(fname,rdata,RAMCHAIN_LARG(IGUANA_LHASH_SPENDS),fparg,fpos,S,&offset,(sizeof(struct iguana_spend256) * numspends),srcsize); } + Kspace = iguana_ramchain_offset(fname,rdata,RAMCHAIN_LARG(IGUANA_LHASH_KSPACE),fparg,fpos,Kspace,&offset,scriptspace,srcsize); // at the end so it can be truncated if ( (fparg= fp) == 0 ) break; lhashes = 0; @@ -732,6 +891,8 @@ int64_t _iguana_rdata_action(FILE *fp,bits256 lhashes[IGUANA_NUMLHASHES],void *d rdata->Uoffset = (uint64_t)((long)U - (long)destptr); rdata->Soffset = (uint64_t)((long)S - (long)destptr); } + rdata->Koffset = (uint64_t)((long)Kspace - (long)destptr); + rdata->scriptspace = (uint32_t)(offset - rdata->Koffset); rdata->Poffset = (uint64_t)((long)P - (long)destptr); //rdata->U2offset = (uint64_t)((long)U2 - (long)destptr); //rdata->P2offset = (uint64_t)((long)P2 - (long)destptr); @@ -752,72 +913,81 @@ int64_t _iguana_rdata_action(FILE *fp,bits256 lhashes[IGUANA_NUMLHASHES],void *d #undef SPARSECOUNT } -int64_t iguana_ramchain_action(RAMCHAIN_FUNC,FILE *fp,bits256 lhashes[IGUANA_NUMLHASHES],struct iguana_ramchaindata *destdata,uint64_t fpos,struct iguana_ramchaindata *srcdata,int32_t numblocks) +int64_t iguana_ramchain_action(char *fname,RAMCHAIN_FUNC,FILE *fp,bits256 lhashes[IGUANA_NUMLHASHES],struct iguana_ramchaindata *destdata,uint64_t fpos,struct iguana_ramchaindata *srcdata,int32_t numblocks,int32_t scriptspace) { - if ( 0 && ramchain->expanded != 0 ) + if ( 0 && ramchain->expanded == 0 ) printf("action.%p (%p %p %p) %ld allocated.%ld [%d:%d %d:%d]\n",srcdata,fp,lhashes,destdata,(long)fpos,(long)srcdata->allocsize,srcdata->txsparsebits,srcdata->numtxsparse,srcdata->pksparsebits,srcdata->numpksparse); - return(_iguana_rdata_action(fp,lhashes,destdata,fpos,ramchain->expanded,srcdata->numtxids,srcdata->numunspents,srcdata->numspends,srcdata->numpkinds,srcdata->numexternaltxids,srcdata->txsparsebits,srcdata->numtxsparse,srcdata->pksparsebits,srcdata->numpksparse,srcdata->allocsize,RAMCHAIN_ARG,numblocks)); + return(_iguana_rdata_action(fname,fp,lhashes,destdata,fpos,ramchain->expanded,srcdata->numtxids,srcdata->numunspents,srcdata->numspends,srcdata->numpkinds,srcdata->numexternaltxids,scriptspace,srcdata->txsparsebits,srcdata->numtxsparse,srcdata->pksparsebits,srcdata->numpksparse,srcdata->allocsize,RAMCHAIN_ARG,numblocks)); } -int64_t iguana_ramchain_size(RAMCHAIN_FUNC,int32_t numblocks) +int64_t iguana_ramchain_size(char *fname,RAMCHAIN_FUNC,int32_t numblocks,int32_t scriptspace) { - return(iguana_ramchain_action(RAMCHAIN_ARG,0,0,0,0,ramchain->H.data,numblocks)); + int64_t allocsize; + allocsize = iguana_ramchain_action(fname,RAMCHAIN_ARG,0,0,0,0,ramchain->H.data,numblocks,scriptspace); + if ( 0 && ramchain->expanded != 0 ) + printf("%p iguana_ramchain_size.expanded.%d %u: Koffset.%u scriptoffset.%u stacksize.%u stackspace.%u [%u]\n",ramchain,ramchain->expanded,(int32_t)allocsize,(int32_t)ramchain->H.data->Koffset,(int32_t)ramchain->H.scriptoffset,(int32_t)ramchain->H.stacksize,(int32_t)ramchain->H.data->stackspace,scriptspace); + return(allocsize); } -long iguana_ramchain_setsize(struct iguana_ramchain *ramchain,struct iguana_ramchaindata *srcdata,int32_t numblocks) +long iguana_ramchain_setsize(char *fname,struct iguana_ramchain *ramchain,struct iguana_ramchaindata *srcdata,int32_t numblocks) { - RAMCHAIN_DECLARE; struct iguana_ramchaindata *rdata = ramchain->H.data; - B = 0, Ux = 0, Sx = 0, P = 0, A = 0, X = 0, TXbits = 0, PKbits = 0, U = 0, S = 0, T = 0; //U2 = 0, P2 = 0, + RAMCHAIN_DECLARE; RAMCHAIN_ZEROES; struct iguana_ramchaindata *rdata = ramchain->H.data; + //B = 0, Ux = 0, Sx = 0, P = 0, A = 0, X = 0, Kspace = TXbits = PKbits = 0, U = 0, S = 0, T = 0; //U2 = 0, P2 = 0, rdata->numtxids = ramchain->H.txidind; rdata->numunspents = ramchain->H.unspentind; rdata->numspends = ramchain->H.spendind; rdata->numpkinds = ramchain->pkind; rdata->numexternaltxids = ramchain->externalind; - rdata->allocsize = iguana_ramchain_size(RAMCHAIN_ARG,numblocks); + rdata->scriptspace = ramchain->H.scriptoffset; + rdata->stackspace = ramchain->H.stacksize; + rdata->allocsize = iguana_ramchain_size(fname,RAMCHAIN_ARG,numblocks,rdata->scriptspace); + if ( 0 && rdata->scriptspace != 0 ) + printf("iguana_ramchain_setsize: Koffset.%d scriptspace.%d stackspace.%d (scriptoffset.%d stacksize.%d) allocsize.%d\n",(int32_t)rdata->Koffset,(int32_t)rdata->scriptspace,(int32_t)rdata->stackspace,(int32_t)ramchain->H.scriptoffset,(int32_t)ramchain->H.stacksize,(int32_t)rdata->allocsize); ramchain->datasize = rdata->allocsize; return((long)rdata->allocsize); } -int64_t iguana_ramchain_compact(RAMCHAIN_FUNC,struct iguana_ramchaindata *destdata,struct iguana_ramchaindata *srcdata,int32_t numblocks) +int64_t iguana_ramchain_compact(char *fname,RAMCHAIN_FUNC,struct iguana_ramchaindata *destdata,struct iguana_ramchaindata *srcdata,int32_t numblocks) { //iguana_ramchain_setsize(ramchain,srcdata); - return(iguana_ramchain_action(RAMCHAIN_ARG,0,0,destdata,0,srcdata,numblocks)); + return(iguana_ramchain_action(fname,RAMCHAIN_ARG,0,0,destdata,0,srcdata,numblocks,ramchain->H.scriptoffset)); } -bits256 iguana_ramchain_lhashes(RAMCHAIN_FUNC,struct iguana_ramchaindata *destdata,struct iguana_ramchaindata *srcdata,int32_t numblocks) +bits256 iguana_ramchain_lhashes(char *fname,RAMCHAIN_FUNC,struct iguana_ramchaindata *destdata,struct iguana_ramchaindata *srcdata,int32_t numblocks,int32_t scriptspace) { - iguana_ramchain_action(RAMCHAIN_ARG,0,destdata->lhashes,0,0,srcdata,numblocks); + iguana_ramchain_action(fname,RAMCHAIN_ARG,0,destdata->lhashes,0,0,srcdata,numblocks,scriptspace); memset(&destdata->sha256,0,sizeof(destdata->sha256)); vcalc_sha256(0,destdata->sha256.bytes,(void *)destdata,sizeof(*destdata)); return(destdata->sha256); } -int64_t iguana_ramchain_saveaction(RAMCHAIN_FUNC,FILE *fp,struct iguana_ramchaindata *rdata,int32_t numblocks) +int64_t iguana_ramchain_saveaction(char *fname,RAMCHAIN_FUNC,FILE *fp,struct iguana_ramchaindata *rdata,int32_t numblocks,int32_t scriptspace) { long before,after; before = ftell(fp); - iguana_ramchain_action(RAMCHAIN_ARG,fp,0,rdata,0,rdata,numblocks); + iguana_ramchain_action(fname,RAMCHAIN_ARG,fp,0,rdata,0,rdata,numblocks,scriptspace); after = ftell(fp); - if ( 0 && ramchain->expanded != 0 ) + if ( 0 && ramchain->expanded == 0 ) { - char str[65]; - printf("SAVEACTION: rdata.%ld DEST T.%d U.%d S.%d P.%d X.%d -> size.%ld %ld vs %ld %p %s\n",sizeof(*rdata),rdata->numtxids,rdata->numunspents,rdata->numspends,rdata->numpkinds,rdata->numexternaltxids,(long)rdata->allocsize,(long)iguana_ramchain_size(RAMCHAIN_ARG,numblocks),after-before+sizeof(*rdata),&X[1],bits256_str(str,X[1])); + int32_t i; for (i=0; i size.%ld %ld vs %ld %u\n",(int32_t)rdata->Koffset,(long)Kspace-(long)rdata,(int32_t)sizeof(*rdata),rdata->numtxids,rdata->numunspents,rdata->numspends,rdata->numpkinds,rdata->numexternaltxids,(long)rdata->allocsize,(long)iguana_ramchain_size(fname,RAMCHAIN_ARG,numblocks,scriptspace),after-before+sizeof(*rdata),scriptspace); } //printf("before.%ld after.%ld allocsize.%ld [%ld] %ld expanded.%d\n",before,after,(long)srcdata->allocsize,(long)ramchain->H.data->allocsize,(long)iguana_ramchain_size(ramchain),ramchain->expanded); return(after - before); } -int64_t iguana_ramchain_init(struct iguana_ramchain *ramchain,struct OS_memspace *mem,struct OS_memspace *hashmem,int32_t firsti,int32_t numtxids,int32_t numunspents,int32_t numspends,int32_t numpkinds,int32_t numexternaltxids,int32_t expanded,int32_t numblocks) +int64_t iguana_ramchain_init(char *fname,struct iguana_ramchain *ramchain,struct OS_memspace *mem,struct OS_memspace *hashmem,int32_t firsti,int32_t numtxids,int32_t numunspents,int32_t numspends,int32_t numpkinds,int32_t numexternaltxids,int32_t scriptspace,int32_t expanded,int32_t numblocks) { - RAMCHAIN_DECLARE; int64_t offset = 0; struct iguana_ramchaindata *rdata; - B = 0, Ux = 0, Sx = 0, P = 0, A = 0, X = 0, TXbits = 0, PKbits = 0, U = 0, S = 0, T = 0; //U2 = 0, P2 = 0, + RAMCHAIN_DECLARE; RAMCHAIN_ZEROES; int64_t offset = 0; struct iguana_ramchaindata *rdata; + //B = 0, Ux = 0, Sx = 0, P = 0, A = 0, X = 0, Kspace = TXbits = PKbits = 0, U = 0, S = 0, T = 0; if ( mem == 0 ) return(0); memset(ramchain,0,sizeof(*ramchain)); ramchain->expanded = (expanded != 0); if ( (ramchain->hashmem= hashmem) != 0 ) iguana_memreset(hashmem); - rdata = ramchain->H.data = mem->ptr, offset += sizeof(struct iguana_ramchaindata); + rdata = ramchain->H.data = mem->ptr;//, offset += sizeof(struct iguana_ramchaindata); if ( (rdata->firsti= firsti) != 0 ) { numtxids++, numunspents++, numspends++; @@ -828,104 +998,137 @@ int64_t iguana_ramchain_init(struct iguana_ramchain *ramchain,struct OS_memspace numexternaltxids = numspends; if ( numpkinds == 0 ) numpkinds = numunspents; + _iguana_rdata_action(fname,0,0,rdata,0,expanded,numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace,0,0,0,0,0,RAMCHAIN_ARG,numblocks); + offset += rdata->allocsize; if ( 0 && expanded != 0 ) printf("init T.%d U.%d S.%d P.%d X.%d -> %ld\n",numtxids,numunspents,numspends,numpkinds,numexternaltxids,(long)offset); - _iguana_rdata_action(0,0,rdata,0,expanded,numtxids,numunspents,numspends,numpkinds,numexternaltxids,0,0,0,0,0,RAMCHAIN_ARG,numblocks); - if ( rdata->allocsize != iguana_ramchain_size(RAMCHAIN_ARG,numblocks) ) + if ( rdata->allocsize != iguana_ramchain_size(fname,RAMCHAIN_ARG,numblocks,scriptspace) ) { - printf("offset.%ld vs memsize.%ld\n",(long)offset,(long)iguana_ramchain_size(RAMCHAIN_ARG,numblocks)); + printf("offset.%ld scriptspace.%d allocsize.%ld vs memsize.%ld\n",(long)offset,scriptspace,(long)rdata->allocsize,(long)iguana_ramchain_size(fname,RAMCHAIN_ARG,numblocks,scriptspace)); exit(-1); } - if ( offset < mem->totalsize ) + if ( offset <= mem->totalsize ) iguana_memreset(mem); else { - printf("offset.%ld vs memsize.%ld\n",(long)offset,(long)iguana_ramchain_size(RAMCHAIN_ARG,numblocks)); - printf("NEED %ld realloc for %ld\n",(long)offset,(long)mem->totalsize); - exit(-1); + printf("offset.%ld vs memsize.%ld\n",(long)offset,(long)mem->totalsize); + printf("NEED %ld realloc for totalsize %ld\n",(long)offset,(long)iguana_ramchain_size(fname,RAMCHAIN_ARG,numblocks,scriptspace)); + getchar(); + //exit(-1); iguana_mempurge(mem); iguana_meminit(mem,"ramchain",0,offset,0); } - //printf("init.(%d %d %d %d %d)\n",numtxids,numunspents,numspends,numpkinds,numexternaltxids); + if ( rdata->allocsize > mem->totalsize ) + { + printf("init.(%d %d %d %d %d) rdata->allocsize.%ld mem->totalsize.%ld hashmemsize.%ld\n",numtxids,numunspents,numspends,numpkinds,numexternaltxids,(long)rdata->allocsize,mem->totalsize,hashmem!=0?hashmem->totalsize:0); + exit(-1); + } return(offset); } -int32_t iguana_ramchain_alloc(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct OS_memspace *mem,struct OS_memspace *hashmem,uint32_t numtxids,uint32_t numunspents,uint32_t numspends,uint32_t numpkinds,uint32_t numexternaltxids,int32_t height,int32_t numblocks) +int32_t iguana_ramchain_alloc(char *fname,struct iguana_info *coin,struct iguana_ramchain *ramchain,struct OS_memspace *mem,struct OS_memspace *hashmem,uint32_t numtxids,uint32_t numunspents,uint32_t numspends,uint32_t numpkinds,uint32_t numexternaltxids,uint32_t scriptspace,int32_t height,int32_t numblocks) { - RAMCHAIN_DECLARE; int64_t hashsize,allocsize,x; - B = 0, Ux = 0, Sx = 0, P = 0, A = 0, X = 0, TXbits = 0, PKbits = 0, U = 0, S = 0, T = 0; //U2 = 0, P2 = 0, + RAMCHAIN_DECLARE; RAMCHAIN_ZEROES; int64_t hashsize,allocsize,x; + //B = 0, Ux = 0, Sx = 0, P = 0, A = 0, X = 0, Kspace = TXbits = PKbits = 0, U = 0, S = 0, T = 0; memset(ramchain,0,sizeof(*ramchain)); ramchain->height = height; - allocsize = _iguana_rdata_action(0,0,0,0,1,numtxids,numunspents,numspends,numpkinds,numexternaltxids,0,0,0,0,0,RAMCHAIN_ARG,numblocks); - //printf("T.%d U.%d S.%d P.%d X.%d -> %ld\n",numtxids,numunspents,numspends,numpkinds,numexternaltxids,(long)allocsize); + allocsize = _iguana_rdata_action(fname,0,0,0,0,1,numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace,0,0,0,0,0,RAMCHAIN_ARG,numblocks); + if ( 0 && ramchain->expanded != 0 ) + printf("T.%d U.%d S.%d P.%d X.%d -> %ld\n",numtxids,numunspents,numspends,numpkinds,numexternaltxids,(long)allocsize); memset(mem,0,sizeof(*mem)); memset(hashmem,0,sizeof(*hashmem)); - hashsize = iguana_hashmemsize(numtxids,numunspents,numspends,numpkinds,numexternaltxids); - while ( (x= (myallocated(0,-1)+hashsize+allocsize)) > coin->MAXMEM ) + hashsize = iguana_hashmemsize(numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace); + while ( 0 && (x= (myallocated(0,-1)+hashsize+allocsize + 65536)) > coin->MAXMEM ) { - char str[65],str2[65]; fprintf(stderr,"ht.%d wait for allocated %s < MAXMEM %s | elapsed %.2f minutes\n",height,mbstr(str,hashsize+allocsize),mbstr(str2,coin->MAXMEM),(double)(time(NULL)-coin->startutc)/60.); - sleep(3); + char str[65],str2[65]; fprintf(stderr,"ht.%d wait for allocated %s < MAXMEM %s | elapsed %.2f minutes hashsize.%ld allocsize.%ld\n",height,mbstr(str,myallocated(0,-1)+hashsize+allocsize),mbstr(str2,coin->MAXMEM),(double)(time(NULL)-coin->startutc)/60.,(long)hashsize,(long)allocsize); + sleep(13); } - iguana_meminit(hashmem,"ramhashmem",0,hashsize + 4096,0); - iguana_meminit(mem,"ramchain",0,allocsize + 4096,0); + iguana_meminit(hashmem,"ramhashmem",0,hashsize,0); + iguana_meminit(mem,"ramchain",0,allocsize + 65536,0); mem->alignflag = sizeof(uint32_t); hashmem->alignflag = sizeof(uint32_t); - if ( iguana_ramchain_init(ramchain,mem,hashmem,1,numtxids,numunspents,numspends,numpkinds,numexternaltxids,1,numblocks) == 0 ) + if ( iguana_ramchain_init(fname,ramchain,mem,hashmem,1,numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace,1,numblocks) == 0 ) return(-1); return(0); } long iguana_ramchain_save(struct iguana_info *coin,RAMCHAIN_FUNC,uint32_t ipbits,bits256 hash2,bits256 prevhash2,int32_t bundlei,struct iguana_bundle *bp) { - struct iguana_ramchaindata *rdata,tmp; - char fname[1024]; long fpos = -1; int32_t hdrsi,checki; FILE *fp; + struct iguana_ramchaindata *rdata,tmp; char fname[1024]; long fpos = -1; int32_t hdrsi,checki; FILE *fp; if ( (rdata= ramchain->H.data) == 0 ) { printf("ramchainsave no data ptr\n"); return(-1); } - if ( (checki= iguana_peerfname(coin,&hdrsi,ipbits==0?"DB":"tmp",fname,ipbits,hash2,prevhash2,ramchain->numblocks)) != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) + if ( (checki= iguana_peerfname(coin,&hdrsi,ipbits==0?GLOBAL_DBDIR:GLOBAL_TMPDIR,fname,ipbits,hash2,prevhash2,ramchain->numblocks,1)) != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) { printf(" wont save.(%s) bundlei.%d != checki.%d\n",fname,bundlei,checki); return(-1); } OS_compatible_path(fname); - if ( (fp= fopen(fname,"rb+")) == 0 ) + /*if ( (fp= fopen(fname,"rb+")) == 0 ) { if ( (fp= fopen(fname,"wb")) != 0 ) coin->peers.numfiles++; + else + { + printf("iguana_ramchain_save: couldnt create.(%s)\n",fname); + return(-1); + } } else if ( ipbits != 0 ) - fseek(fp,0,SEEK_END); + { + //fseek(fp,0,SEEK_END); + } else { fclose(fp); - fp = fopen(fname,"wb"); - } + if ( (fp= fopen(fname,"wb")) == 0 ) + { + printf("iguana_ramchain_save b: couldnt create.(%s)\n",fname); + return(-1); + } + }*/ +#ifdef __PNACL__ + static portable_mutex_t mutex; + portable_mutex_lock(&mutex); +#endif + if ( (fp= fopen(fname,"wb")) == 0 ) + printf("iguana_ramchain_save: couldnt create.(%s) errno.%d\n",fname,errno); + else coin->peers.numfiles++; if ( fp != 0 ) { fpos = ftell(fp); - iguana_ramchain_lhashes(RAMCHAIN_ARG,rdata,rdata,bp!=0?bp->n:1); + if ( ramchain->expanded != 0 ) + iguana_ramchain_lhashes(fname,RAMCHAIN_ARG,rdata,rdata,bp!=0?bp->n:1,ramchain->H.scriptoffset); tmp = *rdata; - iguana_ramchain_compact(RAMCHAIN_ARG,&tmp,rdata,bp!=0?bp->n:1); - fwrite(&tmp,1,sizeof(tmp),fp); - iguana_ramchain_saveaction(RAMCHAIN_ARG,fp,rdata,bp!=0?bp->n:1); + iguana_ramchain_compact(fname,RAMCHAIN_ARG,&tmp,rdata,bp!=0?bp->n:1); + if ( 0 && ramchain->expanded != 0 ) + printf("compact.%s: Koffset.%d scriptoffset.%d stacksize.%d allocsize.%d\n",fname,(int32_t)ramchain->H.data->Koffset,ramchain->H.scriptoffset,ramchain->H.stacksize,(int32_t)ramchain->H.data->allocsize); + if ( fwrite(&tmp,1,sizeof(tmp),fp) != sizeof(tmp) ) + { + printf("ramchain_save error writing header.%s\n",fname); + fpos = -1; + } else iguana_ramchain_saveaction(fname,RAMCHAIN_ARG,fp,rdata,bp!=0?bp->n:1,ramchain->H.scriptoffset); *rdata = tmp; fclose(fp); } - return(fpos); +#ifdef __PNACL__ + portable_mutex_unlock(&mutex); +#endif + return(fpos); } int32_t iguana_ramchain_verify(struct iguana_info *coin,struct iguana_ramchain *ramchain) { RAMCHAIN_DECLARE; struct iguana_txid *t; struct iguana_unspent *u; struct iguana_pkhash *p; struct iguana_ramchaindata *rdata; int32_t k,pkind,vout; struct iguana_kvitem *ptr; bits256 txid; - // iguana_txid { bits256 txid; uint32_t txidind,firstvout,firstvin; uint16_t numvouts,numvins;} if ( (rdata= ramchain->H.data) == 0 ) return(-100); _iguana_ramchain_setptrs(RAMCHAIN_PTRS,rdata); ramchain->pkind = ramchain->H.unspentind = ramchain->H.spendind = rdata->firsti; - ramchain->externalind = 0; + ramchain->externalind = ramchain->H.stacksize = 0; + ramchain->H.scriptoffset = 1; for (ramchain->H.txidind=rdata->firsti; ramchain->H.txidindnumtxids; ramchain->H.txidind++) { t = &T[ramchain->H.txidind]; @@ -937,7 +1140,7 @@ int32_t iguana_ramchain_verify(struct iguana_info *coin,struct iguana_ramchain * if ( t->firstvout != ramchain->H.unspentind ) { printf("%p txidind.%d firstvout.%d != unspentind.%d\n",t,ramchain->H.txidind,t->firstvout,ramchain->H.unspentind); - exit(-1); + //exit(-1); return(-4); } if ( t->firstvin != ramchain->H.spendind ) @@ -967,7 +1170,7 @@ int32_t iguana_ramchain_verify(struct iguana_info *coin,struct iguana_ramchain * else { char str[65]; printf("error -3: %s itemind.%d vs txidind.%d | num.%d\n",bits256_str(str,t->txid),ptr->hh.itemind,ramchain->H.txidind,ramchain->H.data->numtxids); - exit(-1); + //exit(-1); return(-3); } } @@ -977,7 +1180,7 @@ int32_t iguana_ramchain_verify(struct iguana_info *coin,struct iguana_ramchain * if ( u->txidind != ramchain->H.txidind ) { printf("ramchain_verify k.%d %p U.%d u->txidind.%x != txidind.%d\n",k,u,ramchain->H.unspentind,u->txidind,ramchain->H.txidind); - exit(-1); + //exit(-1); return(-6); } if ( (pkind= u->pkind) < 0 || pkind >= rdata->numpkinds ) @@ -988,9 +1191,9 @@ int32_t iguana_ramchain_verify(struct iguana_info *coin,struct iguana_ramchain * p = &P[pkind]; if ( (ptr= iguana_hashfind(ramchain,'P',p->rmd160)) == 0 ) return(-8); - if ( ptr->hh.itemind == pkind && p->firstunspentind > ramchain->H.unspentind ) + if ( ptr->hh.itemind != pkind )//&& p->firstunspentind > ramchain->H.unspentind ) { - printf("%p itemind.%d pkind.%d firstunspent.%d != %d unspentind?\n",p,ptr->hh.itemind,pkind,p->firstunspentind,ramchain->H.unspentind); + printf("%p itemind.%d pkind.%d %d unspentind?\n",p,ptr->hh.itemind,pkind,ramchain->H.unspentind); return(-9); } } @@ -1037,14 +1240,14 @@ int32_t iguana_ramchain_verify(struct iguana_info *coin,struct iguana_ramchain * } } } - if ( ramchain->expanded != 0 && ramchain->A != ramchain->roA ) + if ( ramchain->expanded != 0 && ramchain->A != ramchain->creditsA ) { for (k=rdata->firsti; knumpkinds; k++) { - if ( memcmp(&ramchain->A[k],&ramchain->roA[k],sizeof(ramchain->A[k])) != 0 ) + if ( memcmp(&ramchain->A[k],&ramchain->creditsA[k],sizeof(ramchain->A[k])) != 0 ) { - printf("k.%d balance.(%.8f vs %.8f) lastU.(%d %d)\n",k,dstr(ramchain->A[k].balance),dstr(ramchain->roA[k].balance),ramchain->A[k].lastunspentind,ramchain->roA[k].lastunspentind); - return(-14); + printf("k.%d balance.(%.8f vs %.8f) lastU.(%d %d)\n",k,dstr(ramchain->A[k].total),dstr(ramchain->creditsA[k].total),ramchain->A[k].lastunspentind,ramchain->creditsA[k].lastunspentind); + //return(-14); } //if ( memcmp(&ramchain->P2[k],&ramchain->roP2[k],sizeof(ramchain->P2[k])) != 0 ) // return(-15); @@ -1056,14 +1259,17 @@ int32_t iguana_ramchain_verify(struct iguana_info *coin,struct iguana_ramchain * return(0); } -int32_t iguana_ramchain_free(struct iguana_ramchain *ramchain,int32_t deleteflag) +int32_t iguana_ramchain_free(struct iguana_info *coin,struct iguana_ramchain *ramchain,int32_t deleteflag) { struct iguana_kvitem *item,*tmp; if ( ramchain->H.ROflag != 0 && ramchain->hashmem == 0 ) { - //printf("Free A %p %p, U2, P2\n",ramchain->A,ramchain->roA); - if ( ramchain->A != ramchain->roA ) - myfree(ramchain->A,sizeof(*ramchain->A) * ramchain->H.data->numpkinds), ramchain->A = 0; + if ( ramchain->A != ramchain->creditsA ) + { + //printf("hashmem.%p Free A %p %p, numpkinds.%d %ld\n",ramchain->hashmem,ramchain->A,ramchain->creditsA,ramchain->H.data->numpkinds,sizeof(*ramchain->A) * ramchain->H.data->numpkinds); + if ( deleteflag != 0 ) + myfree(ramchain->A,sizeof(*ramchain->A) * ramchain->H.data->numpkinds), ramchain->A = 0; + } //if ( ramchain->U2 != ramchain->roU2 ) // myfree(ramchain->U2,sizeof(*ramchain->U2) * ramchain->H.data->numunspents), ramchain->U2 = 0; //if ( ramchain->P2 != ramchain->roP2 ) @@ -1089,50 +1295,157 @@ int32_t iguana_ramchain_free(struct iguana_ramchain *ramchain,int32_t deleteflag myfree(item,sizeof(*item)); } } + if ( ramchain->txbits != 0 ) + { + free(ramchain->txbits); + ramchain->txbits = 0; + } + if ( ramchain->cacheT != 0 ) + { + free(ramchain->cacheT); + ramchain->cacheT = 0; + } } + ramchain->txids = 0; + ramchain->pkhashes = 0; if ( ramchain->hashmem != 0 ) - iguana_memreset(ramchain->hashmem); + iguana_mempurge(ramchain->hashmem), ramchain->hashmem = 0; if ( ramchain->filesize != 0 ) + { munmap(ramchain->fileptr,ramchain->filesize); - memset(ramchain,0,sizeof(*ramchain)); + ramchain->fileptr = 0; + ramchain->filesize = 0; + } + if ( ramchain->Xspendptr != 0 ) + { + munmap(ramchain->Xspendptr,ramchain->filesize); + ramchain->Xspendptr = 0; + ramchain->numXspends = 0; + ramchain->Xspendinds = 0; + } + //iguana_volatilespurge(coin,ramchain); + if ( deleteflag != 0 ) + memset(ramchain,0,sizeof(*ramchain)); return(0); } -void iguana_ramchain_extras(struct iguana_ramchain *ramchain,struct OS_memspace *hashmem) +int32_t iguana_bundleremove(struct iguana_info *coin,int32_t hdrsi,int32_t tmpfiles) { - RAMCHAIN_DECLARE; + struct iguana_bundle *bp; int32_t i; char fname[1024],str[65]; + if ( hdrsi >= 0 && hdrsi < coin->bundlescount && (bp= coin->bundles[hdrsi]) != 0 ) + { + printf("delete bundle.[%d]\n",hdrsi); + if ( tmpfiles != 0 ) + { + for (i=0; in; i++) + iguana_blockunmark(coin,bp->blocks[i],bp,i,1); + } + iguana_ramchain_free(coin,&bp->ramchain,0); + if ( iguana_bundlefname(coin,bp,fname) == 0 ) + OS_removefile(fname,0); + sprintf(fname,"%s/%s/spends/%s.%d",GLOBAL_DBDIR,coin->symbol,bits256_str(str,bp->hashes[0]),bp->bundleheight), OS_removefile(fname,0); + sprintf(fname,"%s/%s/accounts/debits.%d",GLOBAL_DBDIR,coin->symbol,bp->bundleheight), OS_removefile(fname,0); + sprintf(fname,"%s/%s/accounts/lastspends.%d",GLOBAL_DBDIR,coin->symbol,bp->bundleheight), OS_removefile(fname,0); + sprintf(fname,"%s/%s/validated/%d",GLOBAL_DBDIR,coin->symbol,bp->bundleheight), OS_removefile(fname,0); + bp->utxofinish = bp->startutxo = bp->balancefinish = bp->validated = bp->emitfinish = bp->converted = 0; + return(0); + } + return(-1); +} + +int32_t iguana_ramchain_extras(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct OS_memspace *hashmem,int32_t extraflag) +{ + RAMCHAIN_DECLARE; int32_t err=0; if ( ramchain->expanded != 0 ) { _iguana_ramchain_setptrs(RAMCHAIN_PTRS,ramchain->H.data); - if ( (ramchain->hashmem= hashmem) != 0 ) - iguana_memreset(hashmem); - ramchain->A = (hashmem != 0) ? iguana_memalloc(hashmem,sizeof(struct iguana_account) * ramchain->H.data->numpkinds,1) : mycalloc('p',ramchain->H.data->numpkinds,sizeof(struct iguana_account)); - //ramchain->P2 = (hashmem != 0) ? iguana_memalloc(hashmem,sizeof(struct iguana_pkextra) * ramchain->H.data->numpkinds,1) : mycalloc('2',ramchain->H.data->numpkinds,sizeof(struct iguana_pkextra)); - ///ramchain->U2 = (hashmem != 0) ? iguana_memalloc(hashmem,sizeof(struct iguana_Uextra) * ramchain->H.data->numunspents,1) : mycalloc('3',ramchain->H.data->numunspents,sizeof(struct iguana_Uextra)); - //printf("iguana_ramchain_extras A.%p:%p U2.%p:%p P2.%p:%p\n",ramchain->A,ramchain->roA,ramchain->U2,ramchain->roU2,ramchain->P2,ramchain->roP2); - //memcpy(ramchain->U2,ramchain->roU2,sizeof(*ramchain->U2) * ramchain->H.data->numunspents); - //memcpy(ramchain->P2,ramchain->roP2,sizeof(*ramchain->P2) * ramchain->H.data->numpkinds); + if ( extraflag == 0 && ramchain->H.data != 0 ) + { + if ( (ramchain->hashmem= hashmem) != 0 ) + iguana_memreset(hashmem); + else printf("alloc ramchain->A %d\n",(int32_t)(sizeof(struct iguana_account) * ramchain->H.data->numpkinds)); + ramchain->A = (hashmem != 0 && hashmem->ptr != 0) ? iguana_memalloc(hashmem,sizeof(struct iguana_account) * ramchain->H.data->numpkinds,1) : mycalloc('p',ramchain->H.data->numpkinds,sizeof(struct iguana_account)); + ramchain->Uextras = (hashmem != 0 && hashmem->ptr != 0) ? iguana_memalloc(hashmem,sizeof(*ramchain->Uextras) * ramchain->H.data->numunspents,1) : mycalloc('p',ramchain->H.data->numunspents,sizeof(*ramchain->Uextras)); + } else err = iguana_volatilesmap(coin,ramchain); } + return(err); } -struct iguana_ramchain *iguana_ramchain_map(struct iguana_info *coin,char *fname,struct iguana_bundle *bp,int32_t numblocks,struct iguana_ramchain *ramchain,struct OS_memspace *hashmem,uint32_t ipbits,bits256 hash2,bits256 prevhash2,int32_t bundlei,long fpos,int32_t allocextras,int32_t expanded) +int32_t iguana_Xspendmap(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct iguana_bundle *bp) { - RAMCHAIN_DECLARE; int32_t valid,i,checki,hdrsi; - char str[65],str2[65]; long filesize; void *ptr; struct iguana_block *block; - if ( ramchain->fileptr == 0 || ramchain->filesize <= 0 ) + int32_t iter; bits256 sha256; char str[65],fname[1024]; void *ptr; long filesize; + for (iter=0; iter<2; iter++) { - if ( (checki= iguana_peerfname(coin,&hdrsi,ipbits==0?"DB":"tmp",fname,ipbits,hash2,prevhash2,numblocks)) != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) + sprintf(fname,"%s/%s%s/spends/%s.%d",GLOBAL_DBDIR,iter==0?"ro/":"",coin->symbol,bits256_str(str,bp->hashes[0]),bp->bundleheight); + if ( (ptr= OS_mapfile(fname,&filesize,0)) != 0 ) { - printf("iguana_ramchain_map.(%s) illegal hdrsi.%d bundlei.%d %s\n",fname,hdrsi,bundlei,bits256_str(str,hash2)); + ramchain->Xspendinds = (void *)((long)ptr + sizeof(sha256)); + if ( bp->Xvalid == 0 ) + vcalc_sha256(0,sha256.bytes,(void *)ramchain->Xspendinds,(int32_t)(filesize - sizeof(sha256))); + ramchain->from_roX = (iter == 0); + if ( bp->Xvalid != 0 || memcmp(sha256.bytes,ptr,sizeof(sha256)) == 0 ) + { + ramchain->Xspendptr = ptr; + ramchain->numXspends = (int32_t)((filesize - sizeof(sha256)) / sizeof(*ramchain->Xspendinds)); + bp->startutxo = bp->utxofinish = (uint32_t)time(NULL); + if ( bp->Xvalid == 0 ) + { + printf("[%d] filesize %ld Xspendptr.%p %p num.%d\n",bp->hdrsi,filesize,ramchain->Xspendptr,ramchain->Xspendinds,ramchain->numXspends); + bp->Xvalid = 1; + } + return(ramchain->numXspends); + //int32_t i; for (i=0; inumXspends; i++) + // printf("(%d u%d) ",ramchain->Xspendinds[i].hdrsi,ramchain->Xspendinds[i].ind); + //printf("mapped utxo vector[%d] from (%s)\n",ramchain->numXspends,fname); + } + else + { + char str[65]; printf("hash cmp error.%d vs (%s)\n",memcmp(sha256.bytes,ptr,sizeof(sha256)),bits256_str(str,sha256)); + munmap(ptr,filesize); + ramchain->Xspendinds = 0; + } + } + } + return(ramchain->numXspends); +} + +struct iguana_ramchain *_iguana_ramchain_map(struct iguana_info *coin,char *fname,struct iguana_bundle *bp,int32_t numblocks,struct iguana_ramchain *ramchain,struct OS_memspace *hashmem,uint32_t ipbits,bits256 hash2,bits256 prevhash2,int32_t bundlei,long fpos,int32_t allocextras,int32_t expanded) +{ + RAMCHAIN_DECLARE; int32_t valid,iter,i,checki,hdrsi; + char str[65],str2[65],dirstr[64]; long filesize; void *ptr; struct iguana_block *block; + /*if ( ramchain->expanded != 0 && (ramchain->sigsfileptr == 0 || ramchain->sigsfilesize == 0) ) + { + sprintf(sigsfname,"sigs/%s/%s",coin->symbol,bits256_str(str,hash2)); + if ( (ramchain->sigsfileptr= OS_mapfile(sigsfname,&ramchain->sigsfilesize,0)) == 0 ) + { + printf("couldnt map.(%s)\n",sigsfname); return(0); } - memset(ramchain,0,sizeof(*ramchain)); - if ( (ptr= OS_mapfile(fname,&filesize,0)) == 0 ) + }*/ + if ( ramchain->fileptr == 0 || ramchain->filesize <= 0 ) + { + for (iter=0; iter<2; iter++) + { + strcpy(dirstr,GLOBAL_DBDIR); + if ( iter == 0 ) + strcat(dirstr,"/ro"); + if ( (checki= iguana_peerfname(coin,&hdrsi,ipbits==0?dirstr:GLOBAL_TMPDIR,fname,ipbits,hash2,prevhash2,numblocks,1)) != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) + { + printf("iguana_ramchain_map.(%s) illegal hdrsi.%d bundlei.%d %s\n",fname,hdrsi,bundlei,bits256_str(str,hash2)); + continue; + } + memset(ramchain,0,sizeof(*ramchain)); + if ( (ptr= OS_mapfile(fname,&filesize,0)) == 0 ) + continue; + ramchain->from_ro = (iter == 0); + ramchain->fileptr = ptr; + ramchain->filesize = (long)filesize; + if ( (ramchain->hashmem= hashmem) != 0 ) + iguana_memreset(hashmem); + break; + } + if ( ramchain->fileptr == 0 ) return(0); - ramchain->fileptr = ptr; - ramchain->filesize = (long)filesize; - if ( (ramchain->hashmem= hashmem) != 0 ) - iguana_memreset(hashmem); } if ( ramchain->fileptr != 0 && ramchain->filesize > 0 ) { @@ -1141,7 +1454,7 @@ struct iguana_ramchain *iguana_ramchain_map(struct iguana_info *coin,char *fname ramchain->H.ROflag = 1; ramchain->expanded = expanded; ramchain->numblocks = (bp == 0) ? 1 : bp->n; - //printf("ptr.%p %p mapped P[%d] fpos.%d + %ld -> %ld vs %ld\n",ptr,ramchain->H.data,(int32_t)ramchain->H.data->Poffset,(int32_t)fpos,(long)ramchain->H.data->allocsize,(long)(fpos + ramchain->H.data->allocsize),ramchain->filesize); + //printf("ptr.%p exp.%d extra.%d %p mapped P[%d] fpos.%d + %ld -> %ld vs %ld offset.%u:%u stack.%u:%u\n",ptr,expanded,allocextras,ramchain->H.data,(int32_t)ramchain->H.data->Poffset,(int32_t)fpos,(long)ramchain->H.data->allocsize,(long)(fpos + ramchain->H.data->allocsize),ramchain->filesize,ramchain->H.scriptoffset,ramchain->H.data->scriptspace,ramchain->H.stacksize,ramchain->H.data->stackspace); if ( 0 && bp != 0 ) { /*blocksRO = (struct iguana_blockRO *)ramchain->H.data; @@ -1157,8 +1470,8 @@ struct iguana_ramchain *iguana_ramchain_map(struct iguana_info *coin,char *fname bp->blocks[i]->RO = blocksRO[i]; } ramchain->H.data = (void *)&blocksRO[bp->n];*/ - for (valid=0,i=bp->n=1; i>=0; i--) - { + for (valid=0,i=bp->n-1; i>=0; i--) + { if ( (block= bp->blocks[i]) != 0 ) { if ( memcmp(block->RO.hash2.bytes,bp->hashes[i].bytes,sizeof(block->RO.hash2)) == 0 ) @@ -1175,11 +1488,12 @@ struct iguana_ramchain *iguana_ramchain_map(struct iguana_info *coin,char *fname } } _iguana_ramchain_setptrs(RAMCHAIN_PTRS,ramchain->H.data); - if ( iguana_ramchain_size(RAMCHAIN_ARG,ramchain->numblocks) != ramchain->H.data->allocsize || fpos+ramchain->H.data->allocsize > filesize ) + if ( iguana_ramchain_size(fname,RAMCHAIN_ARG,ramchain->numblocks,ramchain->H.data->scriptspace) != ramchain->H.data->allocsize || fpos+ramchain->H.data->allocsize > filesize ) { - printf("iguana_ramchain_map.(%s) size mismatch %ld vs %ld vs filesize.%ld numblocks.%d expanded.%d fpos.%d sum %ld\n",fname,(long)iguana_ramchain_size(RAMCHAIN_ARG,ramchain->numblocks),(long)ramchain->H.data->allocsize,(long)filesize,ramchain->numblocks,expanded,(int32_t)fpos,(long)(fpos+ramchain->H.data->allocsize)); - exit(-1); - //munmap(ramchain->fileptr,ramchain->filesize); + printf("iguana_ramchain_map.(%s) size mismatch %ld vs %ld vs filesize.%ld numblocks.%d expanded.%d fpos.%d sum %ld\n",fname,(long)iguana_ramchain_size(fname,RAMCHAIN_ARG,ramchain->numblocks,ramchain->H.data->scriptspace),(long)ramchain->H.data->allocsize,(long)filesize,ramchain->numblocks,expanded,(int32_t)fpos,(long)(fpos+ramchain->H.data->allocsize)); + //exit(-1); + munmap(ramchain->fileptr,ramchain->filesize); + OS_removefile(fname,0); return(0); } else if ( memcmp(hash2.bytes,ramchain->H.data->firsthash2.bytes,sizeof(bits256)) != 0 ) @@ -1191,33 +1505,58 @@ struct iguana_ramchain *iguana_ramchain_map(struct iguana_info *coin,char *fname else if ( ramchain->expanded != 0 ) { if ( allocextras > 0 ) - iguana_ramchain_extras(ramchain,ramchain->hashmem); + { + ramchain->height = ramchain->H.data->height; + if ( iguana_ramchain_extras(coin,ramchain,ramchain->hashmem,allocextras) == 0 && bp != 0 ) + { + bp->balancefinish = (uint32_t)time(NULL); + //printf("found balances for %d\n",bp->hdrsi); + } //else printf("error with extras\n"); + } } - if ( B != 0 ) + if ( B != 0 && bp != 0 ) { for (i=0; in; i++) { - if ( (bp->blocks[i]= iguana_blockhashset(coin,-1,B[i].hash2,1)) == 0 ) + if ( bp->blocks[i] == 0 && (bp->blocks[i]= iguana_blockhashset("mapchain",coin,-1,B[i].hash2,1)) == 0 ) { printf("Error getting blockptr\n"); return(0); } bp->blocks[i]->RO = B[i];//coin->blocks.RO[bp->bundleheight + i]; coin->blocks.RO[bp->bundleheight+i] = B[i]; + bp->hashes[i] = B[i].hash2; } - } + //printf("iguana_ramchain_map.(%s) size %ld vs %ld vs filesize.%ld numblocks.%d expanded.%d fpos.%d sum %ld\n",fname,(long)iguana_ramchain_size(RAMCHAIN_ARG,ramchain->numblocks,ramchain->H.data->scriptspace),(long)ramchain->H.data->allocsize,(long)filesize,ramchain->numblocks,expanded,(int32_t)fpos,(long)(fpos+ramchain->H.data->allocsize)); + bp->Xvalid = 1; + iguana_Xspendmap(coin,ramchain,bp); return(ramchain); } else printf("iguana_ramchain_map.(%s) cant map file\n",fname); return(0); } -void iguana_ramchain_link(struct iguana_ramchain *ramchain,bits256 firsthash2,bits256 lasthash2,int32_t hdrsi,int32_t height,int32_t bundlei,int32_t numblocks,int32_t firsti,int32_t ROflag) +struct iguana_ramchain *iguana_ramchain_map(struct iguana_info *coin,char *fname,struct iguana_bundle *bp,int32_t numblocks,struct iguana_ramchain *ramchain,struct OS_memspace *hashmem,uint32_t ipbits,bits256 hash2,bits256 prevhash2,int32_t bundlei,long fpos,int32_t allocextras,int32_t expanded) +{ + struct iguana_ramchain *retptr; +#ifdef __PNACL__ + static portable_mutex_t mutex; + portable_mutex_lock(&mutex); +#endif + ramchain->height = bp->bundleheight; + retptr = _iguana_ramchain_map(coin,fname,bp,numblocks,ramchain,hashmem,ipbits,hash2,prevhash2,bundlei,fpos,allocextras,expanded); +#ifdef __PNACL__ + portable_mutex_unlock(&mutex); +#endif + return(retptr); +} + +void iguana_ramchain_link(struct iguana_ramchain *ramchain,bits256 firsthash2,int32_t hdrsi,int32_t height,int32_t bundlei,int32_t numblocks,int32_t firsti,int32_t ROflag) { if ( ROflag == 0 ) { ramchain->H.data->firsthash2 = firsthash2; - ramchain->H.data->lasthash2 = lasthash2; + //ramchain->H.data->lasthash2 = lasthash2; ramchain->H.data->hdrsi = hdrsi; ramchain->H.data->height = height; ramchain->H.data->numblocks = numblocks; @@ -1226,9 +1565,9 @@ void iguana_ramchain_link(struct iguana_ramchain *ramchain,bits256 firsthash2,bi ramchain->H.bundlei = bundlei; ramchain->height = height; ramchain->numblocks = numblocks; - ramchain->lasthash2 = lasthash2; + //ramchain->lasthash2 = lasthash2; ramchain->H.txidind = ramchain->H.unspentind = ramchain->H.spendind = ramchain->pkind = firsti; - ramchain->externalind = 0; + ramchain->externalind = 0;//ramchain->H.scriptoffset = ramchain->H.stacksize = 0; } int32_t iguana_ramchain_cmp(struct iguana_ramchain *A,struct iguana_ramchain *B,int32_t deepflag) @@ -1237,29 +1576,36 @@ int32_t iguana_ramchain_cmp(struct iguana_ramchain *A,struct iguana_ramchain *B, struct iguana_txid *Ta,*Tb; struct iguana_unspent20 *Ua,*Ub; struct iguana_spend256 *Sa,*Sb; struct iguana_pkhash *Pa,*Pb; bits256 *Xa,*Xb; struct iguana_blockRO *Ba,*Bb; struct iguana_account *ACCTa,*ACCTb; struct iguana_unspent *Uxa,*Uxb; - struct iguana_spend *Sxa,*Sxb; uint8_t *TXbitsa,*TXbitsb,*PKbitsa,*PKbitsb; + struct iguana_spend *Sxa,*Sxb; uint8_t *TXbitsa,*TXbitsb,*PKbitsa,*PKbitsb,*Kspacea,*Kspaceb; if ( A->H.data != 0 && B->H.data != 0 && A->H.data->numblocks == B->H.data->numblocks && memcmp(A->H.data->firsthash2.bytes,B->H.data->firsthash2.bytes,sizeof(A->H.data->firsthash2)) == 0 ) { if ( A->H.data->firsti == B->H.data->firsti && A->H.data->numtxids == B->H.data->numtxids && A->H.data->numunspents == B->H.data->numunspents && A->H.data->numspends == B->H.data->numspends && A->H.data->numpkinds == B->H.data->numpkinds && A->H.data->numexternaltxids == B->H.data->numexternaltxids ) { - _iguana_ramchain_setptrs(A,&Ba,&Ta,&Ua,&Sa,&Pa,&ACCTa,&Xa,&Uxa,&Sxa,&TXbitsa,&PKbitsa,A->H.data); - _iguana_ramchain_setptrs(B,&Bb,&Tb,&Ub,&Sb,&Pb,&ACCTb,&Xb,&Uxb,&Sxb,&TXbitsb,&PKbitsb,B->H.data); + _iguana_ramchain_setptrs(A,&Ba,&Ta,&Ua,&Sa,&Pa,&ACCTa,&Xa,&Uxa,&Sxa,&TXbitsa,&PKbitsa,&Kspacea,A->H.data); + _iguana_ramchain_setptrs(B,&Bb,&Tb,&Ub,&Sb,&Pb,&ACCTb,&Xb,&Uxb,&Sxb,&TXbitsb,&PKbitsb,&Kspaceb,B->H.data); for (i=A->H.data->firsti; iH.data->numtxids; i++) if ( memcmp(&Ta[i],&Tb[i],sizeof(Ta[i])) != 0 ) return(-2); - if ( A->numblocks > 1 ) + if ( A->numblocks > 0 ) { + if ( A->expanded != 0 ) + { for (i=A->H.data->firsti; iH.data->numspends; i++) if ( memcmp(&Sxa[i],&Sxb[i],sizeof(Sxa[i])) != 0 ) return(-3); - for (i=A->H.data->firsti; iH.data->numunspents; i++) - { + /*for (i=A->H.data->firsti; iH.data->numunspents; i++) + {break; + int32_t j,metalen,checklen; uint8_t _script[8129],*checkscript; if ( memcmp(&Uxa[i],&Uxb[i],sizeof(Uxa[i])) != 0 ) return(-4); + checkscript = iguana_ramchain_scriptdecode(&metalen,&checklen,Kspacea,Uxa[i].type,_script,Uxa[i].scriptoffset,0); + for (j=0; jH.data->firsti; iH.data->numpkinds; i++) { //if ( memcmp(&P2a[i],&P2b[i],sizeof(P2a[i])) != 0 ) @@ -1275,15 +1621,29 @@ int32_t iguana_ramchain_cmp(struct iguana_ramchain *A,struct iguana_ramchain *B, printf("X[%d] A.%s B.%s\n",i,str,str2); return(-8); } + } + else + { + for (i=A->H.data->firsti; iH.data->numspends; i++) + if ( memcmp(&Sa[i],&Sb[i],sizeof(Sa[i])) != 0 ) + return(-9); + for (i=A->H.data->firsti; iH.data->numunspents; i++) + if ( memcmp(&Ua[i],&Ub[i],sizeof(Ua[i])) != 0 ) + return(-10); + /*for (i=A->H.data->firsti; iH.data->numunspents; i++) + {break; + int32_t j,metalen,checklen; uint8_t _script[8129],*checkscript; + checkscript = iguana_ramchain_scriptdecode(&metalen,&checklen,Kspacea,Ua[i].type,_script,Ua[i].scriptoffset,0); + for (j=0; jH.data->firsti; iH.data->numspends; i++) - if ( memcmp(&Sa[i],&Sb[i],sizeof(Sa[i])) != 0 ) - return(-9); - for (i=A->H.data->firsti; iH.data->numunspents; i++) - if ( memcmp(&Ua[i],&Ub[i],sizeof(Ua[i])) != 0 ) - return(-10); } } return(0); @@ -1292,23 +1652,27 @@ int32_t iguana_ramchain_cmp(struct iguana_ramchain *A,struct iguana_ramchain *B, return(-1); } -int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain *dest,struct iguana_ramchain *ramchain) +int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain *dest,struct iguana_ramchain *ramchain,struct iguana_bundle *bp,int16_t bundlei) { RAMCHAIN_DECLARE; RAMCHAIN_DESTDECLARE; - int32_t j,hdrsi,prevout; uint32_t sequence,destspendind=0,desttxidind=0; - bits256 prevhash; uint64_t value; uint8_t type; - struct iguana_txid *tx; struct iguana_ramchaindata *rdata; uint8_t *rmd160; struct iguana_unspent *u; - if ( dest != 0 ) - _iguana_ramchain_setptrs(RAMCHAIN_DESTPTRS,dest->H.data); - _iguana_ramchain_setptrs(RAMCHAIN_PTRS,ramchain->H.data); + int32_t j,hdrsi,prevout,scriptlen; uint32_t sequenceid,destspendind=0,desttxidind=0; uint16_t fileid; uint64_t scriptpos; + bits256 prevhash; uint64_t value; uint8_t type; struct iguana_unspent *u; + struct iguana_txid *tx; struct iguana_ramchaindata *rdata; uint8_t rmd160[20]; + //if ( dest != 0 ) + // printf("iterate ramchain.%p rdata.%p dest.%p ht.%d/%d txids.%p destoffset.%d\n",ramchain,ramchain->H.data,dest,bp->bundleheight,bp->n,ramchain->txids,dest->H.scriptoffset); if ( (rdata= ramchain->H.data) == 0 ) { printf("iguana_ramchain_iterate cant iterate without data\n"); return(-1); } + if ( dest != 0 ) + _iguana_ramchain_setptrs(RAMCHAIN_DESTPTRS,dest->H.data); + //fprintf(stderr,"iterate %d/%d dest.%p ramchain.%p rdata.%p\n",bp->bundleheight,bp->n,dest,ramchain,rdata); + _iguana_ramchain_setptrs(RAMCHAIN_PTRS,ramchain->H.data); ramchain->H.ROflag = 1; ramchain->H.unspentind = ramchain->H.spendind = ramchain->pkind = rdata->firsti; - ramchain->externalind = 0; + ramchain->externalind = ramchain->H.stacksize = 0; + ramchain->H.scriptoffset = 1; if ( dest != 0 ) { desttxidind = dest->H.txidind; @@ -1316,23 +1680,30 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain } for (ramchain->H.txidind=rdata->firsti; ramchain->H.txidindnumtxids; ramchain->H.txidind++) { - if ( 0 && ramchain->expanded != 0 ) - printf("ITER TXID.%d -> dest.%p desttxid.%d dest->hashmem.%p\n",ramchain->H.txidind,dest,dest!=0?dest->H.txidind:0,dest!=0?dest->hashmem:0); + if ( coin->active == 0 ) + return(-1);; + if ( 0 && ramchain->expanded == 0 && dest != 0 ) + printf("ITER [%d] TXID.%d -> dest.%p desttxid.%d dest->hashmem.%p numtxids.%d\n",ramchain->H.data->height,ramchain->H.txidind,dest,dest!=0?dest->H.txidind:0,dest!=0?dest->hashmem:0,rdata->numtxids); tx = &T[ramchain->H.txidind]; - if ( iguana_ramchain_addtxid(coin,RAMCHAIN_ARG,tx->txid,tx->numvouts,tx->numvins,tx->locktime,tx->version,tx->timestamp) == 0 ) + if ( iguana_ramchain_addtxid(coin,RAMCHAIN_ARG,tx->txid,tx->numvouts,tx->numvins,tx->locktime,tx->version,tx->timestamp,bundlei) == 0 ) return(-1); + //printf("txidind.%u firstvout.%u firstvin.%u bundlei.%d n.%d\n",tx->txidind,tx->firstvout,tx->firstvin,bundlei,bp->n); if ( dest != 0 ) { - char str[65]; - if ( 0 && ramchain->expanded != 0 ) - printf("add hdrsi.%d dest.%p txidind.%d %s\n",dest->H.hdrsi,ramchain,dest->H.txidind,bits256_str(str,tx->txid)); - if ( iguana_ramchain_addtxid(coin,RAMCHAIN_DESTARG,tx->txid,tx->numvouts,tx->numvins,tx->locktime,tx->version,tx->timestamp) == 0 ) + //char str[65]; + if ( 0 && ramchain->expanded == 0 ) + printf("ITER [%d] TXID.%d -> dest.%p desttxid.%d dest->hashmem.%p numtxids.%d\n",ramchain->H.data->height,ramchain->H.txidind,dest,dest!=0?dest->H.txidind:0,dest!=0?dest->hashmem:0,rdata->numtxids); + if ( iguana_ramchain_addtxid(coin,RAMCHAIN_DESTARG,tx->txid,tx->numvouts,tx->numvins,tx->locktime,tx->version,tx->timestamp,bundlei) == 0 ) return(-2); } for (j=0; jnumvouts; j++) { - if ( 0 && ramchain->expanded != 0 ) - printf("unspentind.%d pkind.%d Ux.%p\n",ramchain->H.unspentind,Ux[ramchain->H.unspentind].pkind,Ux); + if ( coin->active == 0 ) + return(-1); + fileid = 0; + scriptpos = 0; + scriptlen = 0; + memset(rmd160,0,sizeof(rmd160)); if ( ramchain->H.unspentind < rdata->numunspents ) { if ( ramchain->expanded != 0 ) @@ -1341,10 +1712,20 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain value = u->value; hdrsi = u->hdrsi; type = u->type; + fileid = u->fileid; + scriptpos = u->scriptpos; + scriptlen = u->scriptlen; if ( u->pkind < rdata->numpkinds ) { - rmd160 = P[u->pkind].rmd160; - if ( iguana_ramchain_addunspent(coin,RAMCHAIN_ARG,value,hdrsi,rmd160,j,type) == 0 ) + memcpy(rmd160,P[u->pkind].rmd160,20); + //printf("EXPANDED scriptpos.%u scriptlen.%d type.%d %.8f\n",(uint32_t)scriptpos,scriptlen,type,dstr(value)); + /*scriptlen = 0; + if ( u->scriptoffset != 0 || type == IGUANA_SCRIPT_76AC ) + { + scriptdata = iguana_ramchain_scriptdecode(&metalen,&scriptlen,Kspace,type,_script,u->scriptoffset,P[u->pkind].pubkeyoffset < ramchain->H.scriptoffset ? P[u->pkind].pubkeyoffset : 0); + }*/ + //fprintf(stderr,"iter add %p[%d] type.%d\n",scriptdata,scriptlen,type); + if ( iguana_ramchain_addunspent(coin,RAMCHAIN_ARG,value,hdrsi,rmd160,j,type,fileid,(uint32_t)scriptpos,scriptlen,ramchain->H.txidind-rdata->firsti) == 0 ) return(-3); } } @@ -1352,16 +1733,37 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain { hdrsi = rdata->hdrsi; value = U[ramchain->H.unspentind].value; - rmd160 = U[ramchain->H.unspentind].rmd160; - type = U[ramchain->H.unspentind].type; - if ( iguana_ramchain_addunspent20(coin,RAMCHAIN_ARG,value,rmd160,-20,tx->txid,j,type) == 0 ) + memcpy(rmd160,U[ramchain->H.unspentind].rmd160,20); + type = U[ramchain->H.unspentind].type & 0xf; + fileid = U[ramchain->H.unspentind].fileid; + scriptpos = U[ramchain->H.unspentind].scriptpos; + scriptlen = U[ramchain->H.unspentind].scriptlen; + //printf("scriptpos.%u scriptlen.%d type.%d %.8f\n",(uint32_t)scriptpos,scriptlen,type,dstr(value)); + /*if ( U[ramchain->H.unspentind].scriptoffset != 0 ) + { + scriptdata = &Kspace[U[ramchain->H.unspentind].scriptoffset]; + scriptlen = U[ramchain->H.unspentind].scriptlen; + } + if ( 0 && scriptdata != 0 && scriptlen > 0 ) + { + int32_t i; for (i=0; iH.unspentind,U[ramchain->H.unspentind].scriptoffset); + } //else printf("no script\n");*/ + if ( iguana_ramchain_addunspent20(coin,0,RAMCHAIN_ARG,value,0,scriptlen,tx->txid,j,type,bp,rmd160) == 0 ) return(-4); + if ( 0 ) + { + int32_t i; for (i=0; i<20; i++) + printf("%02x",rmd160[i]); + char str[65]; printf(" raw rmd160 txid.(%s) txidind.%u j.%d\n",bits256_str(str,tx->txid),ramchain->H.txidind,j); + } } if ( dest != 0 ) { - if ( iguana_ramchain_addunspent(coin,RAMCHAIN_DESTARG,value,hdrsi,rmd160,j,type) == 0 ) + if ( iguana_ramchain_addunspent(coin,RAMCHAIN_DESTARG,value,hdrsi,rmd160,j,type,fileid,(uint32_t)scriptpos,scriptlen,ramchain->H.txidind-rdata->firsti) == 0 ) return(-5); - } + } //else printf("addunspent20 done\n"); } else return(-6); } ramchain->H.spendind += tx->numvins; @@ -1369,32 +1771,40 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain { dest->H.txidind++; dest->H.spendind += tx->numvins; - } + } //else printf("iter scriptoffset.%u/%u stacksize.%u/%u\n",ramchain->H.scriptoffset,ramchain->H.data->scriptspace,ramchain->H.stacksize,ramchain->H.data->stackspace); } if ( dest != 0 ) { dest->H.txidind = desttxidind; dest->H.spendind = destspendind; - } + } //else printf("Start VINs\n"); ramchain->H.txidind = ramchain->H.spendind = rdata->firsti; for (ramchain->H.txidind=rdata->firsti; ramchain->H.txidindnumtxids; ramchain->H.txidind++) { tx = &T[ramchain->H.txidind]; for (j=0; jnumvins; j++) { + if ( coin->active == 0 ) + return(-1); + fileid = 0; + scriptpos = 0; + scriptlen = 0; if ( ramchain->expanded != 0 ) { - sequence = (Sx[ramchain->H.spendind].diffsequence == 0) ? 0xffffffff : 0; + fileid = Sx[ramchain->H.spendind].fileid; + scriptpos = Sx[ramchain->H.spendind].scriptpos; + scriptlen = Sx[ramchain->H.spendind].scriptlen; + //scriptlen = iguana_vinscriptdecode(coin,ramchain,&metalen,_script,&Kspace[ramchain->H.data->scriptspace],Kspace,&Sx[ramchain->H.spendind]); + //scriptdata = _script; prevout = iguana_ramchain_txid(coin,RAMCHAIN_ARG,&prevhash,&Sx[ramchain->H.spendind]); - //bundlei = Sx[ramchain->H.spendind].bundlei; - //hdrsi = Sx[ramchain->H.spendind].hdrsi; - if ( iguana_ramchain_addspend(coin,RAMCHAIN_ARG,prevhash,prevout,sequence) == 0 ) + //fprintf(stderr,"from expanded iter\n"); + if ( iguana_ramchain_addspend(coin,RAMCHAIN_ARG,prevhash,prevout,Sx[ramchain->H.spendind].sequenceid,bp->hdrsi,fileid,scriptpos,scriptlen) == 0 ) { - char str[65]; int32_t i; - printf("txidind.%d spendind.%d spendtxid.%x %d vin.%d %s vout.%d\n",ramchain->H.txidind,ramchain->H.spendind,Sx[ramchain->H.spendind].spendtxidind,Sx[ramchain->H.spendind].spendtxidind&0xfffffff,j,bits256_str(str,prevhash),prevout); - for (i=0; iH.data->numexternaltxids; i++) - printf("%p X[%d] %s\n",X,i,bits256_str(str,X[i])); - exit(-1); + char str[65]; + printf("hdrsi.%d txidind.%d spendind.%d spendtxid.%x %d vin.%d %s vout.%d\n",bp->bundleheight,ramchain->H.txidind,ramchain->H.spendind,Sx[ramchain->H.spendind].spendtxidind,Sx[ramchain->H.spendind].spendtxidind&0xfffffff,j,bits256_str(str,prevhash),prevout); + //for (i=0; iH.data->numexternaltxids; i++) + // printf("%p X[%d] %s\n",X,i,bits256_str(str,X[i])); + //exit(-1); iguana_ramchain_txid(coin,RAMCHAIN_ARG,&prevhash,&Sx[ramchain->H.spendind]); return(-7); } @@ -1402,18 +1812,31 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain else { //spendind = (tx->firstvin + j); - sequence = (S[ramchain->H.spendind].diffsequence == 0) ? 0xffffffff : 0; + sequenceid = S[ramchain->H.spendind].sequenceid; prevhash = S[ramchain->H.spendind].prevhash2; prevout = S[ramchain->H.spendind].prevout; - //bundlei = S[ramchain->H.spendind].bundlei; - //hdrsi = S[ramchain->H.spendind].hdrsi; - if ( iguana_ramchain_addspend256(coin,RAMCHAIN_ARG,prevhash,prevout,0,0,sequence) == 0 ) + fileid = S[ramchain->H.spendind].fileid; + scriptpos = S[ramchain->H.spendind].scriptpos; + scriptlen = S[ramchain->H.spendind].vinscriptlen; + /*if ( S[ramchain->H.spendind].scriptoffset != 0 ) + { + scriptdata = &Kspace[S[ramchain->H.spendind].scriptoffset]; + scriptlen = S[ramchain->H.spendind].vinscriptlen; + }*/ + /*if ( scriptdata != 0 && scriptlen > 0 ) + { + int32_t i; for (i=0; iH.spendind); + }*/ + if ( iguana_ramchain_addspend256(coin,0,RAMCHAIN_ARG,prevhash,prevout,0,scriptlen,sequenceid,bp) == 0 ) return(-8); } if ( dest != 0 ) { - if ( iguana_ramchain_addspend(coin,RAMCHAIN_DESTARG,prevhash,prevout,sequence) == 0 ) + if ( iguana_ramchain_addspend(coin,RAMCHAIN_DESTARG,prevhash,prevout,sequenceid,bp->hdrsi,fileid,scriptpos,scriptlen) == 0 ) return(-9); + //printf("from dest iter scriptspace.%d\n",dest->H.stacksize); } } if ( dest != 0 ) @@ -1424,132 +1847,224 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain long iguana_ramchain_data(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_txblock *origtxdata,struct iguana_msgtx *txarray,int32_t txn_count,uint8_t *data,int32_t recvlen) { + static uint64_t totalrecv; int32_t verifyflag = 0; - RAMCHAIN_DECLARE; long fsize; void *ptr; struct iguana_ramchain R,*mapchain,*ramchain = &addr->ramchain; - struct iguana_msgtx *tx; int32_t i,j,fpos,firsti=1,err,flag,bundlei = -2; char fname[1024]; - struct iguana_bundle *bp = 0; struct iguana_block *block; + RAMCHAIN_DECLARE; uint32_t addr_ipbits; struct iguana_ramchain R,*mapchain,*ramchain = &addr->ramchain; + struct iguana_msgtx *tx; char fname[1024]; uint8_t rmd160[20]; // long fsize; void *ptr; + int32_t i,j,fpos,pubkeysize,msize,sigsize,subdir,firsti=1,err,flag,bundlei = -2; bits256 merkle_root; + struct iguana_bundle *bp = 0; struct iguana_block *block; uint32_t scriptspace,stackspace; + totalrecv += recvlen; +#ifdef __PNACL__ + //verifyflag = 1; +#endif + if ( (addr_ipbits= (uint32_t)addr->ipbits) == 0 ) + addr_ipbits = 1; + if ( bits256_nonz(origtxdata->block.RO.merkle_root) == 0 ) + { + memset(&origtxdata->block.RO.prev_block,0,sizeof(bits256)); + origtxdata->block.RO.recvlen = 0; + origtxdata->block.issued = 0; + return(-1); + } + for (i=0; idirty)/sizeof(*addr->dirty); i++) + addr->dirty[i] = 0; + msize = (int32_t)sizeof(bits256) * (txn_count+1) * 2; + if ( msize <= addr->TXDATA.totalsize ) + { + bits256 *tree = addr->TXDATA.ptr; + iguana_memreset(&addr->TXDATA); + for (i=0; iblock.RO.merkle_root) != 0 ) + { + char str[65],str2[65]; + printf(">>>>>>>>>> merkle mismatch.[%d] calc.(%s) vs (%s)\n",txn_count,bits256_str(str,merkle_root),bits256_str(str2,origtxdata->block.RO.merkle_root)); + origtxdata->block.RO.recvlen = 0; + origtxdata->block.issued = 0; + return(-1); + } //else printf("matched merkle.%d\n",txn_count); + } else printf("not enough memory for merkle verify %d vs %lu\n",(int32_t)(sizeof(bits256)*(txn_count+1)),(long)addr->TXDATA.totalsize); + bp = 0, bundlei = -2; if ( iguana_bundlefind(coin,&bp,&bundlei,origtxdata->block.RO.hash2) == 0 ) { + bp = 0, bundlei = -2; if ( iguana_bundlefind(coin,&bp,&bundlei,origtxdata->block.RO.prev_block) == 0 ) + { + origtxdata->block.RO.recvlen = 0; + origtxdata->block.issued = 0; return(-1); + } else if ( bundlei < coin->chain->bundlesize-1 ) bundlei++; else { - printf("error finding block\n"); + origtxdata->block.issued = 0; + origtxdata->block.RO.recvlen = 0; + char str[65]; printf("ramchain data: error finding block %s\n",bits256_str(str,origtxdata->block.RO.hash2)); return(-1); } } - if ( bits256_nonz(bp->hashes[bundlei]) == 0 ) - bp->hashes[bundlei] = origtxdata->block.RO.hash2; - if ( (block= bp->blocks[bundlei]) == 0 ) + if ( (block= bp->blocks[bundlei]) == 0 || bits256_cmp(block->RO.hash2,origtxdata->block.RO.hash2) != 0 || bits256_cmp(bp->hashes[bundlei],origtxdata->block.RO.hash2) != 0 ) { - //char str[65]; printf("%d:%d has no block ptr %s\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei])); + char str[65]; + if ( 0 && block != 0 ) + printf("%d:%d has no block ptr.%p %s or wrong hash\n",bp->hdrsi,bundlei,block,bits256_str(str,origtxdata->block.RO.hash2)); return(-1); } - if ( block->fpipbits != 0 ) + block->txvalid = 1; + if ( block->fpipbits != 0 && block->fpos >= 0 ) { - //printf("ramchaindata have %d:%d at %d\n",bp->hdrsi,bundlei,bp->fpos[bundlei]); + static int32_t numredundant; static double redundantsize; static uint32_t lastdisp; + char str[65],str2[65]; + numredundant++, redundantsize += recvlen; + if ( time(NULL) > lastdisp+30 ) + { + lastdisp = (uint32_t)time(NULL); + printf("ramchaindata have %d:%d at %d | %d blocks %s redundant xfers total %s %.2f%% wasted\n",bp->hdrsi,bundlei,block->fpos,numredundant,mbstr(str,redundantsize),mbstr(str2,totalrecv),100.*redundantsize/totalrecv); + } return(block->fpos); } - //SETBIT(bp->recv,bundlei); - fpos = -1; - //bp->recvlens[bundlei] = recvlen; - //bp->firsttxidinds[bundlei] = firsti; - if ( iguana_ramchain_init(ramchain,&addr->TXDATA,&addr->HASHMEM,1,txn_count,origtxdata->numunspents,origtxdata->numspends,0,0,0,1) == 0 ) + sigsize = pubkeysize = 0; + scriptspace = 1;//iguana_scriptspaceraw(coin,&scriptsize,&sigsize,&pubkeysize,txarray,txn_count); + if ( iguana_ramchain_init(fname,ramchain,&addr->TXDATA,&addr->HASHMEM,1,txn_count,origtxdata->numunspents,origtxdata->numspends,0,0,(scriptspace+sigsize+pubkeysize)*1.1,0,1) == 0 ) + { + if ( block->fpipbits == 0 ) + block->issued = block->RO.recvlen = 0, block->fpos = -1; return(-1); - iguana_ramchain_link(ramchain,origtxdata->block.RO.hash2,origtxdata->block.RO.hash2,bp->hdrsi,bp->bundleheight+bundlei,bundlei,1,firsti,0); + } + block->fpos = fpos = -1; + iguana_ramchain_link(ramchain,block->RO.hash2,bp->hdrsi,bp->bundleheight+bundlei,bundlei,1,firsti,0); _iguana_ramchain_setptrs(RAMCHAIN_PTRS,ramchain->H.data); - if ( T == 0 || U == 0 || S == 0 || B == 0 )// P == 0//|| X == 0 || A == 0 || U2 == 0 || P2 == 0 ) - { - printf("fatal error getting txdataptrs\n"); + subdir = bp->bundleheight / IGUANA_SUBDIRDIVISOR; + char dirname[1024]; sprintf(dirname,"%s/%s/%d",GLOBAL_TMPDIR,coin->symbol,subdir), OS_ensure_directory(dirname); + sprintf(dirname,"%s/%s/%d/%d",GLOBAL_TMPDIR,coin->symbol,subdir,bp->bundleheight), OS_ensure_directory(dirname); + //printf("Kspace.%p bp.[%d:%d] <- scriptspace.%d expanded.%d\n",Kspace,bp->hdrsi,bundlei,scriptspace,ramchain->expanded); + if ( T == 0 || U == 0 || S == 0 || B == 0 ) + { + block->issued = 0; + block->RO.recvlen = 0; + printf("fatal error getting txdataptrs %p %p %p %p\n",T,U,S,B); return(-1); } + block->fpipbits = 1; for (i=0; iH.txidind++) { tx = &txarray[i]; - iguana_ramchain_addtxid(coin,RAMCHAIN_ARG,tx->txid,tx->tx_out,tx->tx_in,tx->lock_time,tx->version,tx->timestamp); + iguana_ramchain_addtxid(coin,RAMCHAIN_ARG,tx->txid,tx->tx_out,tx->tx_in,tx->lock_time,tx->version,tx->timestamp,bundlei); for (j=0; jtx_out; j++) { - iguana_ramchain_addunspent20(coin,RAMCHAIN_ARG,tx->vouts[j].value,tx->vouts[j].pk_script,tx->vouts[j].pk_scriptlen,tx->txid,j,0); + memset(rmd160,0,sizeof(rmd160)); + //printf("i.%d j.%d pkscriptlen.%d\n",i,j,tx->vouts[j].pk_scriptlen); + iguana_ramchain_addunspent20(coin,addr,RAMCHAIN_ARG,tx->vouts[j].value,tx->vouts[j].pk_script,tx->vouts[j].pk_scriptlen,tx->txid,j,-1,bp,rmd160); } ramchain->H.spendind += tx->tx_in; } + //printf("scriptoffset.%d after %d txids\n",ramchain->H.scriptoffset,txn_count); ramchain->H.txidind = ramchain->H.spendind = ramchain->H.data->firsti; for (i=0; iH.txidind++) { tx = &txarray[i]; for (j=0; jtx_in; j++) { - //char str[65]; printf("PT vin.%d %s vout.%d\n",j,bits256_str(str,tx->vins[j].prev_hash),tx->vins[j].prev_vout); - iguana_ramchain_addspend256(coin,RAMCHAIN_ARG,tx->vins[j].prev_hash,tx->vins[j].prev_vout,tx->vins[j].script,tx->vins[j].scriptlen,tx->vins[j].sequence);//,bp->hdrsi,bundlei); + iguana_ramchain_addspend256(coin,addr,RAMCHAIN_ARG,tx->vins[j].prev_hash,tx->vins[j].prev_vout,tx->vins[j].vinscript,tx->vins[j].scriptlen,tx->vins[j].sequence,bp);//,bp->hdrsi,bundlei); } } - //char str[65]; printf("before height.%d num.%d:%d T.%d U.%d S.%d P.%d X.%d %s\n",ramchain->height,ramchain->numblocks,ramchain->H.data->numblocks,ramchain->H.txidind,ramchain->H.unspentind,ramchain->H.spendind,ramchain->pkind,ramchain->externalind,bits256_str(str,ramchain->H.data->firsthash2)); - iguana_ramchain_setsize(ramchain,ramchain->H.data,1); + ramchain->H.data->prevhash2 = block->RO.prev_block; + ramchain->H.data->scriptspace = scriptspace = ramchain->H.scriptoffset; + ramchain->H.data->stackspace = stackspace = ramchain->H.stacksize; + iguana_ramchain_setsize(fname,ramchain,ramchain->H.data,1); flag = 0; if ( ramchain->H.txidind != ramchain->H.data->numtxids || ramchain->H.unspentind != ramchain->H.data->numunspents || ramchain->H.spendind != ramchain->H.data->numspends ) { - printf("error creating PT ramchain: ramchain->txidind %d != %d ramchain->data->numtxids || ramchain->unspentind %d != %d ramchain->data->numunspents || ramchain->spendind %d != %d ramchain->data->numspends\n",ramchain->H.txidind,ramchain->H.data->numtxids,ramchain->H.unspentind,ramchain->H.data->numunspents,ramchain->H.spendind,ramchain->H.data->numspends); + printf("error creating PT ramchain.[%d:%d] ramchain->txidind %d != %d ramchain->data->numtxids || ramchain->unspentind %d != %d ramchain->data->numunspents || ramchain->spendind %d != %d ramchain->data->numspends space.(%d v %d)\n",bp->hdrsi,bp->bundleheight,ramchain->H.txidind,ramchain->H.data->numtxids,ramchain->H.unspentind,ramchain->H.data->numunspents,ramchain->H.spendind,ramchain->H.data->numspends,ramchain->H.scriptoffset,ramchain->H.data->scriptspace); + block->fpipbits = 0; + block->issued = 0; + block->RO.recvlen = 0; } else { if ( (err= iguana_ramchain_verify(coin,ramchain)) == 0 ) { - B[0] = origtxdata->block.RO; - if ( (fpos= (int32_t)iguana_ramchain_save(coin,RAMCHAIN_ARG,(uint32_t)addr->ipbits,origtxdata->block.RO.hash2,origtxdata->block.RO.prev_block,bundlei,0)) >= 0 ) + B[0] = block->RO; + ramchain->H.data->scriptspace = ramchain->H.scriptoffset = scriptspace; + ramchain->H.data->stackspace = ramchain->H.stacksize = stackspace; + if ( (fpos= (int32_t)iguana_ramchain_save(coin,RAMCHAIN_ARG,addr_ipbits,block->RO.hash2,block->RO.prev_block,bundlei,0)) >= 0 ) { - //printf("set fpos.%d\n",fpos); - //bp->ipbits[bundlei] = addr->ipbits; + //char str[65]; printf("saved.%s [%d:%d]\n",bits256_str(str,block->RO.hash2),bp->hdrsi,bundlei); origtxdata->datalen = (int32_t)ramchain->H.data->allocsize; ramchain->H.ROflag = 0; flag = 1; + if ( addr->dirty[0] != 0 && addr->voutsfp != 0 ) + fflush(addr->voutsfp); + if ( addr->dirty[1] != 0 && addr->vinsfp != 0 ) + fflush(addr->vinsfp); memset(&R,0,sizeof(R)); - if ( verifyflag != 0 && (mapchain= iguana_ramchain_map(coin,fname,0,1,&R,0,(uint32_t)addr->ipbits,origtxdata->block.RO.hash2,origtxdata->block.RO.prev_block,bundlei,fpos,1,0)) != 0 ) + if ( verifyflag != 0 && (mapchain= iguana_ramchain_map(coin,fname,0,1,&R,0,addr_ipbits,block->RO.hash2,block->RO.prev_block,bundlei,fpos,1,0)) == 0 ) { + printf("delete unverified [%d:%d]\n",bp->hdrsi,bundlei); + iguana_ramchain_free(coin,&R,1); + fpos = -1; //printf("mapped Soffset.%ld\n",(long)mapchain->data->Soffset); - iguana_ramchain_link(&R,origtxdata->block.RO.hash2,origtxdata->block.RO.hash2,bp->hdrsi,bp->bundleheight+bundlei,bundlei,1,firsti,1); - if ( 0 ) // crashes unix + /*iguana_ramchain_link(&R,block->RO.hash2,bp->hdrsi,bp->bundleheight+bundlei,bundlei,1,firsti,1); + if ( 1 ) // unix issues? { if ( (err= iguana_ramchain_cmp(ramchain,mapchain,0)) != 0 ) - printf("error.%d comparing ramchains\n",err); - ptr = mapchain->fileptr; fsize = mapchain->filesize; - mapchain->fileptr = 0, mapchain->filesize = 0; - iguana_ramchain_free(mapchain,1); - memset(&R,0,sizeof(R)); - R.H.data = (void *)(long)((long)ptr + fpos), R.filesize = fsize; - iguana_ramchain_link(&R,origtxdata->block.RO.hash2,origtxdata->block.RO.hash2,bp->hdrsi,bp->bundleheight+bundlei,bundlei,1,firsti,1); + fpos = -1, printf("error.%d comparing ramchains\n",err); + else + { + ptr = mapchain->fileptr; fsize = mapchain->filesize; + mapchain->fileptr = 0, mapchain->filesize = 0; + iguana_ramchain_free(coin,mapchain,1); + memset(&R,0,sizeof(R)); + R.H.data = (void *)(long)((long)ptr + fpos), R.filesize = fsize; + iguana_ramchain_link(&R,block->RO.hash2,bp->hdrsi,bp->bundleheight+bundlei,bundlei,1,firsti,1); + } } if ( (err= iguana_ramchain_cmp(ramchain,&R,0)) != 0 ) { fpos = -1; + block->issued = 0; + block->RO.recvlen = 0; printf("error.%d comparing REMAP ramchains\n",err); } else { - iguana_ramchain_extras(&R,0); - if ( (err= iguana_ramchain_iterate(coin,0,&R)) != 0 ) + iguana_ramchain_extras(coin,&R,0,0); + if ( (err= iguana_ramchain_iterate(coin,0,&R,bp,bundlei)) != 0 ) printf("err.%d iterate ",err); //printf("SUCCESS REMAP\n"); bp->numtxids += ramchain->H.data->numtxids; bp->numunspents += ramchain->H.data->numunspents; bp->numspends += ramchain->H.data->numspends; + //bp->rawscriptspace += ramchain->H.data->scriptspace; } - iguana_ramchain_free(&R,1); + iguana_ramchain_free(coin,&R,1); + if ( err != 0 ) + iguana_blockunmark(coin,block,bp,bundlei,1);*/ } else { bp->numtxids += ramchain->H.data->numtxids; bp->numunspents += ramchain->H.data->numunspents; bp->numspends += ramchain->H.data->numspends; + //bp->rawscriptspace += ramchain->H.data->scriptspace; } if ( fpos >= 0 ) - block->fpos = fpos, block->fpipbits = (uint32_t)addr->ipbits; + block->fpos = fpos, block->fpipbits = addr_ipbits; } - } else printf("ramchain verification error.%d hdrsi.%d bundlei.%d\n",err,bp->hdrsi,bundlei); + } + else + { + printf("ramchain verification error.%d hdrsi.%d bundlei.%d n.%d\n",err,bp->hdrsi,bundlei,bp->n); + fpos = -1; + } } + if ( fpos < 0 ) + iguana_blockunmark(coin,block,bp,bundlei,1); + //fprintf(stderr,"finished with hdrsi.%d ht.%d scripts.%u:%u\n",bp->hdrsi,bp->bundleheight,ramchain->H.scriptoffset,ramchain->H.data->scriptspace); ramchain->H.ROflag = 0; - iguana_ramchain_free(ramchain,0); + iguana_ramchain_free(coin,ramchain,0); return(fpos); } @@ -1577,9 +2092,44 @@ void iguana_ramchain_disp(struct iguana_ramchain *ramchain) } } -int32_t iguana_bundlefiles(struct iguana_info *coin,uint32_t *ipbits,void **ptrs,long *filesizes,struct iguana_bundle *bp) +void iguana_blockunmark(struct iguana_info *coin,struct iguana_block *block,struct iguana_bundle *bp,int32_t i,int32_t deletefile) +{ + void *ptr; int32_t recvlen,hdrsi,checki; char fname[1024]; static const bits256 zero; + if ( 0 && bp != 0 ) + printf("UNMARK.[%d:%d]\n",bp->hdrsi,i); + if ( block != 0 ) + { + block->queued = 0; + block->fpipbits = 0; + block->fpos = -1; + block->txvalid = 0; + block->issued = 0; + } + if ( bp != 0 && i >= 0 && i < bp->n ) + { + bp->issued[i] = 0; + if ( (ptr= bp->speculativecache[i]) != 0 ) + { + memcpy(&recvlen,ptr,sizeof(recvlen)); + free(ptr); + bp->speculativecache[i] = 0; + } + } + if ( deletefile != 0 ) + { + fname[0] = 0; + if ( block != 0 && (checki= iguana_peerfname(coin,&hdrsi,GLOBAL_TMPDIR,fname,0,block->RO.hash2,zero,1,1)) != i ) + { + //printf("checki.%d vs %d mismatch? %s\n",checki,i,fname); + } + if ( fname[0] != 0 ) + OS_removefile(fname,0); + } +} + +int32_t iguana_oldbundlefiles(struct iguana_info *coin,uint32_t *ipbits,void **ptrs,long *filesizes,struct iguana_bundle *bp) { - static bits256 zero; + static const bits256 zero; int32_t j,bundlei,num,hdrsi,checki; struct iguana_block *block; uint32_t fpipbits; char fname[1024]; for (bundlei=num=0; bundlein; bundlei++) { @@ -1587,9 +2137,7 @@ int32_t iguana_bundlefiles(struct iguana_info *coin,uint32_t *ipbits,void **ptrs fpipbits = block->fpipbits; else { - block->queued = 0; - block->fpipbits = 0; - bp->issued[bundlei] = 0; + iguana_blockunmark(coin,block,bp,bundlei,0); return(0); } if ( num > 0 ) @@ -1601,17 +2149,15 @@ int32_t iguana_bundlefiles(struct iguana_info *coin,uint32_t *ipbits,void **ptrs if ( j == num ) { ipbits[num] = fpipbits; - if ( (checki= iguana_peerfname(coin,&hdrsi,"tmp",fname,fpipbits,bp->hashes[bundlei],bundlei>0?bp->hashes[bundlei-1]:zero,1)) != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) + if ( (checki= iguana_peerfname(coin,&hdrsi,GLOBAL_TMPDIR,fname,fpipbits,bp->hashes[bundlei],zero,1,1)) != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) { printf("B iguana_ramchain_map.(%s) illegal hdrsi.%d bundlei.%d checki.%d\n",fname,hdrsi,bundlei,checki); return(0); } if ( (ptrs[num]= OS_mapfile(fname,&filesizes[num],0)) == 0 ) { - printf("error mapping bundlei.%d\n",bundlei); - block->queued = 0; - block->fpipbits = 0; - bp->issued[bundlei] = 0; + printf("error mapping bundlei.%d (%s)\n",bundlei,fname); + iguana_blockunmark(coin,block,bp,bundlei,1); return(0); } //printf("%s mapped ptrs[%d] filesize.%ld bundlei.%d ipbits.%x fpos.%d\n",fname,num,(long)filesizes[num],bundlei,fpipbits,bp->fpos[bundlei]); @@ -1621,9 +2167,50 @@ int32_t iguana_bundlefiles(struct iguana_info *coin,uint32_t *ipbits,void **ptrs return(num); } -void iguana_bundlemapfree(struct OS_memspace *mem,struct OS_memspace *hashmem,uint32_t *ipbits,void **ptrs,long *filesizes,int32_t num,struct iguana_ramchain *R,int32_t n) +void *iguana_bundlefile(struct iguana_info *coin,char *fname,long *filesizep,struct iguana_bundle *bp,int32_t bundlei) { - int32_t j; + int32_t checki,hdrsi; void *ptr = 0; FILE *fp; static const bits256 zero; + *filesizep = 0; + fname[0] = 0; + if ( (checki= iguana_peerfname(coin,&hdrsi,GLOBAL_TMPDIR,fname,0,bp->hashes[bundlei],zero,1,1)) != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) + { + printf("B iguana_ramchain_map.(%s) illegal hdrsi.%d bundlei.%d checki.%d\n",fname,hdrsi,bundlei,checki); + return(0); + } + if ( (fp= fopen(fname,"rb")) == 0 ) + return(0); + else + { + fclose(fp); + if ( (ptr= OS_mapfile(fname,filesizep,0)) == 0 ) + { + printf("error mapping.(%s) bundlei.%d\n",fname,bundlei); + return(0); + } + } + //printf("mapped.(%s) bundlei.[%d:%d] %p[%ld]\n",fname,hdrsi,bundlei,ptr,*filesizep); + return(ptr); +} + +int32_t iguana_bundlefiles(struct iguana_info *coin,uint32_t *ipbits,void **ptrs,long *filesizes,struct iguana_bundle *bp,int32_t starti,int32_t endi) +{ + int32_t bundlei,num = 0; char fname[1024]; + for (bundlei=starti; bundlei<=endi; bundlei++) + { + if ( (ptrs[num]= iguana_bundlefile(coin,fname,&filesizes[num],bp,bundlei)) != 0 ) + num++; + else + { + printf("%s error ptrs[%d] filesize.%ld bundlei.%d ipbits.%x\n",fname,num,(long)filesizes[num],bundlei,ipbits[bundlei]); + return(bp == coin->current ? num : 0); + } + } + return(num); +} + +void iguana_bundlemapfree(struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *hashmem,uint32_t *ipbits,void **ptrs,long *filesizes,int32_t num,struct iguana_ramchain *R,int32_t starti,int32_t endi) +{ + int32_t j,n = (endi - starti + 1); for (j=0; jH.data->firsthash2, lasthash2 = ramchain->H.data->lasthash2; + static const bits256 zero; + bits256 firsthash2; int32_t err,bundlei,hdrsi,numblocks,firsti,height,retval= -1; + struct iguana_ramchain checkR,*mapchain; char fname[1024]; struct iguana_block *block; + uint32_t scriptspace,scriptoffset,stacksize; uint8_t *destoffset,*srcoffset; + firsthash2 = ramchain->H.data->firsthash2;//, lasthash2 = ramchain->H.data->lasthash2; height = ramchain->height, firsti = ramchain->H.data->firsti, hdrsi = ramchain->H.hdrsi, numblocks = ramchain->numblocks; - //printf("B[] %p\n",B); - //printf("Apresave T.%d U.%d S.%d P.%d X.%d -> size.%ld firsti.%d\n",ramchain->H.data->numtxids,ramchain->H.data->numunspents,ramchain->H.data->numspends,ramchain->H.data->numpkinds,ramchain->H.data->numexternaltxids,(long)ramchain->H.data->allocsize,firsti); - iguana_ramchain_setsize(ramchain,ramchain->H.data,bp->n); + destoffset = &Kspace[ramchain->H.scriptoffset]; + srcoffset = &Kspace[ramchain->H.data->scriptspace - ramchain->H.stacksize]; + if ( ramchain->expanded != 0 ) + { + if ( (long)destoffset > (long)srcoffset ) + printf("smashed stack? dest.%ld vs src %ld offset.%u stacksize.%u space.%u\n",(long)destoffset,(long)srcoffset,(uint32_t)ramchain->H.scriptoffset,(uint32_t)ramchain->H.stacksize,(uint32_t)ramchain->H.scriptoffset); + } + //printf("%d SAVE: Koffset.%d scriptoffset.%d stacksize.%d allocsize.%d gap.%ld RO.%d\n",bp->bundleheight,(int32_t)ramchain->H.data->Koffset,ramchain->H.scriptoffset,ramchain->H.stacksize,(int32_t)ramchain->H.data->allocsize,(long)destoffset - (long)srcoffset,ramchain->H.ROflag); + scriptspace = ramchain->H.data->scriptspace; + scriptoffset = ramchain->H.scriptoffset; + stacksize = ramchain->H.stacksize; + //ramchain->H.scriptoffset = scriptoffset; + if ( (block= bp->blocks[0]) != 0 ) + ramchain->H.data->prevhash2 = block->RO.prev_block; + ramchain->H.data->scriptspace = scriptoffset; + ramchain->H.stacksize = ramchain->H.data->stackspace = stacksize; + iguana_ramchain_setsize(fname,ramchain,ramchain->H.data,bp->n); + //printf("Apresave T.%d U.%d S.%d P.%d X.%d -> size.%ld firsti.%d scriptoffset.%d stacksize.%d\n",ramchain->H.data->numtxids,ramchain->H.data->numunspents,ramchain->H.data->numspends,ramchain->H.data->numpkinds,ramchain->H.data->numexternaltxids,(long)ramchain->H.data->allocsize,firsti,ramchain->H.scriptoffset,ramchain->H.stacksize); *newchain = *ramchain; //memcpy(ramchain->roU2,ramchain->U2,sizeof(*ramchain->U2) * ramchain->H.data->numunspents); //memcpy(ramchain->roP2,ramchain->P2,sizeof(*ramchain->P2) * ramchain->H.data->numpkinds); - memcpy(ramchain->roA,ramchain->A,sizeof(*ramchain->A) * ramchain->H.data->numpkinds); + memcpy(ramchain->creditsA,ramchain->A,sizeof(*ramchain->A) * ramchain->H.data->numpkinds); memset(ramchain->A,0,sizeof(*ramchain->A) * ramchain->H.data->numpkinds); //printf("presave T.%d U.%d S.%d P.%d X.%d -> size.%ld firsti.%d\n",ramchain->H.data->numtxids,ramchain->H.data->numunspents,ramchain->H.data->numspends,ramchain->H.data->numpkinds,ramchain->H.data->numexternaltxids,(long)ramchain->H.data->allocsize,firsti); - if ( (err= iguana_ramchain_iterate(coin,0,ramchain)) != 0 ) + //printf("0 preSAVE: Koffset.%d scriptoffset.%d stacksize.%d allocsize.%d\n",(int32_t)ramchain->H.data->Koffset,ramchain->H.scriptoffset,ramchain->H.stacksize,(int32_t)ramchain->H.data->allocsize); + if ( (err= iguana_ramchain_iterate(coin,0,ramchain,bp,-1)) != 0 ) printf("ERROR.%d iterating presave ramchain hdrsi.%d\n",err,hdrsi); - else if ( (err= iguana_ramchain_verify(coin,ramchain)) != 0 ) - printf("ERROR.%d verifying presave ramchain hdrsi.%d\n",err,hdrsi); - else retval = 0; - printf("postiterateA T.%d U.%d S.%d P.%d X.%d -> size.%ld firsti.%d\n",ramchain->H.data->numtxids,ramchain->H.data->numunspents,ramchain->H.data->numspends,ramchain->H.data->numpkinds,ramchain->H.data->numexternaltxids,(long)ramchain->H.data->allocsize,firsti); + else + { + //printf("postiterate0.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld firsti.%d scripts.%d:%d stack.%d:%d\n",bp->bundleheight,ramchain->H.data->numtxids,ramchain->H.data->numunspents,ramchain->H.data->numspends,ramchain->H.data->numpkinds,ramchain->H.data->numexternaltxids,(long)ramchain->H.data->allocsize,firsti,(int32_t)ramchain->H.scriptoffset,scriptoffset,(int32_t)ramchain->H.stacksize,stacksize); + if ( ramchain->H.scriptoffset > scriptoffset || ramchain->H.stacksize > stacksize ) + printf("MEMORY OVERFLOW\n"); + if ( (err= iguana_ramchain_verify(coin,ramchain)) != 0 ) + printf("ERROR.%d verifying presave ramchain hdrsi.%d\n",err,hdrsi); + else retval = 0; + } + //printf("postiterateA.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld firsti.%d scripts.%d:%d stack.%d:%d\n",bp->bundleheight,ramchain->H.data->numtxids,ramchain->H.data->numunspents,ramchain->H.data->numspends,ramchain->H.data->numpkinds,ramchain->H.data->numexternaltxids,(long)ramchain->H.data->allocsize,firsti,(int32_t)ramchain->H.scriptoffset,scriptoffset,(int32_t)ramchain->H.stacksize,stacksize); + ramchain->H.scriptoffset = scriptoffset; + ramchain->H.data->scriptspace = scriptoffset; + ramchain->H.stacksize = ramchain->H.data->stackspace = stacksize; if ( iguana_ramchain_save(coin,RAMCHAIN_ARG,0,firsthash2,zero,0,bp) < 0 ) - printf("ERROR saving ramchain hdrsi.%d\n",hdrsi); + { + printf("ERROR saving ramchain hdrsi.%d, deleting and will regenerate\n",hdrsi); + iguana_mempurge(hashmem); + } else { //printf("DEST T.%d U.%d S.%d P.%d X.%d -> size.%ld Xoffset.%d\n",ramchain->H.data->numtxids,ramchain->H.data->numunspents,ramchain->H.data->numspends,ramchain->H.data->numpkinds,ramchain->H.data->numexternaltxids,(long)ramchain->H.data->allocsize,(int32_t)ramchain->H.data->Xoffset); //printf("free dest hdrs.%d retval.%d\n",bp->hdrsi,retval); memset(&checkR,0,sizeof(checkR)); + checkR.sigsfileptr = ramchain->sigsfileptr; + checkR.sigsfilesize = ramchain->sigsfilesize; bundlei = 0; if ( cmpflag == 0 ) iguana_memreset(hashmem); - if ( (mapchain= iguana_ramchain_map(coin,fname,bp,numblocks,&checkR,cmpflag==0?hashmem:0,0,firsthash2,zero,bundlei,0,1,1)) != 0 ) + if ( (mapchain= iguana_ramchain_map(coin,fname,bp,numblocks,&checkR,cmpflag==0?hashmem:0,0,firsthash2,zero,bundlei,0,0,1)) != 0 ) { - iguana_ramchain_link(mapchain,firsthash2,lasthash2,hdrsi,height,0,numblocks,firsti,1); - iguana_ramchain_extras(mapchain,hashmem); - //printf("MAP T.%d U.%d S.%d P.%d X.%d -> size.%ld Xoffset.%d\n",mapchain->H.data->numtxids,mapchain->H.data->numunspents,mapchain->H.data->numspends,mapchain->H.data->numpkinds,mapchain->H.data->numexternaltxids,(long)mapchain->H.data->allocsize,(int32_t)mapchain->H.data->Xoffset); - if ( (err= iguana_ramchain_iterate(coin,0,mapchain)) != 0 ) + iguana_ramchain_link(mapchain,firsthash2,hdrsi,height,0,numblocks,firsti,1); + iguana_ramchain_extras(coin,mapchain,hashmem,0); + //printf("expSAVE: Koffset.%d scriptoffset.%d stacksize.%d allocsize.%d\n",(int32_t)mapchain->H.data->Koffset,mapchain->H.scriptoffset,mapchain->H.stacksize,(int32_t)mapchain->H.data->allocsize); + if ( (err= iguana_ramchain_iterate(coin,0,mapchain,bp,bundlei)) != 0 ) printf("err.%d iterate mapped dest\n",err); else if ( cmpflag != 0 ) { @@ -1699,182 +2317,304 @@ int32_t iguana_ramchain_expandedsave(struct iguana_info *coin,RAMCHAIN_FUNC,stru retval = 0; } } - int32_t i; for (i=0; iH.data->lhashes[i].uints[0]); - printf("%llx ht.%d\n",(long long)mapchain->H.data->sha256.txid,mapchain->height); - iguana_ramchain_free(mapchain,cmpflag); + //printf("%08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %llx ht.%d bundlehashes.%s\n",mapchain->H.data->lhashes[0].uints[0],mapchain->H.data->lhashes[1].uints[0],mapchain->H.data->lhashes[2].uints[0],mapchain->H.data->lhashes[3].uints[0],mapchain->H.data->lhashes[4].uints[0],mapchain->H.data->lhashes[5].uints[0],mapchain->H.data->lhashes[6].uints[0],mapchain->H.data->lhashes[7].uints[0],mapchain->H.data->lhashes[8].uints[0],mapchain->H.data->lhashes[9].uints[0],(long long)mapchain->H.data->sha256.txid,mapchain->height,coin->symbol); + iguana_ramchain_free(coin,mapchain,cmpflag); } iguana_mempurge(hashmem); } + if ( retval < 0 ) + { + printf("remove unmappable bundle.[%d]\n",bp->hdrsi); + iguana_bundleremove(coin,bp->hdrsi,0); + } return(retval); } -struct iguana_ramchain *iguana_bundleload(struct iguana_info *coin,struct iguana_bundle *bp) +struct iguana_ramchain *iguana_bundleload(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct iguana_bundle *bp,int32_t extraflag) { - static bits256 zero; + static const bits256 zero; struct iguana_blockRO *B; struct iguana_txid *T; int32_t i,firsti = 1; char fname[512]; struct iguana_block *block; struct iguana_ramchain *mapchain; - memset(&bp->ramchain,0,sizeof(bp->ramchain)); - if ( (mapchain= iguana_ramchain_map(coin,fname,bp,bp->n,&bp->ramchain,0,0,bp->hashes[0],zero,0,0,0,1)) != 0 ) - { - iguana_ramchain_link(mapchain,bp->hashes[0],bp->ramchain.lasthash2,bp->hdrsi,bp->bundleheight,0,bp->ramchain.numblocks,firsti,1); - //char str[65]; printf("bp.%d: T.%d U.%d S.%d P%d X.%d MAPPED %s %p\n",bp->hdrsi,bp->ramchain.H.data->numtxids,bp->ramchain.H.data->numunspents,bp->ramchain.H.data->numspends,bp->ramchain.H.data->numpkinds,bp->ramchain.H.data->numexternaltxids,mbstr(str,bp->ramchain.H.data->allocsize),bp->ramchain.H.data); - //ramcoder_test(bp->ramchain.H.data,bp->ramchain.H.data->allocsize); - B = (void *)(long)((long)mapchain->H.data + mapchain->H.data->Boffset); - T = (void *)(long)((long)mapchain->H.data + mapchain->H.data->Toffset); + memset(ramchain,0,sizeof(*ramchain)); + if ( (mapchain= iguana_ramchain_map(coin,fname,bp,bp->n,ramchain,0,0,bp->hashes[0],zero,0,0,extraflag,1)) != 0 ) + { + iguana_ramchain_link(mapchain,bp->hashes[0],bp->hdrsi,bp->bundleheight,0,bp->n,firsti,1); + //char str[65]; printf("bp.%d: T.%d U.%d S.%d P%d X.%d MAPPED %s %p\n",bp->hdrsi,mapchain->H.data->numtxids,mapchain->H.data->numunspents,mapchain->H.data->numspends,mapchain->H.data->numpkinds,mapchain->H.data->numexternaltxids,mbstr(str,mapchain->H.data->allocsize),mapchain->H.data); + //ramcoder_test(mapchain->H.data,mapchain->H.data->allocsize); + B = RAMCHAIN_PTR(ramchain->H.data,Boffset); + T = RAMCHAIN_PTR(ramchain->H.data,Toffset); + //B = (void *)(long)((long)mapchain->H.data + mapchain->H.data->Boffset); + //T = (void *)(long)((long)mapchain->H.data + mapchain->H.data->Toffset); for (i=0; in; i++) { - if ( (block= bp->blocks[i]) != 0 || (block= iguana_blockhashset(coin,bp->bundleheight+i,bp->hashes[i],1)) != 0 ) + if ( (block= bp->blocks[i]) != 0 || (block= iguana_blockhashset("bundleload",coin,bp->bundleheight+i,bp->hashes[i],1)) != 0 ) { block->queued = 1; + block->txvalid = 1; block->height = bp->bundleheight + i; block->hdrsi = bp->hdrsi; block->bundlei = i; block->fpipbits = (uint32_t)calc_ipbits("127.0.0.1"); block->RO = B[i]; //printf("%x ",(int32_t)B[i].hash2.ulongs[3]); - if ( bp->blocks[i] == 0 ) - bp->blocks[i] = block; - if ( bits256_nonz(bp->hashes[i]) == 0 ) - bp->hashes[i] = B[i].hash2; + iguana_hash2set(coin,"bundleload",bp,i,block->RO.hash2); + //if ( bits256_nonz(bp->hashes[i]) == 0 ) + // bp->hashes[i] = B[i].hash2; if ( bp->bundleheight+i == coin->blocks.hwmchain.height+1 ) { //printf("try extend.%d\n",bp->bundleheight+i); - _iguana_chainlink(coin,block); + //_iguana_chainlink(coin,block); wrong context } } } - //printf("bundle.%d\n",bp->bundleheight); + //printf("mapped bundle.%d\n",bp->bundleheight); bp->emitfinish = (uint32_t)time(NULL) + 1; - /*for (i=1; iH.data->numtxids; i++) - {break; - if ( iguana_txidfind(coin,&height,&tx,T[i].txid) == 0 ) - printf("error couldnt find T[%d] %s\n",i,bits256_str(str,T[i].txid)); - else if ( memcmp(&tx,&T[i],sizeof(T[i])) != 0 ) - printf("compare error T[%d] %s\n",i,bits256_str(str,T[i].txid)); - }*/ + iguana_bundlecalcs(coin,bp,60); + } + else + { + //printf("couldnt load bundle.%d\n",bp->bundleheight); + memset(&bp->ramchain,0,sizeof(bp->ramchain)); + bp->ramchain.height = bp->bundleheight; + bp->emitfinish = 0; + //iguana_bundleremove(coin,bp->hdrsi,0); } if ( mapchain != 0 ) coin->newramchain++; return(mapchain); } +int64_t iguana_ramchainopen(char *fname,struct iguana_info *coin,struct iguana_ramchain *ramchain,struct OS_memspace *mem,struct OS_memspace *hashmem,int32_t bundleheight,bits256 hash2) +{ + RAMCHAIN_DECLARE; RAMCHAIN_ZEROES; int32_t i,numblocks = coin->chain->bundlesize; uint32_t numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace; struct iguana_bundle *bp; struct iguana_ramchaindata *rdata; int64_t hashsize,allocsize; + //B = 0, Ux = 0, Sx = 0, P = 0, A = 0, X = 0, Kspace = TXbits = PKbits = 0, U = 0, S = 0, T = 0; + mem->alignflag = sizeof(uint32_t); + hashmem->alignflag = sizeof(uint32_t); + scriptspace = numexternaltxids = numtxids = coin->chain->bundlesize * 1.5; + numunspents = numspends = numpkinds = numtxids * 2; + for (i=0; ibundlescount; i++) + if ( (bp= coin->bundles[i]) != 0 && (rdata= bp->ramchain.H.data) != 0 ) + { + if ( rdata->numtxids > numtxids ) + numtxids = rdata->numtxids; + if ( rdata->numpkinds > numpkinds ) + numpkinds = rdata->numpkinds; + if ( rdata->numspends > numspends ) + numspends = rdata->numspends; + if ( rdata->numunspents > numunspents ) + numunspents = rdata->numunspents; + if ( rdata->numexternaltxids > numexternaltxids ) + numexternaltxids = rdata->numexternaltxids; + if ( rdata->scriptspace > scriptspace ) + scriptspace = rdata->scriptspace; + } +#ifndef __APPLE__ + numtxids *= 1.25; numexternaltxids *= 1.25, scriptspace *= 1.25; + numunspents *= 1.25, numspends *= 1.25, numpkinds *= 1.25; +#endif + if ( mem->ptr == 0 ) + { + while ( (allocsize= _iguana_rdata_action(fname,0,0,0,0,1,numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace,0,0,0,0,0,RAMCHAIN_ARG,numblocks)) > 2*1024LL*1024L*1024L ) + { + numtxids *= .9; + numunspents *= .9; + numspends *= .9; + numpkinds *= .9; + numexternaltxids *= .9; + } + iguana_meminit(mem,coin->symbol,0,allocsize + 65536*3,0); + } + if ( hashmem->ptr == 0 ) + { + hashsize = iguana_hashmemsize(numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace); + iguana_meminit(hashmem,coin->symbol,0,hashsize + 65536*3,0); + } + if ( iguana_ramchain_init(fname,ramchain,mem,hashmem,1,numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace,1,numblocks) > 0 ) + { + iguana_ramchain_link(ramchain,hash2,bundleheight/coin->chain->bundlesize,bundleheight,0,0,1,0); + ramchain->expanded = 1; + ramchain->H.scriptoffset = 1; + _iguana_ramchain_setptrs(RAMCHAIN_PTRS,ramchain->H.data); + iguana_ramchain_extras(coin,ramchain,hashmem,0); + } + if ( rdata != 0 ) + return(rdata->allocsize); + else return(0); +} + +int32_t iguana_mapchaininit(char *fname,struct iguana_info *coin,struct iguana_ramchain *mapchain,struct iguana_bundle *bp,int32_t bundlei,struct iguana_block *block,void *ptr,long filesize) +{ + int32_t firsti = 1; RAMCHAIN_DECLARE; + memset(mapchain,0,sizeof(*mapchain)); + mapchain->fileptr = ptr; + mapchain->filesize = filesize; + mapchain->H.data = (void *)(long)((long)ptr + block->fpos); + mapchain->H.ROflag = 1; + if ( ptr == 0 || block->fpos > filesize ) + { + printf("ptr.%p fpos error %d > %ld mapping hdrsi.%d bundlei.%d\n",ptr,block->fpos,filesize,bp->hdrsi,bundlei); + return(-1); + } + _iguana_ramchain_setptrs(MAPCHAIN_PTRS,mapchain->H.data); + if ( block->fpos+mapchain->H.data->allocsize > filesize || iguana_ramchain_size(fname,MAPCHAIN_ARG,1,mapchain->H.data->scriptspace) != mapchain->H.data->allocsize ) + { + printf("iguana_mapchaininit.%d ipbits.%x size mismatch %ld vs %ld vs filesize.%ld fpos.%ld bundlei.%d expanded.%d soff.%d\n",bp->bundleheight,block->fpipbits,(long)iguana_ramchain_size(fname,MAPCHAIN_ARG,1,mapchain->H.data->scriptspace),(long)mapchain->H.data->allocsize,(long)filesize,(long)block->fpos,bundlei,mapchain->expanded,mapchain->H.data->scriptspace); + //getchar(); + return(-1); + } + else if ( memcmp(bp->hashes[bundlei].bytes,mapchain->H.data->firsthash2.bytes,sizeof(bits256)) != 0 ) + { + char str[65],str2[65]; printf("iguana_bundlesaveHT.[%d:%d] hash2 mismatch %s vs %s\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei]),bits256_str(str2,mapchain->H.data->firsthash2)); + return(-1); + } + iguana_ramchain_link(mapchain,bp->hashes[bundlei],bp->hdrsi,bp->bundleheight+bundlei,bundlei,1,firsti,1); + if ( bp->blocks[bundlei]->RO.txn_count == 0 ) + bp->blocks[bundlei]->RO.txn_count = mapchain->H.data->numtxids - 1; + return(0); +} + // helper threads: NUM_HELPERS int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_bundle *bp,uint32_t starttime) // helper thread { - static int depth; static bits256 zero; - RAMCHAIN_DESTDECLARE; RAMCHAIN_DECLARE; - void **ptrs,*ptr; long *filesizes,filesize; uint32_t *ipbits; char fname[1024]; - struct iguana_ramchain *R,*mapchain,*dest,newchain; uint32_t fpipbits,now = (uint32_t)time(NULL); - int32_t i,numtxids,valid,numunspents,numspends,numpkinds,numexternaltxids,fpos; struct iguana_block *block; + static int depth; static const bits256 zero; + RAMCHAIN_DESTDECLARE; RAMCHAIN_DECLARE; RAMCHAIN_ZEROES; + void **ptrs; long *filesizes; uint32_t *ipbits; char fname[1024]; + struct iguana_ramchain *R,*mapchain,*dest,newchain; uint32_t fpipbits; bits256 prevhash2; + int32_t i,starti,endi,bp_n,numtxids,valid,sigspace,pubkeyspace,numunspents,numspends,numpkinds,numexternaltxids,scriptspace; struct iguana_block *block; long fpos; struct OS_memspace HASHMEM; int32_t err,j,num,hdrsi,bundlei,firsti= 1,retval = -1; - B = 0, Ux = 0, Sx = 0, P = 0, A = 0, X = 0, TXbits = 0, PKbits = 0, U = 0, S = 0, T = 0;//U2 = 0, P2 = 0, + memset(&HASHMEM,0,sizeof(HASHMEM)); + starti = 0, endi = bp->n - 1; + //B = 0, Ux = 0, Sx = 0, P = 0, A = 0, X = 0, Kspace = TXbits = PKbits = 0, U = 0, S = 0, T = 0; R = mycalloc('s',bp->n,sizeof(*R)); ptrs = mycalloc('w',bp->n,sizeof(*ptrs)); ipbits = mycalloc('w',bp->n,sizeof(*ipbits)); filesizes = mycalloc('f',bp->n,sizeof(*filesizes)); - if ( (num= iguana_bundlefiles(coin,ipbits,ptrs,filesizes,bp)) == 0 ) + if ( (num= iguana_bundlefiles(coin,ipbits,ptrs,filesizes,bp,starti,endi)) != bp->n ) { - iguana_bundlemapfree(0,0,ipbits,ptrs,filesizes,bp->n,R,bp->n); + iguana_bundlemapfree(coin,0,0,ipbits,ptrs,filesizes,num,R,starti,endi); + printf("iguana_bundlesaveHT: no bundlefiles error.[%d]\n",bp->hdrsi); return(-1); } - for (bundlei=numtxids=numunspents=numspends=0; bundlein; bundlei++) + if ( bp == coin->current ) + endi = num-1; + bp_n = (endi - starti + 1); + scriptspace = 1; + sigspace = pubkeyspace = 0; + if ( (block= bp->blocks[starti]) != 0 ) + prevhash2 = block->RO.prev_block; + else memset(prevhash2.bytes,0,sizeof(prevhash2)); + for (bundlei=starti,numtxids=numunspents=scriptspace=numspends=0; bundlei<=endi; bundlei++) { - if ( (block= bp->blocks[bundlei]) != 0 ) - fpipbits = block->fpipbits, fpos = block->fpos; - else fpipbits = fpos = 0; - mapchain = &R[bundlei]; - for (j=0; jactive == 0 ) { - printf("j.%d num.%d bundlei.%d\n",j,num,bundlei); - break; + iguana_bundlemapfree(coin,mem,&HASHMEM,ipbits,ptrs,filesizes,num,R,starti,endi); + return(-1); } - mapchain->fileptr = ptr; - mapchain->filesize = filesize; - mapchain->H.data = (void *)(long)((long)ptr + fpos); - mapchain->H.ROflag = 1; - if ( fpos+mapchain->H.data->allocsize > filesize || iguana_ramchain_size(MAPCHAIN_ARG,1) != mapchain->H.data->allocsize ) + if ( (block= bp->blocks[bundlei]) == 0 || bits256_nonz(block->RO.hash2) == 0 || memcmp(block->RO.hash2.bytes,bp->hashes[bundlei].bytes,sizeof(bits256)) != 0 || bits256_cmp(block->RO.prev_block,prevhash2) != 0 ) // block != iguana_blockfind("bundlesave",coin,block->RO.hash2) { - printf("iguana_bundlesaveHT ipbits.%x size mismatch %ld vs %ld vs filesize.%ld fpos.%ld bundlei.%d expanded.%d\n",fpipbits,(long)iguana_ramchain_size(MAPCHAIN_ARG,1),(long)mapchain->H.data->allocsize,(long)filesize,(long)fpos,bundlei,mapchain->expanded); - //getchar(); + printf("block.%p error vs %p\n",block,iguana_blockfind("bundlesaveerr",coin,block->RO.hash2)); break; } - else if ( memcmp(bp->hashes[bundlei].bytes,mapchain->H.data->firsthash2.bytes,sizeof(bits256)) != 0 ) + fpipbits = block->fpipbits, fpos = block->fpos; + mapchain = &R[bundlei]; + //printf("mapchain.[%d:%d] %p[%ld]\n",bp->hdrsi,bundlei,ptrs[bundlei],filesizes[bundlei]); + sprintf(fname,"save.%d",bp->hdrsi); + if ( iguana_mapchaininit(fname,coin,mapchain,bp,bundlei,block,ptrs[bundlei],filesizes[bundlei]) < 0 ) { - char str[65],str2[65]; printf("iguana_bundlesaveHT hash2 mismatch %s vs %s\n",bits256_str(str,bp->hashes[bundlei]),bits256_str(str2,mapchain->H.data->firsthash2)); - break; + iguana_bundlemapfree(coin,0,0,ipbits,ptrs,filesizes,num,R,starti,endi); + iguana_blockunmark(coin,bp->blocks[bundlei],bp,bundlei,1); + printf("error mapping hdrsi.%d bundlei.%d\n",bp->hdrsi,bundlei); + return(-1); } - iguana_ramchain_link(mapchain,bp->hashes[bundlei],bp->hashes[bundlei],bp->hdrsi,bp->bundleheight+bundlei,bundlei,1,firsti,1); + //printf("done mapchain.[%d:%d]\n",bp->hdrsi,bundlei); numtxids += (mapchain->H.data->numtxids - 1); numunspents += (mapchain->H.data->numunspents - 1); numspends += (mapchain->H.data->numspends - 1); - if ( (block= bp->blocks[bundlei]) == 0 || bits256_nonz(block->RO.hash2) == 0 || block != iguana_blockfind(coin,block->RO.hash2) || memcmp(block->RO.hash2.bytes,bp->hashes[bundlei].bytes,sizeof(bits256)) != 0 ) + scriptspace += 1;//iguana_ramchain_scriptspace(coin,&sigsize,&pubkeysize,mapchain); + //sigspace += sigsize; + //pubkeyspace += pubkeysize; + //printf("%x ",(uint32_t)block->RO.hash2.ulongs[3]); + _iguana_ramchain_setptrs(MAPCHAIN_PTRS,mapchain->H.data); + if ( bits256_cmp(B[0].hash2,block->RO.hash2) != 0 ) { - printf("block.%p error vs %p\n",block,iguana_blockfind(coin,block->RO.hash2)); + printf("mapped chain [%d:%d] hash2 mismatch\n",bp->hdrsi,bundlei); break; } - //printf("%x ",(uint32_t)block->RO.hash2.ulongs[3]); - //printf("(%d %d %d) ",numtxids,numunspents,numspends); + //printf("(%d %d).%d ",mapchain->H.data->numtxids,bp->blocks[bundlei]->RO.txn_count,numtxids); //printf("%d ",numtxids); + prevhash2 = block->RO.hash2; } - //printf("RObits\n"); - if ( bundlei != bp->n ) + scriptspace += pubkeyspace*1.1 + sigspace*1.1; + //printf("mem.%p mapchain txid tables, scriptspace.%u sigspace.%u pubkeyspace.%u bundlei.%d/%d\n",mem,scriptspace,sigspace,pubkeyspace,bundlei,bp->n); + if ( bundlei != endi+1 ) { - iguana_bundlemapfree(0,0,ipbits,ptrs,filesizes,num,R,bp->n); + iguana_bundlemapfree(coin,0,0,ipbits,ptrs,filesizes,num,R,starti,endi); + iguana_blockunmark(coin,bp->blocks[bundlei],bp,bundlei,1); printf("error mapping hdrsi.%d bundlei.%d\n",bp->hdrsi,bundlei); return(-1); } - //printf("-> total (%d %d %d)\n",numtxids,numunspents,numspends); + dest = &bp->ramchain; + //printf("iguana_bundlesaveHT.%d -> total (%d %d %d) scriptspace.%d (pubkeys.%d sigs.%d) dest->txids %p\n",bp->bundleheight,numtxids,numunspents,numspends,scriptspace,pubkeyspace,sigspace,dest->txids); + dest->txids = dest->pkhashes = 0; numpkinds = numunspents; numexternaltxids = numspends; - dest = &bp->ramchain; //printf("E.%d depth.%d start bundle ramchain %d at %u started.%u lag.%d\n",coin->numemitted,depth,bp->bundleheight,now,starttime,now-starttime); depth++; - if ( iguana_ramchain_alloc(coin,dest,mem,&HASHMEM,numtxids,numunspents,numspends,numpkinds,numexternaltxids,bp->bundleheight,bp->n) < 0 ) + if ( iguana_ramchain_alloc(fname,coin,dest,mem,&HASHMEM,numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace+sigspace,bp->bundleheight+starti,bp_n) < 0 ) { - iguana_bundlemapfree(mem,&HASHMEM,ipbits,ptrs,filesizes,num,R,bp->n); + printf("error iguana_ramchain_alloc for bundleheight.%d\n",bp->bundleheight); + iguana_bundlemapfree(coin,mem,&HASHMEM,ipbits,ptrs,filesizes,num,R,starti,endi); return(-1); } - iguana_ramchain_link(dest,bp->hashes[0],bp->hashes[bp->n-1],bp->hdrsi,bp->bundleheight,0,bp->n,firsti,0); + iguana_ramchain_link(dest,bp->hashes[starti],bp->hdrsi,bp->bundleheight,0,bp->n,firsti,0); + dest->expanded = 1; + dest->H.scriptoffset = 1; _iguana_ramchain_setptrs(RAMCHAIN_DESTPTRS,dest->H.data); - iguana_ramchain_extras(dest,&HASHMEM); - for (i=0; in; i++) + iguana_ramchain_extras(coin,dest,&HASHMEM,0); + for (i=starti; i<=endi; i++) { - if ( (block= bp->blocks[i]) != 0 && block == iguana_blockfind(coin,bp->hashes[i]) ) + if ( coin->active == 0 ) + { + iguana_bundlemapfree(coin,mem,&HASHMEM,ipbits,ptrs,filesizes,num,R,starti,endi); + return(-1); + } + if ( (block= bp->blocks[i]) != 0 )//&& block == iguana_blockfind("saveHT",coin,bp->hashes[i]) ) { - //printf("(%x:%x) ",(uint32_t)block->RO.hash2.ulongs[3],(uint32_t)bp->hashes[i].ulongs[3]); - if ( iguana_blockvalidate(coin,&valid,block,1) != 0 || (bp->bundleheight+i > 0 && bits256_nonz(block->RO.prev_block) == 0) ) + if ( bits256_nonz(block->RO.prev_block) == 0 && i > 0 ) + block->RO.prev_block = bp->hashes[i-1]; + if ( (bp->bundleheight+i > 0 && bits256_nonz(block->RO.prev_block) == 0) || iguana_blockvalidate(coin,&valid,block,1) < 0 ) { char str[65]; printf("null prevblock error at ht.%d patch.(%s)\n",bp->bundleheight+i,bits256_str(str,bp->hashes[i-1])); - block->queued = 0; - block->fpipbits = 0; - bp->issued[i] = 0; + iguana_bundlemapfree(coin,mem,&HASHMEM,ipbits,ptrs,filesizes,num,R,starti,endi); + iguana_blockunmark(coin,block,bp,i,1); return(-1); } destB[i] = block->RO; - } else printf("error getting block (%d:%d) %p vs %p\n",bp->hdrsi,i,block,iguana_blockfind(coin,bp->hashes[i])); + } else printf("error getting block (%d:%d) %p vs %p\n",bp->hdrsi,i,block,bp->blocks[i]); } dest->H.txidind = dest->H.unspentind = dest->H.spendind = dest->pkind = dest->H.data->firsti; - dest->externalind = 0; - //printf("\n"); - for (bundlei=0; bundlein; bundlei++) + dest->externalind = dest->H.stacksize = 0; + dest->H.scriptoffset = 1; + for (bundlei=starti; bundlei<=endi; bundlei++) { + if ( coin->active == 0 ) + break; if ( (block= bp->blocks[bundlei]) != 0 ) { iguana_blocksetcounters(coin,block,dest); coin->blocks.RO[bp->bundleheight+bundlei] = block->RO; destB[bundlei] = block->RO; - //printf("(%d %d) ",R[bundlei].H.data->numtxids,dest->H.txidind); - if ( (err= iguana_ramchain_iterate(coin,dest,&R[bundlei])) != 0 ) + //fprintf(stderr,"(%d %d).%d ",R[bundlei].H.data->numtxids,dest->H.txidind,bundlei); + if ( (err= iguana_ramchain_iterate(coin,dest,&R[bundlei],bp,bundlei)) != 0 ) { - printf("error ramchain_iterate hdrs.%d bundlei.%d\n",bp->hdrsi,bundlei); + if ( (block= bp->blocks[bundlei]) != 0 ) + { + iguana_bundlemapfree(coin,mem,&HASHMEM,ipbits,ptrs,filesizes,num,R,starti,endi); + iguana_blockunmark(coin,block,bp,bundlei,1); + return(-1); + } + if ( coin->active != 0 ) + printf("error ramchain_iterate hdrs.%d bundlei.%d\n",bp->hdrsi,bundlei); break; } } @@ -1884,43 +2624,54 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str break; } } + if ( dest->H.scriptoffset > dest->H.data->scriptspace ) + { + printf("bundlesave: stack smashed %d+%d > %d\n",dest->H.scriptoffset,dest->H.stacksize,dest->H.data->scriptspace); + bundlei = -1; + } + //printf(" about to save dest scriptoffset.%d stacksize.%d data scriptspace.%d\n",dest->H.scriptoffset,dest->H.stacksize,dest->H.data->scriptspace); depth--; - if ( bundlei == bp->n && iguana_ramchain_expandedsave(coin,RAMCHAIN_DESTARG,&newchain,&HASHMEM,0,bp) == 0 ) + memset(&newchain,0,sizeof(newchain)); + if ( bundlei == endi+1 && iguana_ramchain_expandedsave(coin,RAMCHAIN_DESTARG,&newchain,&HASHMEM,0,bp) == 0 ) { - char str[65],str2[65]; printf("%s d.%d ht.%d %s saved lag.%d elapsed.%ld\n",bits256_str(str2,newchain.H.data->sha256),depth,dest->height,mbstr(str,dest->H.data->allocsize),now-starttime,time(NULL)-now); + //char str[65]; printf("d.%d ht.%d %s saved lag.%d elapsed.%ld\n",depth,dest->height,mbstr(str,dest->H.data->allocsize),now-starttime,time(NULL)-now); retval = 0; - } - iguana_bundlemapfree(mem,&HASHMEM,ipbits,ptrs,filesizes,num,R,bp->n); + } else bp->generrs++; + iguana_bundlemapfree(coin,mem,&HASHMEM,ipbits,ptrs,filesizes,num,R,starti,endi); if ( retval == 0 ) { - //printf("delete %d files hdrs.%d retval.%d\n",num,bp->hdrsi,retval); - for (j=0; jhdrsi,retval,bp_n); + if ( iguana_bundleload(coin,&newchain,bp,0) == 0 ) + retval = -1; + else if ( bp_n == bp->n && bp->n == coin->chain->bundlesize && bp->hdrsi < coin->bundlescount-3 ) { - if ( iguana_peerfname(coin,&hdrsi,"tmp",fname,ipbits[j],bp->hashes[0],zero,1) >= 0 ) - coin->peers.numfiles -= OS_removefile(fname,0); - else printf("error removing.(%s)\n",fname); + for (j=starti; j<=endi; j++) + { + if ( iguana_peerfname(coin,&hdrsi,GLOBAL_TMPDIR,fname,0,bp->hashes[j],zero,1,1) >= 0 ) + coin->peers.numfiles -= OS_removefile(fname,0); + else printf("error removing.(%s)\n",fname); + } + //sprintf(dirname,"%s/%s/%d",GLOBAL_TMPDIR,coin->symbol,bp->bundleheight), OS_portable_rmdir(dirname,1); } + //sleep(1); + newchain.A = 0; } - iguana_ramchain_free(dest,0); - bp->ramchain = newchain; - if ( 0 ) + if ( coin->active != 0 ) { - bp->ramchain.hashmem = 0; - bp->ramchain.txids = 0; - bp->ramchain.pkhashes = 0; - bp->ramchain.fileptr = 0; - bp->ramchain.filesize = 0; + iguana_ramchain_free(coin,dest,0); + bp->ramchain = newchain; } - else iguana_bundleload(coin,bp); + //printf("finished bundlesave.%d retval.%d\n",bp->bundleheight,retval); return(retval); } -void iguana_mergefree(struct OS_memspace *mem,struct iguana_ramchain *A,struct iguana_ramchain *B,struct OS_memspace *hashmem,struct OS_memspace *hashmemA,struct OS_memspace *hashmemB) +void iguana_mergefree(struct iguana_info *coin,struct OS_memspace *mem,struct iguana_ramchain *A,struct iguana_ramchain *B,struct OS_memspace *hashmem,struct OS_memspace *hashmemA,struct OS_memspace *hashmemB) { if ( A != 0 ) - iguana_ramchain_free(A,0); + iguana_ramchain_free(coin,A,0); if ( B != 0 ) - iguana_ramchain_free(B,0); + iguana_ramchain_free(coin,B,0); if ( mem != 0 ) iguana_mempurge(mem); if ( hashmemA != 0 ) @@ -1929,56 +2680,56 @@ void iguana_mergefree(struct OS_memspace *mem,struct iguana_ramchain *A,struct i iguana_mempurge(hashmemB); } -int32_t iguana_bundlemergeHT(struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_bundle *bp,struct iguana_bundle *nextbp,uint32_t starttime) +int32_t iguana_bundlemergeHT(char *fname,struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_bundle *bp,struct iguana_bundle *nextbp,uint32_t starttime) { - static int32_t depth; static bits256 zero; + static int32_t depth; static const bits256 zero; RAMCHAIN_DESTDECLARE; struct OS_memspace HASHMEM,HASHMEMA,HASHMEMB; uint32_t now = (uint32_t)time(NULL); char str[65],fnameA[1024],fnameB[1024]; struct iguana_ramchain _Achain,_Bchain,*A,*B,R,newchain,*dest = &R; int32_t err,retval = -1,firsti = 1; memset(mem,0,sizeof(*mem)); memset(&HASHMEMA,0,sizeof(HASHMEMA)); - iguana_meminit(&HASHMEMA,"hashmemA",0,iguana_hashmemsize(bp->ramchain.H.txidind,bp->ramchain.H.unspentind,bp->ramchain.H.spendind,bp->ramchain.pkind,bp->ramchain.externalind) + 4096,0); + iguana_meminit(&HASHMEMA,"hashmemA",0,iguana_hashmemsize(bp->ramchain.H.txidind,bp->ramchain.H.unspentind,bp->ramchain.H.spendind,bp->ramchain.pkind,bp->ramchain.externalind,bp->ramchain.H.data->scriptspace) + IGUANA_MAXSCRIPTSIZE,0); memset(&HASHMEMB,0,sizeof(HASHMEMB)); - iguana_meminit(&HASHMEMB,"hashmemB",0,iguana_hashmemsize(nextbp->ramchain.H.txidind,nextbp->ramchain.H.unspentind,nextbp->ramchain.H.spendind,nextbp->ramchain.pkind,nextbp->ramchain.externalind) + 4096,0); + iguana_meminit(&HASHMEMB,"hashmemB",0,iguana_hashmemsize(nextbp->ramchain.H.txidind,nextbp->ramchain.H.unspentind,nextbp->ramchain.H.spendind,nextbp->ramchain.pkind,nextbp->ramchain.externalind,nextbp->ramchain.H.data->scriptspace) + IGUANA_MAXSCRIPTSIZE,0); memset(&_Achain,0,sizeof(_Achain)); A = &_Achain; memset(&_Bchain,0,sizeof(_Bchain)); B = &_Bchain; if ( (A= iguana_ramchain_map(coin,fnameA,bp,bp->ramchain.numblocks,A,&HASHMEMA,0,bp->hashes[0],zero,0,0,1,1)) != 0 ) { - iguana_ramchain_link(A,bp->hashes[0],bp->ramchain.lasthash2,bp->hdrsi,bp->bundleheight,0,bp->ramchain.numblocks,firsti,1); + iguana_ramchain_link(A,bp->hashes[0],bp->hdrsi,bp->bundleheight,0,bp->ramchain.numblocks,firsti,1); } if ( (B= iguana_ramchain_map(coin,fnameB,bp,nextbp->ramchain.numblocks,B,&HASHMEMB,0,nextbp->hashes[0],zero,0,0,1,1)) != 0 ) { - iguana_ramchain_link(B,bp->hashes[0],nextbp->ramchain.lasthash2,nextbp->hdrsi,nextbp->bundleheight,0,nextbp->ramchain.numblocks,firsti,1); + iguana_ramchain_link(B,bp->hashes[0],nextbp->hdrsi,nextbp->bundleheight,0,nextbp->ramchain.numblocks,firsti,1); } if ( A == 0 || B == 0 || A->H.data == 0 || B->H.data == 0 || (A->H.data->allocsize + B->H.data->allocsize) > IGUANA_MAXRAMCHAINSIZE ) { printf("MERGE error %d[%d] %d[%d]\n",A->height,A->numblocks,B->height,B->numblocks); - iguana_mergefree(mem,A,B,&HASHMEM,&HASHMEMA,&HASHMEMB); + iguana_mergefree(coin,mem,A,B,&HASHMEM,&HASHMEMA,&HASHMEMB); return(-1); } if ( A->H.data != 0 && B->H.data != 0 && B->height == A->height+A->numblocks ) { - if ( iguana_ramchain_alloc(coin,dest,mem,&HASHMEM,(A->H.data->numtxids+B->H.data->numtxids),(A->H.data->numunspents+B->H.data->numunspents),(A->H.data->numspends+B->H.data->numspends),(A->H.data->numpkinds+B->H.data->numpkinds),(A->H.data->numexternaltxids+B->H.data->numexternaltxids),A->height,A->numblocks + B->numblocks) < 0 ) + if ( iguana_ramchain_alloc(fname,coin,dest,mem,&HASHMEM,(A->H.data->numtxids+B->H.data->numtxids),(A->H.data->numunspents+B->H.data->numunspents),(A->H.data->numspends+B->H.data->numspends),(A->H.data->numpkinds+B->H.data->numpkinds),(A->H.data->numexternaltxids+B->H.data->numexternaltxids),A->H.data->scriptspace,A->height,A->numblocks + B->numblocks) < 0 ) { printf("depth.%d ht.%d fsize.%s ERROR alloc lag.%d elapsed.%ld\n",depth,dest->height,mbstr(str,dest->H.data->allocsize),now-starttime,time(NULL)-now); - iguana_mergefree(mem,A,B,&HASHMEM,&HASHMEMA,&HASHMEMB); + iguana_mergefree(coin,mem,A,B,&HASHMEM,&HASHMEMA,&HASHMEMB); return(-1); } depth++; - iguana_ramchain_link(dest,A->H.data->firsthash2,B->H.data->lasthash2,A->H.hdrsi,A->height,0,A->numblocks+B->numblocks,firsti,0); + iguana_ramchain_link(dest,A->H.data->firsthash2,A->H.hdrsi,A->height,0,A->numblocks+B->numblocks,firsti,0); _iguana_ramchain_setptrs(RAMCHAIN_DESTPTRS,dest->H.data); - iguana_ramchain_extras(dest,&HASHMEM); + iguana_ramchain_extras(coin,dest,&HASHMEM,0); dest->H.txidind = dest->H.unspentind = dest->H.spendind = dest->pkind = dest->H.data->firsti; dest->externalind = 0; - if ( (err= iguana_ramchain_iterate(coin,dest,A)) != 0 ) + if ( (err= iguana_ramchain_iterate(coin,dest,A,bp,-1)) != 0 ) printf("error.%d ramchain_iterate A.%d\n",err,A->height); - else if ( (err= iguana_ramchain_iterate(coin,dest,B)) != 0 ) + else if ( (err= iguana_ramchain_iterate(coin,dest,B,nextbp,-1)) != 0 ) printf("error.%d ramchain_iterate B.%d\n",err,B->height); else if ( iguana_ramchain_expandedsave(coin,RAMCHAIN_DESTARG,&newchain,&HASHMEM,0,0) == 0 ) { printf("merging isnt setup to save the blockROs\n"); printf("depth.%d ht.%d fsize.%s MERGED %d[%d] and %d[%d] lag.%d elapsed.%ld bp.%d -> %d\n",depth,dest->height,mbstr(str,dest->H.data->allocsize),A->height,A->numblocks,B->height,B->numblocks,now-starttime,time(NULL)-now,bp->bundleheight,nextbp->bundleheight); - iguana_mergefree(mem,A,B,&HASHMEM,&HASHMEMA,&HASHMEMB); + iguana_mergefree(coin,mem,A,B,&HASHMEM,&HASHMEMA,&HASHMEMB); bp->mergefinish = 0; nextbp->mergefinish = (uint32_t)time(NULL); bp->nextbp = nextbp->nextbp; @@ -1991,15 +2742,16 @@ int32_t iguana_bundlemergeHT(struct iguana_info *coin,struct OS_memspace *mem,st else { bp->mergefinish = nextbp->mergefinish = 0; - iguana_mergefree(mem,A,B,&HASHMEM,&HASHMEMA,&HASHMEMB); + iguana_mergefree(coin,mem,A,B,&HASHMEM,&HASHMEMA,&HASHMEMB); } - iguana_ramchain_free(dest,0); + iguana_ramchain_free(coin,dest,0); depth--; } else printf("error merging A.%d [%d] and B.%d [%d]\n",A->height,A->numblocks,B->height,B->numblocks); coin->merging--; return(retval); } +#ifdef later void iguana_ramchainmerge(struct iguana_info *coin) // jl777: verify prev/next hash2 { struct iguana_bundle *bp,*nextbp,*A,*B; int64_t total = 0; int32_t n,flag = 0; @@ -2011,7 +2763,7 @@ void iguana_ramchainmerge(struct iguana_info *coin) // jl777: verify prev/next h while ( bp != 0 && (nextbp= bp->nextbp) != 0 ) { n++; - if ( nextbp != 0 && bp != 0 && bp->emitfinish > coin->startutc && nextbp->emitfinish > coin->startutc && bp->mergefinish == 0 && nextbp->mergefinish == 0 && bp->ramchain.datasize + nextbp->ramchain.datasize < IGUANA_MAXRAMCHAINSIZE ) + if ( nextbp != 0 && bp != 0 && bp->emitfinish > 1 && nextbp->emitfinish > 1 && bp->mergefinish == 0 && nextbp->mergefinish == 0 && bp->ramchain.datasize + nextbp->ramchain.datasize < IGUANA_MAXRAMCHAINSIZE ) { if ( total == 0 || (bp->ramchain.datasize + nextbp->ramchain.datasize) < total ) { @@ -2041,3 +2793,4 @@ void iguana_ramchainmerge(struct iguana_info *coin) // jl777: verify prev/next h printf("bundles.%d\n",n); } } +#endif diff --git a/iguana/iguana_realtime.c b/iguana/iguana_realtime.c new file mode 100755 index 000000000..0780d59b0 --- /dev/null +++ b/iguana/iguana_realtime.c @@ -0,0 +1,357 @@ +/****************************************************************************** + * 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" + +void iguana_RTramchainfree(struct iguana_info *coin,struct iguana_bundle *bp) +{ + int32_t hdrsi; + if ( coin->utxotable != 0 ) + { + printf("free RTramchain\n"); + iguana_utxoupdate(coin,-1,0,0,0,0,-1); // free hashtables + coin->RTheight = coin->balanceswritten * coin->chain->bundlesize; + coin->RTgenesis = 0; + iguana_ramchain_free(coin,&coin->RTramchain,1); + if ( bp != 0 ) + bp->ramchain = coin->RTramchain; + iguana_mempurge(&coin->RTmem); + iguana_mempurge(&coin->RThashmem); + coin->RTdatabad = 0; + for (hdrsi=coin->bundlescount-1; hdrsi>0; hdrsi--) + if ( (bp= coin->bundles[hdrsi]) == 0 && bp != coin->current ) + { + iguana_volatilespurge(coin,&bp->ramchain); + if ( iguana_volatilesmap(coin,&bp->ramchain) != 0 ) + printf("error mapping bundle.[%d]\n",hdrsi); + } + printf("done RTramchain\n"); + } +} + +void *iguana_ramchainfile(struct iguana_info *coin,struct iguana_ramchain *dest,struct iguana_ramchain *R,struct iguana_bundle *bp,int32_t bundlei,struct iguana_block *block) +{ + char fname[1024]; long filesize; int32_t err; void *ptr=0; + if ( block == bp->blocks[bundlei] && (ptr= iguana_bundlefile(coin,fname,&filesize,bp,bundlei)) != 0 ) + { + if ( iguana_mapchaininit(fname,coin,R,bp,bundlei,block,ptr,filesize) >= 0 ) + { + if ( dest != 0 && dest->H.data != 0 ) + err = iguana_ramchain_iterate(coin,dest,R,bp,bundlei); + else err = 0; + if ( err != 0 || dest->H.data == 0 || bits256_cmp(R->H.data->firsthash2,block->RO.hash2) != 0 ) + { + char str[65]; + printf("ERROR [%d:%d] %s vs ",bp->hdrsi,bundlei,bits256_str(str,block->RO.hash2)); + printf("mapped.%s\n",bits256_str(str,R->H.data->firsthash2)); + } else return(ptr); + } + iguana_blockunmark(coin,block,bp,bundlei,1); + iguana_ramchain_free(coin,R,1); + } //else printf("ramchainfile ptr.%p block.%p\n",ptr,block); + return(0); +} + +void iguana_RTramchainalloc(char *fname,struct iguana_info *coin,struct iguana_bundle *bp) +{ + uint32_t i,changed = 0; struct iguana_ramchaindata *rdata; struct iguana_ramchain *dest = &coin->RTramchain; struct iguana_blockRO *B; struct iguana_bundle *tmpbp; + if ( (rdata= dest->H.data) != 0 ) + { + i = 0; + if ( coin->RTheight != bp->bundleheight + rdata->numblocks ) + changed++; + else + { + B = RAMCHAIN_PTR(rdata,Boffset); + //B = (void *)(long)((long)rdata + rdata->Boffset); + for (i=0; inumblocks; i++) + if ( bits256_cmp(B[i].hash2,bp->hashes[i]) != 0 ) + { + char str[65],str2[65]; printf("mismatched hash2 at %d %s vs %s\n",bp->bundleheight+i,bits256_str(str,B[i].hash2),bits256_str(str2,bp->hashes[i])); + changed++; + break; + } + } + if ( changed != 0 ) + { + printf("RTramchain changed %d bundlei.%d | coin->RTheight %d != %d bp->bundleheight + %d coin->RTramchain.H.data->numblocks\n",coin->RTheight,i,coin->RTheight,bp->bundleheight,rdata->numblocks); + //coin->RTheight = coin->balanceswritten * coin->chain->bundlesize; + iguana_RTramchainfree(coin,bp); + } + } + if ( coin->RTramchain.H.data == 0 ) + { + printf("ALLOC RTramchain\n"); + iguana_ramchainopen(fname,coin,dest,&coin->RTmem,&coin->RThashmem,bp->bundleheight,bp->hashes[0]); + dest->H.txidind = dest->H.unspentind = dest->H.spendind = dest->pkind = dest->H.data->firsti; + dest->externalind = dest->H.stacksize = 0; + dest->H.scriptoffset = 1; + if ( 1 ) + { + for (i=0; ihdrsi; i++) + if ( (tmpbp= coin->bundles[i]) != 0 ) + { + //iguana_volatilespurge(coin,&tmpbp->ramchain); + iguana_volatilesmap(coin,&tmpbp->ramchain); + } + sleep(1); + } + } +} + +void iguana_rdataset(struct iguana_ramchain *dest,struct iguana_ramchaindata *rdest,struct iguana_ramchain *src) +{ + *dest = *src; + dest->H.data = rdest; + *rdest = *src->H.data; + rdest->numpkinds = src->pkind; + rdest->numexternaltxids = src->externalind; + rdest->numtxids = src->H.txidind; + rdest->numunspents = src->H.unspentind; + rdest->numspends = src->H.spendind; + //printf("RT set numtxids.%u numspends.%u\n",rdest->numtxids,rdest->numspends); +} + +void iguana_rdatarestore(struct iguana_ramchain *dest,struct iguana_ramchaindata *rdest,struct iguana_ramchain *src) +{ + *src = *dest; + *src->H.data = *rdest; + src->pkind = rdest->numpkinds; + src->externalind = rdest->numexternaltxids; + src->H.txidind = rdest->numtxids; + src->H.unspentind = rdest->numunspents; + src->H.spendind = rdest->numspends; + printf("RT restore numtxids.%u numspends.%u\n",rdest->numtxids,rdest->numspends); +} + +void iguana_RThdrs(struct iguana_info *coin,struct iguana_bundle *bp,int32_t numaddrs) +{ + int32_t datalen,i; uint8_t serialized[512]; char str[65]; struct iguana_peer *addr; + for (i=0; ipeers.numranked; i++) + { + queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); + if ( (addr= coin->peers.ranked[i]) != 0 && addr->usock >= 0 && addr->dead == 0 && (datalen= iguana_gethdrs(coin,serialized,coin->chain->gethdrsmsg,bits256_str(str,bp->hashes[0]))) > 0 ) + { + iguana_send(coin,addr,serialized,datalen); + addr->pendhdrs++; + } + } +} + +void iguana_RTspendvectors(struct iguana_info *coin,struct iguana_bundle *bp) +{ + int32_t iterate,lasti,num,hdrsi,orignumemit; struct iguana_ramchain R; struct iguana_ramchaindata RDATA; + if ( bp->hdrsi <= 0 ) + return; + bp->ramchain = coin->RTramchain; + iguana_rdataset(&R,&RDATA,&coin->RTramchain); + if ( (lasti= (coin->RTheight - ((coin->RTheight/bp->n)*bp->n))) >= bp->n-1 ) + lasti = bp->n - 1; + orignumemit = bp->numtmpspends; +#ifdef __APPLE__ + iterate = 0*(coin->bundlescount-1); +#else + iterate = 0; +#endif + if ( iguana_spendvectors(coin,bp,&coin->RTramchain,coin->RTstarti,lasti,0,iterate) < 0 ) + { + printf("RTutxo error -> RTramchainfree\n"); + coin->RTdatabad = 1; + return; + } + else + { + printf("RTspendvectors calculated to %d [%d]\n",coin->RTheight,bp->hdrsi); + bp->converted = 1; + for (hdrsi=num=0; hdrsihdrsi; hdrsi++) + { +#ifdef __APPLE__ + if ( coin->bundles[hdrsi]->lastprefetch == 0 ) + { + iguana_ramchain_prefetch(coin,&coin->bundles[hdrsi]->ramchain,2); + coin->bundles[hdrsi]->lastprefetch = (uint32_t)time(NULL); + } +#endif + num += iguana_convert(coin,IGUANA_NUMHELPERS,coin->bundles[hdrsi],1,orignumemit); + } + printf("RTspendvectors converted.%d to %d\n",num,coin->RTheight); + bp->converted = (uint32_t)time(NULL); + if ( iguana_balancegen(coin,1,bp,coin->RTstarti,coin->RTheight > 0 ? coin->RTheight-1 : bp->n-1,orignumemit) < 0 ) + coin->RTdatabad = 1; + else if ( coin->RTgenesis == 0 ) + printf(">>>>>> IGUANA %s READY FOR REALTIME RPC <<<<<<\n",coin->symbol); + //printf("iguana_balancegen [%d] (%d to %d)\n",bp->hdrsi,coin->RTstarti,(coin->RTheight-1)%bp->n); + coin->RTstarti = (coin->RTheight % bp->n); + } +} + +int32_t iguana_realtime_update(struct iguana_info *coin) +{ + double startmillis0; static double totalmillis0; static int32_t num0; + struct iguana_bundle *bp; struct iguana_ramchaindata *rdata; int32_t bundlei,i,n,flag=0; bits256 hash2,*ptr; struct iguana_peer *addr; + struct iguana_block *block=0; struct iguana_blockRO *B; struct iguana_ramchain *dest=0,blockR; + if ( coin->current != 0 && (coin->blocks.hwmchain.height % coin->chain->bundlesize) == coin->chain->bundlesize-1 && coin->blocks.hwmchain.height/coin->chain->bundlesize == coin->longestchain/coin->chain->bundlesize ) + { + block = coin->current->blocks[coin->current->n - 1]; + if ( _iguana_chainlink(coin,block) <= 0 ) + { + //printf("RT edge case couldnt link\n"); + } + else printf("RT edge case.%d\n",block->height); + } + if ( coin->spendvectorsaved <= 1 ) + return(0); + for (i=0; ibundlescount-1; i++) + { + if ( (bp= coin->bundles[i]) != 0 && (i > 0 && bp->utxofinish == 0) ) + { + if ( iguana_spendvectors(coin,bp,&bp->ramchain,0,bp->n,0,0) < 0 ) + { + printf("error generating spendvectors.[%d], exiting. just restart iguana\n",i); + exit(-1); + } // else printf("generated UTXO.[%d]\n",i); + coin->spendvectorsaved = 1; + } + } + bp = coin->current; + if ( bp == 0 || iguana_validated(coin) < bp->hdrsi ) + return(0); + if ( 1 && coin->RTheight > 0 && coin->spendvectorsaved != 1 && coin->bundlescount-1 != coin->balanceswritten ) + { + printf("RT mismatch %d != %d\n",coin->bundlescount-1,coin->balanceswritten); + coin->spendvectorsaved = 0; + iguana_RTramchainfree(coin,coin->current); + return(0); + } + if ( coin->RTdatabad == 0 && bp->hdrsi == coin->longestchain/coin->chain->bundlesize && bp->hdrsi >= coin->balanceswritten && coin->RTheight >= bp->bundleheight && coin->RTheight < bp->bundleheight+bp->n && ((coin->RTheight < coin->blocks.hwmchain.height && time(NULL) > bp->lastRT) || time(NULL) > bp->lastRT+10) ) + { + if ( (block= bp->blocks[0]) == 0 || block->txvalid == 0 || block->mainchain == 0 ) + { + if ( block != 0 ) + { + if ( _iguana_chainlink(coin,block) <= 0 ) + { + iguana_blockunmark(coin,block,bp,0,0); + bp->issued[0] = 0; + hash2 = bp->hashes[0]; + //char str[65]; printf("RT[0] [%d:%d] %s %p\n",bp->hdrsi,0,bits256_str(str,hash2),block); + addr = coin->peers.ranked[rand() % 8]; + if ( addr != 0 && addr->usock >= 0 && addr->dead == 0 ) + iguana_sendblockreqPT(coin,addr,bp,0,hash2,0); + } + } + } + //char str[65]; printf("check longest.%d RTheight.%d hwm.%d %s %p\n",coin->longestchain,coin->RTheight,coin->blocks.hwmchain.height,bits256_str(str,bp->hashes[0]),block); + if ( bits256_cmp(coin->RThash1,bp->hashes[1]) != 0 ) + coin->RThash1 = bp->hashes[1]; + bp->lastRT = (uint32_t)time(NULL); + if ( coin->RTheight < coin->longestchain && coin->peers.numranked > 0 && time(NULL) > coin->RThdrstime+10 ) + { + iguana_RThdrs(coin,bp,coin->peers.numranked); + coin->RThdrstime = bp->lastRT; + for (i=0; ipeers.numranked; i++) + { + if ( (addr= coin->peers.ranked[i]) != 0 && addr->usock >= 0 && addr->dead == 0 ) + { + //printf("%d ",addr->numRThashes); + } + } + //printf("RTheaders %s\n",coin->symbol); + } + bp->lastRT = (uint32_t)time(NULL); + iguana_RTramchainalloc("RTbundle",coin,bp); + bp->isRT = 1; + while ( (rdata= coin->RTramchain.H.data) != 0 && coin->RTheight <= coin->blocks.hwmchain.height ) + { + if ( coin->RTdatabad != 0 ) + break; + dest = &coin->RTramchain; + B = RAMCHAIN_PTR(rdata,Boffset); + //B = (void *)(long)((long)rdata + rdata->Boffset); + bundlei = (coin->RTheight % coin->chain->bundlesize); + if ( (block= iguana_bundleblock(coin,&hash2,bp,bundlei)) != 0 ) + iguana_bundlehashadd(coin,bp,bundlei,block); + //printf("RT.%d vs hwm.%d starti.%d bp->n %d block.%p/%p ramchain.%p\n",coin->RTheight,coin->blocks.hwmchain.height,coin->RTstarti,bp->n,block,bp->blocks[bundlei],dest->H.data); + if ( coin->RTdatabad == 0 && block != 0 && bits256_nonz(block->RO.prev_block) != 0 ) + { + iguana_blocksetcounters(coin,block,dest); + startmillis0 = OS_milliseconds(); + if ( coin->RTdatabad == 0 && iguana_ramchainfile(coin,dest,&blockR,bp,bundlei,block) == 0 ) + { + for (i=0; in; i++) + if ( GETBIT(bp->haveblock,i) == 0 ) + bp->issued[i] = 0; + if ( (n= iguana_bundleissuemissing(coin,bp,3,1.)) > 0 ) + printf("RT issued %d priority requests [%d] to unstick stuckiters.%d\n",n,bp->hdrsi,coin->stuckiters); + for (i=bundlei; in; i++) + { + block = iguana_bundleblock(coin,&hash2,bp,i); + if ( bits256_nonz(hash2) != 0 && (block == 0 || block->txvalid == 0) ) + { + uint8_t serialized[512]; int32_t len; struct iguana_peer *addr; + //char str[65]; printf("RT error [%d:%d] %s %p\n",bp->hdrsi,i,bits256_str(str,hash2),block); + addr = coin->peers.ranked[rand() % 8]; + if ( addr != 0 && addr->usock >= 0 && addr->dead == 0 && (len= iguana_getdata(coin,serialized,MSG_BLOCK,&hash2,1)) > 0 ) + iguana_send(coin,addr,serialized,len); + coin->RTgenesis = 0; + } + if ( bits256_nonz(hash2) != 0 ) + iguana_blockQ("RTerr",coin,bp,i,hash2,1); + break; + } + return(-1); + } else iguana_ramchain_free(coin,&blockR,1); + B[bundlei] = block->RO; + totalmillis0 += (OS_milliseconds() - startmillis0); + num0++; + flag++; + coin->blocks.RO[bp->bundleheight+bundlei] = block->RO; + coin->RTheight++; + printf(">>>> RT.%d hwm.%d L.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld\n",coin->RTheight,coin->blocks.hwmchain.height,coin->longestchain,dest->H.txidind,dest->H.unspentind,dest->H.spendind,dest->pkind,dest->externalind,(long)dest->H.data->allocsize); + if ( coin->RTramchain.H.data != 0 ) + coin->RTramchain.H.data->numblocks = bundlei + 1; + else break; + } else break; + } + } + n = 0; + if ( coin->RTdatabad == 0 && dest != 0 && flag != 0 && coin->RTheight >= coin->longestchain ) + { + //printf("ramchainiterate.[%d] ave %.2f micros, total %.2f seconds starti.%d num.%d\n",num0,(totalmillis0*1000.)/num0,totalmillis0/1000.,coin->RTstarti,coin->RTheight%bp->n); + if ( (n= iguana_walkchain(coin,1)) == coin->RTheight-1 ) + { + //printf("RTgenesis verified\n"); + iguana_RTspendvectors(coin,bp); + coin->RTgenesis = (uint32_t)time(NULL); + } else coin->RTdatabad = 1; + } + if ( dest != 0 && flag != 0 ) + printf("<<<< flag.%d RT.%d:%d hwm.%d L.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld\n",flag,coin->RTheight,n,coin->blocks.hwmchain.height,coin->longestchain,dest->H.txidind,dest->H.unspentind,dest->H.spendind,dest->pkind,dest->externalind,dest->H.data!=0?(long)dest->H.data->allocsize:-1); + if ( coin->RTdatabad != 0 ) + { + iguana_RTramchainfree(coin,bp); + //memset(bp->hashes,0,sizeof(bp->hashes)); + memset(bp->blocks,0,sizeof(bp->blocks)); + if ( 0 && bp->speculative != 0 ) + { + ptr = bp->speculative; + bp->speculative = 0; + memset(ptr,0,sizeof(*bp->speculative)*bp->n); + myfree(ptr,(bp->n+1)*sizeof(*bp->speculative)); + } + iguana_RTramchainalloc("RTbundle",coin,bp); + } + return(flag); +} diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 1bdfd61ba..b3dc5a749 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -17,6 +17,9 @@ // peer context, ie massively multithreaded -> bundlesQ +static int32_t numDuplicates,numAfteremit; +static int64_t sizeDuplicates,sizeAfteremit; + struct iguana_bundlereq *iguana_bundlereq(struct iguana_info *coin,struct iguana_peer *addr,int32_t type,int32_t datalen) { struct iguana_bundlereq *req; int32_t allocsize; @@ -30,30 +33,78 @@ struct iguana_bundlereq *iguana_bundlereq(struct iguana_info *coin,struct iguana return(req); } +int32_t iguana_speculativesearch(struct iguana_info *coin,struct iguana_block **blockptrp,bits256 hash2) +{ + int32_t i,j; struct iguana_bundle *bp; + if ( blockptrp != 0 ) + *blockptrp = 0; + for (i=0; ibundlescount; i++) + { + if ( (bp= coin->bundles[i]) != 0 && bp->speculative != 0 ) + { + for (j=0; jn&&jnumspec; j++) + if ( bits256_cmp(hash2,bp->speculative[j]) == 0 ) + { + if ( blockptrp != 0 ) + *blockptrp = bp->blocks[j]; + if ( bp->speculativecache[j] != 0 ) + return(1); + else return(-1); + } + } + } + return(0); +} + int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t iamthreadsafe) { static bits256 lastreq,lastreq2; - int32_t len; uint8_t serialized[sizeof(struct iguana_msghdr) + sizeof(uint32_t)*32 + sizeof(bits256)]; + int32_t len,j; struct iguana_bundle *checkbp; uint8_t serialized[sizeof(struct iguana_msghdr) + sizeof(uint32_t)*32 + sizeof(bits256)]; struct iguana_block *block=0; char hexstr[65]; init_hexbytes_noT(hexstr,hash2.bytes,sizeof(hash2)); - if ( memcmp(lastreq.bytes,hash2.bytes,sizeof(hash2)) == 0 || memcmp(lastreq2.bytes,hash2.bytes,sizeof(hash2)) == 0 ) + if ( addr == 0 || memcmp(lastreq.bytes,hash2.bytes,sizeof(hash2)) == 0 || memcmp(lastreq2.bytes,hash2.bytes,sizeof(hash2)) == 0 ) { - //printf("duplicate req\n"); - return(0); + //printf("duplicate req %s or null addr.%p\n",bits256_str(hexstr,hash2),addr); + // if ( (rand() % 10 ) != 0 ) + return(0); + } + checkbp = 0, j = -2; + if ( (checkbp= iguana_bundlefind(coin,&checkbp,&j,hash2)) != 0 && j >= 0 && j < checkbp->n ) + { + if ( checkbp->emitfinish != 0 || ((block= checkbp->blocks[j]) != 0 && block->txvalid != 0) ) + { + //printf("found valid [%d:%d] in blockreqPT\n",checkbp->hdrsi,j); + return(0); + } + } + if ( 1 && coin->enableCACHE != 0 && iguana_speculativesearch(coin,&block,hash2) != 0 ) + { + if ( block != 0 && block->hdrsi != 0 && block->bundlei != 0 ) + { + //printf("found valid [%d:%d] in blockreqPT txvalid.%d\n",block!=0?block->hdrsi:-1,block!=0?block->bundlei:-1,block->txvalid); + if ( block->txvalid != 0 ) + return(0); + } } - lastreq2 = lastreq; - lastreq = hash2; if ( addr->msgcounts.verack == 0 ) { - printf("iguana_sendblockreq %s hasn't verack'ed yet\n",addr->ipaddr); + //printf("iguana_sendblockreq (%s) addrind.%d hasn't verack'ed yet\n",addr->ipaddr,addr->addrind); + //iguana_send_version(coin,addr,coin->myservices); return(-1); } - if ( (len= iguana_getdata(coin,serialized,MSG_BLOCK,hexstr)) > 0 ) + lastreq2 = lastreq; + lastreq = hash2; + if ( (len= iguana_getdata(coin,serialized,MSG_BLOCK,&hash2,1)) > 0 ) { iguana_send(coin,addr,serialized,len); coin->numreqsent++; addr->pendblocks++; addr->pendtime = (uint32_t)time(NULL); - //printf("REQ.%s bundlei.%d hdrsi.%d\n",bits256_str(hexstr,hash2),bundlei,bp!=0?bp->hdrsi:-1); + if ( bp != 0 && bundlei >= 0 && bundlei < bp->n ) + bp->issued[bundlei] = addr->pendtime; + if ( block != 0 ) + block->issued = addr->pendtime; + if ( 0 && coin->current == bp ) + printf("REQ.%s bundlei.%d hdrsi.%d\n",bits256_str(hexstr,hash2),bundlei,bp!=0?bp->hdrsi:-1); } else printf("MSG_BLOCK null datalen.%d\n",len); return(len); } @@ -61,8 +112,8 @@ int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr, int32_t iguana_sendtxidreq(struct iguana_info *coin,struct iguana_peer *addr,bits256 hash2) { uint8_t serialized[sizeof(struct iguana_msghdr) + sizeof(uint32_t)*32 + sizeof(bits256)]; - int32_t len,i,r,j; char hexstr[65]; init_hexbytes_noT(hexstr,hash2.bytes,sizeof(hash2)); - if ( (len= iguana_getdata(coin,serialized,MSG_TX,hexstr)) > 0 ) + int32_t len,i,r,j; //char hexstr[65]; init_hexbytes_noT(hexstr,hash2.bytes,sizeof(hash2)); + if ( (len= iguana_getdata(coin,serialized,MSG_TX,&hash2,1)) > 0 ) { if ( addr == 0 ) { @@ -107,13 +158,146 @@ void iguana_gotunconfirmedM(struct iguana_info *coin,struct iguana_peer *addr,st req->datalen = datalen; req->txid = tx->txid; memcpy(req->serialized,data,datalen); - queue_enqueue("bundlesQ",&coin->bundlesQ,&req->DL,0); + queue_enqueue("recvQ",&coin->recvQ,&req->DL,0); +} + +#ifdef later +struct iguana_txblock *iguana_peertxdata(struct iguana_info *coin,int32_t *bundleip,char *fname,struct OS_memspace *mem,uint32_t ipbits,bits256 hash2) +{ + int32_t bundlei,datalen,checki,hdrsi,fpos; char str[65],str2[65]; FILE *fp; + bits256 checkhash2; struct iguana_txblock *txdata = 0; static const bits256 zero; + if ( (bundlei= iguana_peerfname(coin,&hdrsi,GLOBAL_TMPDIR,fname,ipbits,hash2,zero,1)) >= 0 ) + //if ( (bundlei= iguana_peerfname(coin,&hdrsi,fname,ipbits,hash2)) >= 0 ) + { + if ( (fp= fopen(fname,"rb")) != 0 ) + { + fseek(fp,bundlei * sizeof(bundlei),SEEK_SET); + fread(&fpos,1,sizeof(fpos),fp); + fseek(fp,fpos,SEEK_SET); + fread(&checki,1,sizeof(checki),fp); + if ( ftell(fp)-sizeof(checki) == fpos && bundlei == checki ) + { + fread(&checkhash2,1,sizeof(checkhash2),fp); + if ( memcmp(hash2.bytes,checkhash2.bytes,sizeof(hash2)) == 0 ) + { + fread(&datalen,1,sizeof(datalen),fp); + if ( datalen < (mem->totalsize - mem->used - 4) ) + { + if ( (txdata= iguana_memalloc(mem,datalen,0)) != 0 ) + { + fread(txdata,1,datalen,fp); + if ( txdata->datalen != datalen || txdata->block.bundlei != bundlei ) + { + printf("%s peertxdata txdata->datalen.%d != %d bundlei.%d vs %d\n",bits256_str(str,txdata->block.RO.hash2),txdata->datalen,datalen,txdata->block.bundlei,bundlei); + //getchar(); + txdata = 0; + iguana_memreset(mem); + } //else printf("SUCCESS txdata.%s bundlei.%d fpos.%d T.%d U.%d S.%d P.%d\n",bits256_str(str,txdata->block.hash2),bundlei,fpos,txdata->numtxids,txdata->numunspents,txdata->numspends,txdata->numpkinds); + } else printf("peertxdata error allocating txdata\n"); + } else printf("mismatch peertxdata datalen %d vs %ld totalsize %ld\n",datalen,mem->totalsize - mem->used - 4,(long)mem->totalsize); + } else printf("peertxdata hash mismatch %s != %s\n",bits256_str(str,hash2),bits256_str(str2,checkhash2)); + } else printf("peertxdata bundlei.%d != checki.%d, fpos.%d ftell.%ld\n",bundlei,checki,fpos,ftell(fp)); + fclose(fp); + } else printf("cant find file.(%s)\n",fname); + } //else printf("bundlei.%d\n",bundlei); + *bundleip = bundlei; + return(txdata); +} +#endif + +int32_t iguana_speculativefind(struct iguana_info *coin,struct iguana_bundle *bp,struct iguana_block *block,uint8_t *data,int32_t recvlen) +{ + int32_t i,j,numcached,cachelen; uint8_t *tmp; char str[65]; + if ( coin->enableCACHE == 0 ) + return(-1); + if ( recvlen < 0 || recvlen > IGUANA_MAXPACKETSIZE ) + { + printf("iguana_speculativefind: illegal recvlen.%d\n",recvlen); + return(-1); + } + for (i=0; in; i++) + { + if ( bits256_cmp(bp->speculative[i],block->RO.hash2) == 0 ) + { + if ( (tmp= bp->speculativecache[i]) != 0 ) + { + memcmp(&cachelen,tmp,sizeof(cachelen)); + if ( cachelen < 0 || cachelen > IGUANA_MAXPACKETSIZE ) + { + printf("illegal cachelen.%d %s [%d:%d] %p\n",cachelen,coin->symbol,bp->hdrsi,i,tmp); + bp->speculativecache[i] = 0; + continue; + } + if ( memcmp(&recvlen,tmp,sizeof(recvlen)) != 0 || memcmp(&tmp[sizeof(recvlen)],data,recvlen) != 0 ) + printf("cachedata ERROR [%d:%d] already has recvlen.%d vs %d for %s\n",bp->hdrsi,i,recvlen,cachelen,bits256_str(str,block->RO.hash2)); + return(0); + } + bp->speculativecache[i] = calloc(1,recvlen + sizeof(recvlen)); + memcpy(bp->speculativecache[i],&recvlen,sizeof(recvlen)); + memcpy(&bp->speculativecache[i][sizeof(recvlen)],data,recvlen); + for (j=numcached=0; jn; j++) + if ( bp->speculativecache[j] != 0 ) + numcached++; + if ( 0 && bp == coin->current ) + printf("cache %s [%d:%d] h.%d s.%d c.%d -> %d\n",bits256_str(str,block->RO.hash2),bp->hdrsi,i,bp->numhashes,bp->numsaved,bp->numcached,numcached); + return(i); + } + } + return(-1); +} + +int8_t iguana_blockstatus(struct iguana_info *coin,struct iguana_block *block) +{ + int32_t status = 0; + if ( block->RO.recvlen != 0 ) + status |= 1; + if ( block->fpipbits != 0 ) + status |= 2; + if ( block->fpos >= 0 ) + status |= 4; + if ( bits256_nonz(block->RO.prev_block) != 0 ) + status |= 8; + if ( block->queued != 0 ) + status |= 0xc0; // force negative, 0x80 can be +128 + return(status); +} + +void iguana_bundletime(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei,struct iguana_block *block,int32_t duplicateflag) +{ + uint32_t starttime; int32_t duration; + if ( bp != 0 && bundlei >= 0 && bundlei < bp->n && block != 0 ) + { + starttime = block->issued; + if ( starttime == 0 || bp->issued[bundlei] > block->issued ) + starttime = bp->issued[bundlei]; + bp->issued[bundlei] = 1; + if ( starttime != 0 ) + { + duration = (uint32_t)time(NULL) - starttime; + if ( duplicateflag != 0 ) + { + bp->duplicatedurations += duration; + bp->duplicatescount++; + } + else + { + bp->totaldurations += duration; + bp->durationscount++; + } + if ( (block= bp->blocks[bundlei]) != 0 && block->lag == 0 ) + block->lag = duration; + } + } } void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_txblock *origtxdata,struct iguana_msgtx *txarray,struct iguana_msghdr *H,uint8_t *data,int32_t recvlen) { - struct iguana_bundlereq *req; struct iguana_txblock *txdata = 0; int32_t i,j,bundlei,copyflag; char fname[1024]; - struct iguana_bundle *bp; + struct iguana_bundlereq *req; struct iguana_txblock *txdata = 0; int32_t valid,speculative=0,i,j,bundlei,copyflag; struct iguana_block *block; struct iguana_bundle *bp; uint32_t now; char str[65]; + if ( recvlen < 0 || recvlen > IGUANA_MAXPACKETSIZE ) + { + printf("iguana_getblockM: illegal recvlen.%d\n",recvlen); + return; + } if ( 0 ) { for (i=0; ispace[0]; i++) @@ -139,16 +323,124 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i } } } - copyflag = 1 * (strcmp(coin->symbol,"BTC") != 0); - req = iguana_bundlereq(coin,addr,'B',copyflag * recvlen); - req->recvlen = recvlen; - req->H = *H; + if ( iguana_blockvalidate(coin,&valid,&origtxdata->block,1) < 0 ) + { + printf("got block that doesnt validate? %s\n",bits256_str(str,origtxdata->block.RO.hash2)); + return; + } + else if ( 0 && coin->enableCACHE != 0 ) + printf("cache.%d validated.(%s)\n",coin->enableCACHE,bits256_str(str,origtxdata->block.RO.hash2)); + origtxdata->block.txvalid = 1; + if ( addr != 0 && addr != &coin->internaladdr ) + { + static uint64_t received[IGUANA_MAXPEERS],count[IGUANA_MAXPEERS],lastcount,lastreceived,last; + received[addr->addrind] += recvlen; + count[addr->addrind]++; + now = (uint32_t)time(NULL); + if ( ((rand() % 100) == 0 && now > last+10) || now > last+60 ) + { + int64_t sum2 = 0,sum = 0,diffr,diff; double bw = 0.; + for (i=0; i coin->maxbandwidth ) + coin->maxbandwidth = bw; + } + dxblend(&coin->bandwidth,bw,.9); + char str[65],str2[65],str3[65],str4[65]; printf("%s BLOCKS.%llu RECV %s ave %.1f | dup.%d %s after.%d %s %s/sec %.2f%% %s\n",coin->symbol,(long long)sum2,mbstr(str,sum),(double)sum/(sum2!=0?sum2:1),numDuplicates,mbstr(str2,sizeDuplicates),numAfteremit,mbstr(str3,sizeAfteremit),mbstr(str4,bw),coin->maxbandwidth!=0.?100.*coin->bandwidth/coin->maxbandwidth:0.,coin->maxbandwidth>4*coin->bandwidth?"SLOW":""); + last = now; + } + if ( coin->bandwidth < 0.25*coin->maxbandwidth ) + { + //printf(">>SLOW.%d<< ",addr->addrind); + //iguana_blast(coin,addr); + } + } + copyflag = 0;//(coin->enableCACHE != 0) && (strcmp(coin->symbol,"BTC") != 0); bp = 0, bundlei = -2; - if ( copyflag != 0 && recvlen != 0 && ((bp= iguana_bundlefind(coin,&bp,&bundlei,origtxdata->block.RO.hash2)) == 0 || (bp->blocks[bundlei] != 0 && bp->blocks[bundlei]->fpipbits == 0)) ) + bp = iguana_bundlefind(coin,&bp,&bundlei,origtxdata->block.RO.hash2); + if ( bp != 0 && bundlei >= 0 && bundlei < bp->n ) + { + block = bp->blocks[bundlei]; + if ( bp->emitfinish != 0 ) + { + numAfteremit++; + sizeAfteremit += recvlen; + if ( block != 0 ) + iguana_bundletime(coin,bp,bundlei,block,1); + //printf("got [%d:%d] with emitfinish.%u\n",bp->hdrsi,bundlei,bp->emitfinish); + return; + } + bp->dirty++; + if ( bundlei >= 0 && block != 0 ) + { + if ( iguana_blockstatus(coin,block) != 0 && block->txvalid != 0 ) + { + numDuplicates++; + sizeDuplicates += recvlen; + iguana_bundletime(coin,bp,bundlei,block,1); + //printf("duplicate [%d:%d] %s\n",bp->hdrsi,bundlei,bits256_str(str,block->RO.hash2)); + if ( bits256_cmp(origtxdata->block.RO.hash2,block->RO.hash2) == 0 ) + return; + else printf("mismatched tx received? mainchain.%d\n",block->mainchain); + if ( block->mainchain != 0 ) + return; + } + else + { + iguana_bundletime(coin,bp,bundlei,block,0); + if ( 0 && bp == coin->current ) + printf("recv [%d:%d] %s\n",bp->hdrsi,bundlei,bits256_str(str,block->RO.hash2)); + } + block->RO = origtxdata->block.RO; + block->txvalid = 1; + /*if ( block->serdata == 0 ) + { + block->serdata = malloc(recvlen); + memcpy(block->serdata,data,recvlen); + }*/ + //printf("update prev for [%d:%d]\n",bp->hdrsi,bundlei); + } + } + else + { + if ( (bp= coin->current) != 0 ) + { + for (i=0; ibundlescount; i++) + { + if ( (bp= coin->bundles[i]) != 0 && bp->emitfinish == 0 && bp->speculative != 0 && bp->numhashes < bp->n ) + { + if ( (j= iguana_speculativefind(coin,bp,&origtxdata->block,data,recvlen)) >= 0 ) + { + copyflag = 0; + speculative = 1; + if ( bp->blocks[j] != 0 ) + iguana_bundletime(coin,bp,j,bp->blocks[j],0); + break; + } + } + } + } + } + if ( copyflag != 0 && recvlen != 0 && (bp == 0 || bundlei < 0 || ((block= bp->blocks[bundlei]) != 0 && iguana_blockstatus(coin,block) == 0)) ) + { + req = iguana_bundlereq(coin,addr,'B',copyflag * recvlen); + req->copyflag = 1; + //printf("copy %p serialized[%d]\n",req,req->recvlen); + memcpy(req->serialized,data,recvlen); + } + else { - //printf("copy %p serialized[%d]\n",req->serialized,req->recvlen); - memcpy(req->serialized,data,recvlen), req->copyflag = 1; + copyflag = 0; + req = iguana_bundlereq(coin,addr,'B',0); } + req->recvlen = recvlen; + req->H = *H; if ( bits256_cmp(origtxdata->block.RO.hash2,coin->APIblockhash) == 0 ) { printf("MATCHED APIblockhash\n"); @@ -163,12 +455,14 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i addr->lastblockrecv = (uint32_t)time(NULL); addr->recvblocks += 1.; addr->recvtotal += recvlen; - if ( iguana_ramchain_data(coin,addr,origtxdata,txarray,origtxdata->block.RO.txn_count,data,recvlen) >= 0 ) + if ( speculative == 0 && iguana_ramchain_data(coin,addr,origtxdata,txarray,origtxdata->block.RO.txn_count,data,recvlen) > 0 ) { txdata->block.fpipbits = (uint32_t)addr->ipbits; + txdata->block.RO.recvlen = recvlen; + txdata->block.fpos = 0; req->datalen = txdata->datalen; req->ipbits = txdata->block.fpipbits; - if ( 0 ) + /*if ( 0 ) { struct iguana_txblock *checktxdata; struct OS_memspace checkmem; int32_t checkbundlei; memset(&checkmem,0,sizeof(checkmem)); @@ -178,16 +472,17 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i printf("check datalen.%d bundlei.%d T.%d U.%d S.%d P.%d X.%d\n",checktxdata->datalen,checkbundlei,checktxdata->numtxids,checktxdata->numunspents,checktxdata->numspends,checktxdata->numpkinds,checktxdata->numexternaltxids); } iguana_mempurge(&checkmem); - } + }*/ } } - //printf("recvlen.%d\n",req->recvlen); req->block = txdata->block; + //printf("recvlen.%d ipbits.%x prev.(%s)\n",req->block.RO.recvlen,req->block.fpipbits,bits256_str(str,txdata->block.RO.prev_block)); req->block.RO.txn_count = req->numtx = txdata->block.RO.txn_count; coin->recvcount++; coin->recvtime = (uint32_t)time(NULL); req->addr = addr; - queue_enqueue("bundlesQ",&coin->bundlesQ,&req->DL,0); + netBLOCKS++; + queue_enqueue("recvQ",&coin->recvQ,&req->DL,0); } void iguana_gottxidsM(struct iguana_info *coin,struct iguana_peer *addr,bits256 *txids,int32_t n) @@ -196,125 +491,111 @@ void iguana_gottxidsM(struct iguana_info *coin,struct iguana_peer *addr,bits256 //printf("got %d txids from %s\n",n,addr->ipaddr); req = iguana_bundlereq(coin,addr,'T',0); req->hashes = txids, req->n = n; - queue_enqueue("bundlesQ",&coin->bundlesQ,&req->DL,0); + queue_enqueue("recvQ",&coin->recvQ,&req->DL,0); } void iguana_gotheadersM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_block *blocks,int32_t n) { - struct iguana_bundlereq *req; + struct iguana_bundlereq *req; int32_t i,num; if ( addr != 0 ) { + static uint32_t hdrsreceived[IGUANA_MAXPEERS]; + hdrsreceived[addr->addrind] += n; + char str[65]; + if ( (rand() % 1000) == 0 ) + { + uint32_t i,sum = 0; + for (i=0; i %s\n",sum,mbstr(str,sum*80)); + } addr->recvhdrs++; if ( addr->pendhdrs > 0 ) addr->pendhdrs--; //printf("%s blocks[%d] ht.%d gotheaders pend.%d %.0f\n",addr->ipaddr,n,blocks[0].height,addr->pendhdrs,milliseconds()); + if ( bits256_cmp(blocks[1].RO.hash2,coin->RThash1) == 0 ) + { + num = (n < coin->chain->bundlesize ? n : coin->chain->bundlesize); + for (i=0; iRThashes[i] = blocks[i].RO.hash2; + addr->numRThashes = num; + } } req = iguana_bundlereq(coin,addr,'H',0); req->blocks = blocks, req->n = n; - queue_enqueue("bundlesQ",&coin->bundlesQ,&req->DL,0); + HDRnet++; + //char str[65]; printf("PTblockhdrs.%s net.%d blocks.%d\n",bits256_str(str,blocks[0].RO.hash2),HDRnet,netBLOCKS); + queue_enqueue("recvQ",&coin->recvQ,&req->DL,0); } void iguana_gotblockhashesM(struct iguana_info *coin,struct iguana_peer *addr,bits256 *blockhashes,int32_t n) { - struct iguana_bundlereq *req; + struct iguana_bundlereq *req; int32_t num; if ( addr != 0 ) { addr->recvhdrs++; if ( addr->pendhdrs > 0 ) addr->pendhdrs--; - } - req = iguana_bundlereq(coin,addr,'S',0); - req->hashes = blockhashes, req->n = n; - //printf("bundlesQ blockhashes.%p[%d]\n",blockhashes,n); - queue_enqueue("bundlesQ",&coin->bundlesQ,&req->DL,0); -} - -void iguana_patch(struct iguana_info *coin,struct iguana_block *block) -{ - int32_t i,j,origheight,height; struct iguana_block *prev,*next; struct iguana_bundle *bp; - prev = iguana_blockhashset(coin,-1,block->RO.prev_block,1); - block->hh.prev = prev; - if ( prev != 0 ) - { - if ( prev->mainchain != 0 ) + if ( bits256_cmp(blockhashes[1],coin->RThash1) == 0 ) { - prev->hh.next = block; - if ( memcmp(block->RO.prev_block.bytes,coin->blocks.hwmchain.RO.hash2.bytes,sizeof(bits256)) == 0 ) - _iguana_chainlink(coin,block); - if ( (next= block->hh.next) != 0 && bits256_nonz(next->RO.hash2) > 0 ) - next->height = block->height + 1; - } - else if ( 0 && block->height < 0 ) - { - for (i=0; i<1; i++) - { - if ( (prev= prev->hh.prev) == 0 ) - break; - if ( prev->mainchain != 0 && prev->height >= 0 ) - { - j = i; - origheight = (prev->height + i + 2); - prev = block->hh.prev; - height = (origheight - 1); - while ( i > 0 && prev != 0 ) - { - if ( prev->mainchain != 0 && prev->height != height ) - { - printf("mainchain height mismatch j.%d at i.%d %d != %d\n",j,i,prev->height,height); - break; - } - prev = prev->hh.prev; - height--; - } - if ( i == 0 ) - { - //printf("SET HEIGHT.%d j.%d\n",origheight,j); - if ( (bp= coin->bundles[origheight / coin->chain->bundlesize]) != 0 ) - { - iguana_bundlehash2add(coin,0,bp,origheight % coin->chain->bundlesize,block->RO.hash2); - block->height = origheight; - block->mainchain = 1; - prev = block->hh.prev; - prev->hh.next = block; - } - } //else printf("break at i.%d for j.%d origheight.%d\n",i,j,origheight); - break; - } - } + num = (n < coin->chain->bundlesize ? n : coin->chain->bundlesize); + memcpy(addr->RThashes,blockhashes,num * sizeof(*addr->RThashes)); + addr->numRThashes = num; } } + req = iguana_bundlereq(coin,addr,'S',0); + req->hashes = blockhashes, req->n = n; + char str[65]; + if ( 0 && n > 2 && addr != 0 ) + printf("addr.%d %s [%d]\n",addr->rank,bits256_str(str,blockhashes[1]),n); + queue_enqueue("recvQ",&coin->recvQ,&req->DL,0); + if ( strcmp("BTC",coin->symbol) != 0 && n > coin->chain->bundlesize ) + iguana_sendblockreqPT(coin,addr,0,-1,blockhashes[1],0); } uint32_t iguana_allhashcmp(struct iguana_info *coin,struct iguana_bundle *bp,bits256 *blockhashes,int32_t num) { bits256 allhash; int32_t err,i,n; struct iguana_block *block,*prev; - if ( bits256_nonz(bp->allhash) > 0 && num >= coin->chain->bundlesize ) + if ( bits256_nonz(bp->allhash) > 0 && num >= coin->chain->bundlesize && bp->emitfinish == 0 ) { vcalc_sha256(0,allhash.bytes,blockhashes[0].bytes,coin->chain->bundlesize * sizeof(*blockhashes)); - if ( memcmp(allhash.bytes,bp->allhash.bytes,sizeof(allhash)) == 0 && bp->queued == 0 ) + if ( memcmp(allhash.bytes,bp->allhash.bytes,sizeof(allhash)) == 0 ) { if ( bp->bundleheight > 0 ) - prev = iguana_blockfind(coin,iguana_blockhash(coin,bp->bundleheight-1)); + prev = iguana_blockfind("allhashcmp",coin,iguana_blockhash(coin,bp->bundleheight-1)); else prev = 0; for (i=n=0; ichain->bundlesize&&in; i++) { if ( (err= iguana_bundlehash2add(coin,&block,bp,i,blockhashes[i])) < 0 ) + { + printf("error adding blockhash allhashes hdrsi.%d i.%d\n",bp->hdrsi,i); return(err); + } if ( block != 0 && block == bp->blocks[i] ) { + if ( i > 0 ) + block->RO.prev_block = blockhashes[i-1]; block->height = bp->bundleheight + i; block->mainchain = 1; if ( prev != 0 ) { - //block->RO.prev_block = prev->RO.hash2; + block->RO.prev_block = prev->RO.hash2; prev->hh.next = block; block->hh.prev = prev; } - } + //if ( bp->hdrsi < coin->MAXBUNDLES ) + // iguana_blockQ(coin,bp,i,blockhashes[i],0); + } else printf("no allhashes block.%p or mismatch.%p\n",block,bp->blocks[i]); prev = block; } - //printf("ALLHASHES FOUND! %d requested.%d\n",bp->bundleheight,n); - iguana_bundleQ(coin,bp,bp->n*2 + (rand() % 500)); + coin->allhashes++; + n = 0; + if ( bp->hdrsi < coin->MAXBUNDLES || (coin->current != 0 && coin->lastpending != 0 && bp->hdrsi >= coin->current->hdrsi && bp->hdrsi <= coin->lastpending->hdrsi) ) + n = iguana_bundleissuemissing(coin,bp,1,3.); + if ( 0 && n > 0 ) + printf("ALLHASHES FOUND! %d allhashes.%d issued %d\n",bp->bundleheight,coin->allhashes,n); + if ( bp->queued == 0 ) + iguana_bundleQ(coin,bp,bp->n*5 + (rand() % 500)); return(bp->queued); } } @@ -323,164 +604,150 @@ uint32_t iguana_allhashcmp(struct iguana_info *coin,struct iguana_bundle *bp,bit void iguana_bundlespeculate(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t offset) { - if ( bp->numhashes < bp->n && bundlei == 0 && bp->speculative == 0 && bp->bundleheight < coin->longestchain-coin->chain->bundlesize ) + if ( bp == 0 ) + return; + if ( strcmp("BTC",coin->symbol) != 0 && bp->numhashes < bp->n && bundlei == 0 && bp->speculative == 0 && bp->bundleheight < coin->longestchain-coin->chain->bundlesize ) { char str[65]; bits256_str(str,bp->hashes[0]); - printf("Afound block -> %d %d hdr.%s\n",bp->bundleheight,coin->longestchain-coin->chain->bundlesize,str); + //fprintf(stderr,"Afound block -> %d %d hdr.%s\n",bp->bundleheight,coin->longestchain-coin->chain->bundlesize,str); queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(str),1); } - else if ( bp->speculative != 0 && bundlei < bp->numspec && memcmp(hash2.bytes,bp->speculative[bundlei].bytes,sizeof(hash2)) == 0 ) + /*else if ( bp->speculative != 0 && bundlei < bp->numspec && memcmp(hash2.bytes,bp->speculative[bundlei].bytes,sizeof(hash2)) == 0 ) { bundlei += offset; - if ( bundlei < bp->n && bundlei < bp->numspec ) + if ( bundlei < bp->n && bundlei < bp->numspec && time(NULL) > bp->issued[bundlei]+30 ) { - //char str[65]; printf("speculative req[%d] %s\n",bundlei,bits256_str(str,bp->speculative[bundlei])); - //iguana_blockQ(coin,0,-1,bp->speculative[bundlei],0); + char str[65]; printf("speculative req[%d] %s\n",bundlei,bits256_str(str,bp->speculative[bundlei])); + iguana_blockQ("speculate",coin,0,-1,bp->speculative[bundlei],0); + bp->issued[bundlei] = (uint32_t)time(NULL); } - } //else printf("speculative.%p %d vs %d cmp.%d\n",bp->speculative,bundlei,bp->numspec,bp->speculative!=0?memcmp(hash2.bytes,bp->speculative[bundlei].bytes,sizeof(hash2)):-1); + } */ //else printf("speculative.%p %d vs %d cmp.%d\n",bp->speculative,bundlei,bp->numspec,bp->speculative!=0?memcmp(hash2.bytes,bp->speculative[bundlei].bytes,sizeof(hash2)):-1);*/ } -int32_t iguana_bundleiters(struct iguana_info *coin,struct iguana_bundle *bp,int32_t timelimit) +int32_t iguana_bundlehashadd(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei,struct iguana_block *block) { - int32_t i,n,valid,pend,max,counter = 0; uint32_t now; struct iguana_block *block; double endmillis; - coin->numbundlesQ--; - if ( bp->numhashes < bp->n && bp->bundleheight < coin->longestchain-coin->chain->bundlesize ) + static const bits256 zero; + struct iguana_ramchain blockR; int32_t hdrsi,firstflag=0,checki,retval=-1; long size = 0; FILE *fp; char fname[1024]; + block->bundlei = bundlei; + block->hdrsi = bp->hdrsi; + if ( bits256_nonz(bp->hashes[bundlei]) != 0 && bits256_cmp(bp->hashes[bundlei],block->RO.hash2) != 0 ) { - //printf("ITERATE bundle.%d vs %d: h.%d n.%d r.%d s.%d finished.%d speculative.%p\n",bp->bundleheight,coin->longestchain-coin->chain->bundlesize,bp->numhashes,bp->n,bp->numrecv,bp->numsaved,bp->emitfinish,bp->speculative); - if ( bp->speculative == 0 ) + char str[65],str2[65]; printf("mismatched.[%d:%d] %s <-? %s%s\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei]),bits256_str(str2,block->RO.hash2),block->mainchain?".main":""); + if ( block == bp->blocks[bundlei] ) { - char str[64]; - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); + if ( block->mainchain == 0 ) + { + printf("mainchain blockptr.%p vs %p\n",block,bp->blocks[bundlei]); + return(-1); + } } - else + else if ( bp->blocks[bundlei] != 0 ) { - for (i=1; in; i++) - if ( bits256_nonz(bp->hashes[i]) == 0 && bits256_nonz(bp->speculative[i]) > 0 ) - { - iguana_blockQ(coin,0,-1,bp->speculative[i],0); - break; - } + printf("mismatched blockptr.%p vs %p\n",block,bp->blocks[bundlei]); + return(-1); } - sleep(1); - iguana_bundleQ(coin,bp,bp->n * 10); - return(0); - } - pend = queue_size(&coin->priorityQ) + queue_size(&coin->blocksQ); - for (i=0; ipeers.active[i].pendblocks; - if ( pend >= coin->MAXPENDING*coin->MAXPEERS ) - { - sleep(10000); - printf("SKIP pend.%d vs %d: ITERATE bundle.%d n.%d r.%d s.%d finished.%d timelimit.%d\n",pend,coin->MAXPENDING*coin->MAXPEERS,bp->bundleheight,bp->n,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit); - iguana_bundleQ(coin,bp,counter == 0 ? bp->n*5 : bp->n*2); - return(0); } - max = 1 + ((coin->MAXPENDING*coin->MAXPEERS - pend) >> 1); - endmillis = OS_milliseconds() + timelimit; - while ( bp->emitfinish == 0 && OS_milliseconds() < endmillis ) + //if ( bp->blocks[bundlei] == 0 ) + firstflag = 1; + bp->blocks[bundlei] = block; + iguana_bundlehash2add(coin,0,bp,bundlei,block->RO.hash2); + if ( firstflag != 0 && bp->emitfinish == 0 ) { - now = (uint32_t)time(NULL); - for (i=n=counter=0; in; i++) + //block->fpos = -1; + if ( 0 && iguana_ramchainfile(coin,0,&blockR,bp,bundlei,block) == 0 ) { - if ( (block= bp->blocks[i]) != 0 ) - { - if ( block->fpipbits == 0 && (block->queued == 0 || bp->issued[i] == 0 || now > bp->issued[i]+13) ) - { - //if ( bp->bundleheight == 20000 ) - // printf("(%d:%d) ",bp->hdrsi,i); - block->numrequests++; - iguana_blockQ(coin,bp,i,block->RO.hash2,bp->numsaved > bp->n-10); - bp->issued[i] = now; - counter++; - if ( --max <= 0 ) - break; - } - else if ( block->fpipbits != 0 ) - n++; - } //else printf("iguana_bundleiters[%d] unexpected null block[%d]\n",bp->bundleheight,i); - bp->numsaved = n; + size = sizeof(blockR); + iguana_ramchain_free(coin,&blockR,1); } - if ( max <= 0 ) - break; - usleep(10000); - } - //if ( 0 && counter > 0 ) - printf("ITERATE bundle.%d h.%d n.%d r.%d s.%d finished.%d issued.%d\n",bp->bundleheight,bp->numhashes,bp->n,bp->numrecv,bp->numsaved,bp->emitfinish,counter); - if ( bp->emitfinish == 0 ) - { - if ( bp->numsaved >= bp->n ) + else if ( bp->hdrsi == coin->longestchain/bp->n ) { - for (i=0; in; i++) + checki = iguana_peerfname(coin,&hdrsi,GLOBAL_TMPDIR,fname,0,block->RO.hash2,zero,1,0); + if ( (fp= fopen(fname,"rb")) != 0 ) { - if ( (block= bp->blocks[i]) != 0 ) - { - //printf("(%x:%x) ",(uint32_t)block->RO.hash2.ulongs[3],(uint32_t)bp->hashes[i].ulongs[3]); - if ( iguana_blockvalidate(coin,&valid,block,0) != 0 || (bp->bundleheight+i > 0 && bits256_nonz(block->RO.prev_block) == 0) ) - { - //char str[65]; printf(">>>>>>> null prevblock error at ht.%d patch.(%s) and reissue\n",bp->bundleheight+i,bits256_str(str,bp->hashes[i-1])); - block->queued = 0; - block->fpipbits = 0; - bp->issued[i] = 0; - iguana_blockQ(coin,bp,i,block->RO.hash2,0); - iguana_bundleQ(coin,bp,counter == 0 ? bp->n*5 : bp->n*2); - return(0); - } - } else printf("error getting block (%d:%d) %p vs %p\n",bp->hdrsi,i,block,iguana_blockfind(coin,bp->hashes[i])); + fseek(fp,0,SEEK_END); + size = (uint32_t)ftell(fp); + fclose(fp); } - // merkle - printf(">>>>>>>>>>>>>>>>>>>>>>> EMIT bundle.%d\n",bp->bundleheight); - bp->emitfinish = 1; - sleep(1); - iguana_emitQ(coin,bp); - return(1); } - iguana_bundleQ(coin,bp,counter == 0 ? bp->n*5 : bp->n*2); + if ( size != 0 ) + { + retval = 0; + //printf("initialize with fp.[%d:%d] len.%ld\n",bp->hdrsi,bundlei,size); + block->RO.recvlen = (int32_t)size; + block->fpipbits = 1; + block->txvalid = 1; + block->fpos = 0; + block->issued = (uint32_t)time(NULL); + } } - return(0); + return(retval); } // main context, ie single threaded struct iguana_bundle *iguana_bundleset(struct iguana_info *coin,struct iguana_block **blockp,int32_t *bundleip,struct iguana_block *origblock) { - struct iguana_block *block,*prevblock; bits256 zero,hash2,prevhash2; struct iguana_bundle *prevbp,*bp = 0; int32_t prevbundlei,bundlei = -2; + struct iguana_block *block,*prevblock; bits256 zero,hash2,prevhash2; struct iguana_bundle *prevbp,*bp = 0; int32_t prevbundlei,bundlei = -2; // struct iguana_ramchain blockR; *bundleip = -2; *blockp = 0; if ( origblock == 0 ) return(0); memset(zero.bytes,0,sizeof(zero)); hash2 = origblock->RO.hash2; - if ( (block= iguana_blockhashset(coin,-1,hash2,1)) != 0 ) + if ( (block= iguana_blockhashset("bundleset",coin,-1,hash2,1)) != 0 ) { + prevhash2 = origblock->RO.prev_block; if ( block != origblock ) + { iguana_blockcopy(coin,block,origblock); + //fprintf(stderr,"bundleset block.%p vs origblock.%p prev.%d bits.%x fpos.%ld\n",block,origblock,bits256_nonz(prevhash2),block->fpipbits,block->fpos); + } *blockp = block; - prevhash2 = origblock->RO.prev_block; - if ( 1 && bits256_nonz(prevhash2) > 0 ) - iguana_patch(coin,block); + //if ( 0 && bits256_nonz(prevhash2) > 0 ) + // iguana_patch(coin,block); + bp = 0, bundlei = -2; if ( (bp= iguana_bundlefind(coin,&bp,&bundlei,hash2)) != 0 && bundlei < coin->chain->bundlesize ) { - block->bundlei = bundlei; - block->hdrsi = bp->hdrsi; - bp->blocks[bundlei] = block; - iguana_bundlehash2add(coin,0,bp,bundlei,hash2); + if ( iguana_bundlehashadd(coin,bp,bundlei,block) < 0 ) + { + if ( bp->emitfinish == 0 && block->issued == 0 && strcmp("BTC",coin->symbol) != 0 )//|| coin->PREFETCHLAG < 0) ) + iguana_blockQ("bundleset",coin,bp,bundlei,block->RO.hash2,1);//coin->current == 0 || bp->hdrsi <= coin->current->hdrsi+coin->MAXBUNDLES); + } + //fprintf(stderr,"bundle found %d:%d\n",bp->hdrsi,bundlei); + //printf("bundlehashadd set.%d\n",bundlei); if ( bundlei > 0 ) - iguana_bundlehash2add(coin,0,bp,bundlei-1,prevhash2); + { + //printf("bundlehashadd prev %d\n",bundlei); + if ( bits256_nonz(prevhash2) != 0 ) + iguana_bundlehash2add(coin,0,bp,bundlei-1,prevhash2); + } else if ( bp->hdrsi > 0 && (bp= coin->bundles[bp->hdrsi-1]) != 0 ) iguana_bundlehash2add(coin,0,bp,coin->chain->bundlesize-1,prevhash2); - iguana_bundlespeculate(coin,bp,bundlei,hash2,1); + if ( 1 && strcmp("BTC",coin->symbol) != 0 ) + iguana_bundlespeculate(coin,bp,bundlei,hash2,1); } prevbp = 0, prevbundlei = -2; iguana_bundlefind(coin,&prevbp,&prevbundlei,prevhash2); - if ( block->blockhashes != 0 ) - printf("has blockhashes bp.%p[%d] prevbp.%p[%d]\n",bp,bundlei,prevbp,prevbundlei); - if ( prevbp != 0 && prevbundlei >= 0 && (prevblock= iguana_blockfind(coin,prevhash2)) != 0 ) + //if ( 0 && block->blockhashes != 0 ) + // fprintf(stderr,"has blockhashes bp.%p[%d] prevbp.%p[%d]\n",bp,bundlei,prevbp,prevbundlei); + if ( prevbp != 0 && prevbundlei >= 0 && (prevblock= iguana_blockfind("bundleset2",coin,prevhash2)) != 0 ) { if ( prevbundlei < coin->chain->bundlesize ) { if ( prevbp->hdrsi+1 == coin->bundlescount && prevbundlei == coin->chain->bundlesize-1 ) - iguana_bundlecreate(coin,&prevbundlei,prevbp->bundleheight + coin->chain->bundlesize,hash2,zero,0); + { + printf("AUTOCREATE.%d\n",prevbp->bundleheight + coin->chain->bundlesize); + if ( (bp= iguana_bundlecreate(coin,bundleip,prevbp->bundleheight + coin->chain->bundlesize,hash2,zero,0)) != 0 ) + { + if ( bp->queued == 0 ) + iguana_bundleQ(coin,bp,1000); + } + } if ( prevbundlei < coin->chain->bundlesize-1 ) + { + //printf("bundlehash2add next %d\n",prevbundlei); iguana_bundlehash2add(coin,0,prevbp,prevbundlei+1,hash2); - iguana_bundlespeculate(coin,prevbp,prevbundlei,prevhash2,2); + } + if ( 1 && strcmp("BTC",coin->symbol) != 0 ) + iguana_bundlespeculate(coin,prevbp,prevbundlei,prevhash2,2); } } } else printf("iguana_bundleset: error adding blockhash\n"); @@ -488,9 +755,39 @@ struct iguana_bundle *iguana_bundleset(struct iguana_info *coin,struct iguana_bl return(iguana_bundlefind(coin,&bp,bundleip,hash2)); } +void iguana_checklongestchain(struct iguana_info *coin,struct iguana_bundle *bp,int32_t num) +{ + int32_t i; struct iguana_peer *addr; + if ( num > 3 && num < bp->n ) + { + if ( coin->longestchain > bp->bundleheight+num+10*coin->chain->minconfirms ) + { + printf("strange.%d suspicious longestchain.%d vs [%d:%d] %d bp->n %d\n",coin->longestchain_strange,coin->longestchain,bp->hdrsi,num,bp->bundleheight+num,bp->n); + if ( coin->longestchain_strange++ > 10 ) + { + coin->badlongestchain = coin->longestchain; + coin->longestchain = bp->bundleheight+num; + coin->longestchain_strange = 0; + for (i=0; ipeers.numranked; i++) + if ( (addr= coin->peers.ranked[i]) != 0 && addr->height >= coin->badlongestchain ) + { + printf("blacklist addr.(%s) height %d\n",addr->ipaddr,addr->height); + addr->dead = 1; + addr->rank = 0; + } + } + } + else if ( coin->longestchain_strange > 0 ) + { + //printf("not strange.%d suspicious longestchain.%d vs [%d:%d] %d bp->n %d\n",coin->longestchain_strange,coin->longestchain,bp->hdrsi,num,bp->bundleheight+num,bp->n); + coin->longestchain_strange--; + } + } +} + struct iguana_bundlereq *iguana_recvblockhdrs(struct iguana_info *coin,struct iguana_bundlereq *req,struct iguana_block *blocks,int32_t n,int32_t *newhwmp) { - int32_t i,bundlei,match; struct iguana_block *block; struct iguana_bundle *bp,*firstbp = 0; + int32_t i,bundlei,match; struct iguana_block *block; struct iguana_peer *addr; struct iguana_bundle *bp,*firstbp = 0; if ( blocks == 0 ) { printf("iguana_recvblockhdrs null blocks?\n"); @@ -504,114 +801,301 @@ struct iguana_bundlereq *iguana_recvblockhdrs(struct iguana_info *coin,struct ig bp = 0, bundlei = -1; if ( (bp= iguana_bundleset(coin,&block,&bundlei,&blocks[i])) != 0 ) { + bp->dirty++; + if ( 0 && bp->issued[bundlei] == 0 && bp->hdrsi < coin->MAXBUNDLES ) + iguana_blockQ("recvhdr",coin,bp,bundlei,blocks[i].RO.hash2,1); + //printf("{%d:%d} ",bp->hdrsi,bundlei); if ( i == 0 ) + { firstbp = bp; + iguana_checklongestchain(coin,bp,n); + } if ( bundlei == i+1 && bp == firstbp ) match++; - else printf("recvhdr: ht.%d[%d] vs i.%d\n",bp->bundleheight,bundlei,i); + else + { + if ( bp != coin->current && i != n-1 ) + fprintf(stderr,"recvhdr: ht.%d[%d] vs i.%d\n",bp->bundleheight,bundlei,i); + } } + //else if ( bp != firstbp ) + // printf("blockhash[%d] cant be found n.%d\n",i,n); } + char str[65]; + if ( 0 && bp == coin->current ) + printf("i.%d n.%d match.%d blockhdrs.%s hdrsi.%d\n",i,n,match,bits256_str(str,blocks[0].RO.hash2),firstbp!=0?firstbp->hdrsi:-1); if ( firstbp != 0 && match == coin->chain->bundlesize-1 && n == firstbp->n ) { if ( firstbp->queued == 0 ) { - printf("firstbp blockQ %d\n",firstbp->bundleheight); - iguana_bundleQ(coin,firstbp,1000 + 10*(rand() % (int32_t)(1+sqrt(firstbp->bundleheight)))); + //fprintf(stderr,"firstbp blockQ %d\n",firstbp->bundleheight); + iguana_bundleQ(coin,firstbp,1000); } - } else printf("match.%d vs n.%d bp->n.%d ht.%d\n",match,n,firstbp->n,firstbp->bundleheight); + } + if ( i == n && i == match && firstbp == coin->current && (addr= req->addr) != 0 ) + { + addr->RThashes[i] = firstbp->hashes[0]; + for (i=1; iRThashes[i] = blocks[i].RO.hash2; + //memcpy(addr->RThashes,blockhashes,bp->numspec * sizeof(*addr->RThashes)); + addr->numRThashes = n; + } } return(req); } +void iguana_autoextend(struct iguana_info *coin,struct iguana_bundle *bp) +{ + char hashstr[65]; struct iguana_bundle *newbp; int32_t bundlei; static const bits256 zero; + if ( bp->hdrsi == coin->bundlescount-1 && bits256_nonz(bp->nextbundlehash2) != 0 ) + { + init_hexbytes_noT(hashstr,bp->nextbundlehash2.bytes,sizeof(bits256)); + newbp = 0, bundlei = -2; + if ( iguana_bundlefind(coin,&newbp,&bundlei,bp->nextbundlehash2) != 0 ) + { + if ( newbp->bundleheight != bp->bundleheight+bp->n ) + { + printf("found spurious extra hash for [%d:%d]\n",bp->hdrsi,bp->n); + memset(&bp->nextbundlehash2,0,sizeof(bp->nextbundlehash2)); + return; + } + } + newbp = iguana_bundlecreate(coin,&bundlei,bp->bundleheight+coin->chain->bundlesize,bp->nextbundlehash2,zero,1); + if ( newbp != 0 ) + { + if ( newbp->speculative == 0 ) + queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr),1); + //char str[65],str2[65]; printf("EXTEND last bundle %s/%s ht.%d\n",bits256_str(str,newbp->hashes[0]),bits256_str(str2,bp->nextbundlehash2),newbp->bundleheight); + if ( newbp->queued == 0 ) + iguana_bundleQ(coin,newbp,1000); + } + } +} + struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct iguana_bundlereq *req,bits256 *blockhashes,int32_t num) { - int32_t bundlei,i; struct iguana_bundle *bp;// struct iguana_block *block; + int32_t bundlei,i,starti; struct iguana_bundle *bp; bits256 allhash,zero; struct iguana_peer *addr; struct iguana_block *block; char str[65],str2[65]; // uint8_t serialized[512]; + memset(zero.bytes,0,sizeof(zero)); bp = 0, bundlei = -2; iguana_bundlefind(coin,&bp,&bundlei,blockhashes[1]); - // char str[65]; printf("blockhashes[%d] %d of %d %s bp.%d[%d]\n",num,bp==0?-1:bp->hdrsi,coin->bundlescount,bits256_str(str,blockhashes[1]),bp==0?-1:bp->bundleheight,bundlei); + if ( 0 && num >= coin->chain->bundlesize ) + printf("blockhashes[%d] %d of %d %s bp.%d[%d]\n",num,bp==0?-1:bp->hdrsi,coin->bundlescount,bits256_str(str,blockhashes[1]),bp==0?-1:bp->bundleheight,bundlei); + if ( num < 2 ) + return(req); if ( bp != 0 ) { + bp->dirty++; bp->hdrtime = (uint32_t)time(NULL); blockhashes[0] = bp->hashes[0]; + //iguana_blockQ("recvhash0",coin,bp,0,blockhashes[0],1); if ( num >= coin->chain->bundlesize ) { - iguana_blockQ(coin,0,-1,blockhashes[coin->chain->bundlesize],1); + if ( bits256_nonz(bp->nextbundlehash2) == 0 && num > coin->chain->bundlesize ) + { + bp->nextbundlehash2 = blockhashes[coin->chain->bundlesize]; + iguana_blockQ("recvhash1",coin,0,-1,bp->nextbundlehash2,1); + } + //printf("call allhashes\n"); + if ( 0 && bp->hdrsi == coin->bundlescount-1 ) + iguana_autoextend(coin,bp); if ( iguana_allhashcmp(coin,bp,blockhashes,num) > 0 ) return(req); + //printf("done allhashes\n"); } - if ( (bp->speculative == 0 || num > bp->numspec) && bp->emitfinish == 0 ) + else if ( bp->hdrsi == coin->bundlescount-1 ) + iguana_checklongestchain(coin,bp,num); + if ( strcmp("BTC",coin->symbol) != 0 && (bp->speculative == 0 || num > bp->numspec) && bp->emitfinish == 0 ) { - printf("FOUND speculative BLOCKHASHES[%d] ht.%d\n",num,bp->bundleheight); - if ( bp->speculative != 0 ) - myfree(bp->speculative,sizeof(*bp->speculative) * bp->numspec); - bp->speculative = blockhashes; - bp->numspec = num; - req->hashes = 0; - iguana_blockQ(coin,0,-1,blockhashes[2],1); + //printf("FOUND speculative.%s BLOCKHASHES[%d] ht.%d\n",bits256_str(str,blockhashes[1]),num,bp->bundleheight); + if ( bp->speculative == 0 ) + { + bp->speculative = mycalloc('s',bp->n+1,sizeof(*bp->speculative)); + for (i=0; in; i++) + if ( GETBIT(bp->haveblock,i) == 0 ) + bp->issued[i] = 0; + iguana_bundleissuemissing(coin,bp,3,1.); + } + for (i=1; in; i++) + { + bp->speculative[i] = blockhashes[i]; + //if ( bp->blocks[i] == 0 || bp->blocks[i]->issued == 0 ) + // iguana_blockQ("speculate",coin,bp,-i,blockhashes[i],0); + if ( bp->blocks[i] == 0 ) + bp->blocks[i] = iguana_blockhashset("recvhashes3",coin,bp->bundleheight+i,blockhashes[i],1); + //printf("speculate new issue [%d:%d]\n",bp->hdrsi,i); + } + bp->speculative[0] = bp->hashes[0]; + bp->numspec = num <= bp->n+1 ? num : bp->n+1; + if ( bp == coin->current && (addr= req->addr) != 0 ) + { + memcpy(addr->RThashes,blockhashes,bp->numspec * sizeof(*addr->RThashes)); + addr->numRThashes = bp->numspec; + } + //iguana_blockQ(coin,0,-1,blockhashes[2],1); } } else if ( num >= coin->chain->bundlesize ) { - for (i=coin->bundlescount-1; i>=0; i--) + starti = coin->current != 0 ? coin->current->hdrsi : 0; + for (i=coin->bundlescount-1; i>=starti; i--) { - if ( (bp= coin->bundles[i]) != 0 && bits256_nonz(bp->hashes[0]) > 0 ) + if ( (bp= coin->bundles[i]) != 0 )//&& bp->emitfinish > 1 ) { blockhashes[0] = bp->hashes[0]; - if ( iguana_allhashcmp(coin,bp,blockhashes,coin->chain->bundlesize) > 0 ) + vcalc_sha256(0,allhash.bytes,blockhashes[0].bytes,coin->chain->bundlesize * sizeof(*blockhashes)); + if ( 0 && i == starti ) + printf("vcalc.(%s) [%d].(%s)\n",bits256_str(str,allhash),bp->hdrsi,bits256_str(str2,bp->hashes[0])); + if ( bits256_cmp(allhash,bp->allhash) == 0 ) { - bp->hdrtime = (uint32_t)time(NULL); - iguana_blockQ(coin,bp,1,blockhashes[1],0); - iguana_blockQ(coin,bp,0,blockhashes[0],0); - iguana_blockQ(coin,bp,coin->chain->bundlesize-1,blockhashes[coin->chain->bundlesize-1],0); - printf("matched bundle.%d\n",bp->bundleheight); - return(req); + if ( 0 && bp->speculative == 0 ) + printf("matched allhashes.[%d]\n",bp->hdrsi); + if ( bp->queued != 0 ) + bp->queued = 0; + if ( iguana_allhashcmp(coin,bp,blockhashes,coin->chain->bundlesize) > 0 ) + { + bp->hdrtime = (uint32_t)time(NULL); + //iguana_blockQ("recvhash2",coin,bp,1,blockhashes[1],1); + //iguana_blockQ("recvhash3",coin,bp,0,blockhashes[0],1); + //iguana_blockQ("recvhash4",coin,bp,coin->chain->bundlesize-1,blockhashes[coin->chain->bundlesize-1],0); + //printf("matched bundle.%d\n",bp->bundleheight); + return(req); + } else printf("unexpected mismatch??\n"); } } } - //printf("issue block1\n"); + //printf("%s.[%d] no match to allhashes\n",bits256_str(str,blockhashes[1]),num); struct iguana_block *block; - if ( num == coin->chain->bundlesize+1 && (block= iguana_blockhashset(coin,-1,blockhashes[1],1)) != 0 ) - block->blockhashes = blockhashes, req->hashes = 0; - iguana_blockQ(coin,0,-1,blockhashes[1],1); + if ( (block= iguana_blockhashset("recvhashes",coin,-1,blockhashes[1],1)) != 0 ) + { + //block->blockhashes = blockhashes, req->hashes = 0; + //printf("set block->blockhashes[%d]\n",num); + } + /*if ( (addr= coin->peers.ranked[0]) != 0 ) + { + if ( (len= iguana_getdata(coin,serialized,MSG_BLOCK,&blockhashes[1],1)) > 0 ) + { + iguana_send(coin,addr,serialized,len); + //char str[65]; printf("REQ.%s\n",bits256_str(str,blockhashes[1])); + } + }*/ + iguana_blockQ("hdr1",coin,0,-1,blockhashes[1],1); + } + else + { + if ( (block= iguana_blockfind("recvhashes2",coin,blockhashes[1])) == 0 ) + { + iguana_blockhashset("recvhashes3",coin,-1,blockhashes[1],1); + if ( (block= iguana_blockfind("recvhashes4",coin,blockhashes[1])) != 0 ) + iguana_blockQ("recvhash6",coin,0,-6,blockhashes[1],1); // should be RT block + } + if ( block != 0 ) + block->newtx = 1; + iguana_blockQ("RTblock",coin,0,-7,blockhashes[1],1); // should be RT block + } + if ( strcmp("BTC",coin->symbol) != 0 ) + { + iguana_blockQ("recvhash7",coin,0,-7,blockhashes[1],1); + iguana_blockQ("recvhash7",coin,0,-7,blockhashes[num-1],1); } - else iguana_blockQ(coin,0,-1,blockhashes[1],0); // should be RT block return(req); } struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_bundlereq *req,struct iguana_block *origblock,int32_t numtx,int32_t datalen,int32_t recvlen,int32_t *newhwmp) { - struct iguana_bundle *bp=0; int32_t bundlei = -2; struct iguana_block *block; - bp = iguana_bundleset(coin,&block,&bundlei,origblock); - //static int total; char str[65]; printf("RECV %s [%d:%d] block.%08x | %d\n",bits256_str(str,origblock->RO.hash2),bp!=0?bp->hdrsi:-1,bundlei,block->fpipbits,total++); - if ( block != 0 ) - { - block->RO.recvlen = recvlen; - if ( req->copyflag != 0 && block->queued == 0 && bp != 0 )//block->rawdata == 0 ) - { - //char str[65]; printf("%s copyflag.%d %d data %d %d\n",bits256_str(str,block->RO.hash2),req->copyflag,block->height,req->recvlen,recvlen); - //block->rawdata = mycalloc('n',1,block->RO.recvlen); - //memcpy(block->rawdata,req->serialized,block->RO.recvlen); - //block->copyflag = 1; - coin->numcached++; - block->queued = 1; - queue_enqueue("cacheQ",&coin->cacheQ,&req->DL,0); - return(0); + struct iguana_bundle *bp=0,*prev; int32_t n,bundlei = -2; struct iguana_block *block,*next; char str[65]; bits256 hash2; + if ( bits256_nonz(origblock->RO.prev_block) != 0 ) + iguana_blockQ("prev",coin,0,-1,origblock->RO.prev_block,1); + if ( (bp= iguana_bundleset(coin,&block,&bundlei,origblock)) != 0 && bp == coin->current && block != 0 && bp->speculative != 0 && bundlei >= 0 ) + { + if ( bp->speculative != 0 && bp->numspec <= bundlei ) + { + bp->speculative[bundlei] = block->RO.hash2; + bp->numspec = bundlei+1; + } + while ( bundlei < bp->n && block != 0 && bp->bundleheight+bundlei == coin->blocks.hwmchain.height+1 && _iguana_chainlink(coin,block) != 0 ) + { + //printf("MAIN.%d ",bp->bundleheight+bundlei); + bundlei++; + block = iguana_bundleblock(coin,&hash2,bp,bundlei); } - while ( block != 0 && memcmp(block->RO.prev_block.bytes,coin->blocks.hwmchain.RO.hash2.bytes,sizeof(bits256)) == 0 ) + //printf("autoadd [%d:%d]\n",bp->hdrsi,bundlei); + } + if ( bp != 0 ) + { + bp->dirty++; + if ( block != 0 && block->mainchain != 0 && bundlei == 0 && bp->hdrsi > 0 ) { - if ( _iguana_chainlink(coin,block) != 0 ) + if ( (prev= coin->bundles[bp->hdrsi - 1]) != 0 ) { - printf("chainlink.%d -> next.%p\n",block->height,block->hh.next); - block = block->hh.next; - } else break; + //printf("found adjacent [%d:%d] speculative.%p\n",prev->hdrsi,bp->n-1,prev->speculative); + } + } + } + if ( block != 0 )//&& bp != 0 && bp->hdrsi == coin->bundlescount-1 ) + { + int32_t i,numsaved = 0; struct iguana_block *tmpblock; static int32_t numrecv; + numrecv++; + if ( bp != 0 ) + { + for (i=numsaved=0; in; i++) + if ( (tmpblock= bp->blocks[i]) != 0 && tmpblock->fpipbits != 0 && tmpblock->fpos >= 0 && ((bp->hdrsi == 0 && i == 0) || bits256_nonz(tmpblock->RO.prev_block) != 0) ) + numsaved++; + } + //fprintf(stderr,"%s [%d:%d] block.%x | s.%d r.%d copy.%d mainchain.%d\n",bits256_str(str,origblock->RO.hash2),bp!=0?bp->hdrsi:-1,bundlei,block!=0?block->fpipbits:0,numsaved,numrecv,req->copyflag,block->mainchain); + if ( _iguana_chainlink(coin,block) == 0 ) + { + next = block; + for (i=n=0; ichain->bundlesize && n == 0; i++) + { + if ( (block= iguana_blockfind("recvblock",coin,block->RO.prev_block)) == 0 ) + break; + if ( block->mainchain != 0 || _iguana_chainlink(coin,block) != 0 ) + { + _iguana_chainlink(coin,next); + n++; + break; + } + next = block; + } + } // else printf("RECV MAINCHAIN.%d\n",coin->blocks.hwmchain.height); + } + if ( 0 && bundlei == 1 && bp != 0 && bp->numhashes < bp->n && strcmp("BTC",coin->symbol) != 0 && bp->speculative == 0 && bp == coin->current ) + { + printf("reissue hdrs request for [%d]\n",bp->hdrsi); + queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); + } + if ( (block= iguana_blockhashset("recvblock",coin,-1,origblock->RO.hash2,1)) != 0 ) + { + if ( block != origblock ) + iguana_blockcopy(coin,block,origblock); + if ( block->lag != 0 && block->issued != 0 ) + block->lag = (uint32_t)time(NULL) - block->issued; + if ( req->copyflag != 0 ) + { + if ( block->queued == 0 && bp != 0 ) + { + char str[65]; fprintf(stderr,"req.%p %s copyflag.%d %d data %d %d\n",req,bits256_str(str,block->RO.hash2),req->copyflag,block->height,req->recvlen,recvlen); + coin->numcached++; + block->queued = 1; + queue_enqueue("cacheQ",&coin->cacheQ,&req->DL,0); + return(0); + } + else if ( block->req == 0 ) + { + block->req = req; + req = 0; + } //else printf("already have cache entry.(%s)\n",bits256_str(str,origblock->RO.hash2)); } //printf("datalen.%d ipbits.%x\n",datalen,req->ipbits); - } else printf("cant create block.%llx block.%p bp.%p bundlei.%d\n",(long long)origblock->RO.hash2.txid,block,bp,bundlei); + } else printf("cant create origblock.%p block.%p bp.%p bundlei.%d\n",origblock,block,bp,bundlei); return(req); } struct iguana_bundlereq *iguana_recvtxids(struct iguana_info *coin,struct iguana_bundlereq *req,bits256 *txids,int32_t n) { + char str[65]; + if ( n > 0 ) + printf("got txids[%d] %s\n",n,bits256_str(str,txids[0])); return(req); } @@ -629,17 +1113,170 @@ struct iguana_bundlereq *iguana_recvunconfirmed(struct iguana_info *coin,struct return(req); } -int32_t iguana_processbundlesQ(struct iguana_info *coin,int32_t *newhwmp) // single threaded +int32_t iguana_blockreq(struct iguana_info *coin,int32_t height,int32_t priority) +{ + int32_t hdrsi,bundlei; struct iguana_bundle *bp; + hdrsi = height / coin->chain->bundlesize; + bundlei = height % coin->chain->bundlesize; + if ( (bp= coin->bundles[hdrsi]) != 0 && bits256_nonz(bp->hashes[bundlei]) != 0 ) + { + iguana_blockQ("blockreq",coin,bp,bundlei,bp->hashes[bundlei],priority); + return(height); + } + return(-1); +} + +int32_t iguana_reqblocks(struct iguana_info *coin) +{ + int32_t hdrsi,hdrsi0,bundlei0,lflag,bundlei,iters=0,flag = 0; bits256 hash2; struct iguana_block *next,*block; struct iguana_bundle *bp; + if ( time(NULL) < coin->lastreqtime+2 ) + return(0); + coin->lastreqtime = (uint32_t)time(NULL); + //printf("reqblocks %u\n",coin->lastreqtime); + hdrsi = (coin->blocks.hwmchain.height+1) / coin->chain->bundlesize; + if ( (bp= coin->bundles[hdrsi]) != 0 ) + { + bundlei = (coin->blocks.hwmchain.height+1) % coin->chain->bundlesize; + if ( (next= bp->blocks[bundlei]) != 0 || (next= iguana_blockfind("reqblocks",coin,bp->hashes[bundlei])) != 0 ) + { + if ( bits256_nonz(next->RO.prev_block) > 0 ) + _iguana_chainlink(coin,next); + else if ( next->queued == 0 && next->fpipbits == 0 && (rand() % 100) == 0 ) + { + //printf("HWM next %d\n",coin->blocks.hwmchain.height+1); + iguana_blockQ("reqblocks",coin,bp,bundlei,next->RO.hash2,1); + } + } + } + lflag = 1; + while ( coin->active != 0 && iters < coin->longestchain/3+1 ) + { + iters++; + lflag = 0; + hdrsi = (coin->blocks.hwmchain.height+1) / coin->chain->bundlesize; + bundlei = (coin->blocks.hwmchain.height+1) % coin->chain->bundlesize; + if ( 1 ) + { + if ( (next= iguana_bundleblock(coin,&hash2,coin->bundles[hdrsi],bundlei)) == 0 ) + { + hdrsi0 = (coin->blocks.hwmchain.height) / coin->chain->bundlesize; + bundlei0 = (coin->blocks.hwmchain.height) % coin->chain->bundlesize; + if ( coin->bundles[hdrsi0] != 0 && (block= iguana_bundleblock(coin,&hash2,coin->bundles[hdrsi0],bundlei0)) != 0 ) + next = block->hh.next; //, next/block->mainchain = 1; + } + } + else + { + if ( (next= iguana_blockfind("reqloop",coin,iguana_blockhash(coin,coin->blocks.hwmchain.height+1))) == 0 ) + { + } + } + if ( next == 0 && hdrsi < coin->bundlescount && (bp= coin->bundles[hdrsi]) != 0 && (next= bp->blocks[bundlei]) != 0 ) + { + if ( bits256_nonz(next->RO.prev_block) == 0 ) + { + printf(" next has null prev [%d:%d]\n",bp->hdrsi,bundlei); + iguana_blockQ("reqblocks0",coin,bp,bundlei,next->RO.hash2,1); + next = 0; + } + } + if ( next != 0 ) + { + //printf("have next %d\n",coin->blocks.hwmchain.height); + if ( memcmp(next->RO.prev_block.bytes,coin->blocks.hwmchain.RO.hash2.bytes,sizeof(bits256)) == 0 ) + { + if ( _iguana_chainlink(coin,next) != 0 ) + lflag++, flag++; + //else printf("chainlink error for %d\n",coin->blocks.hwmchain.height+1); + } + } + if ( 1 )//queue_size(&coin->blocksQ) < _IGUANA_MAXPENDING ) + { + double threshold,lag = OS_milliseconds() - coin->backstopmillis; + bp = coin->bundles[(coin->blocks.hwmchain.height+1)/coin->chain->bundlesize]; + if ( bp != 0 && bp->durationscount != 0 ) + threshold = (double)bp->totaldurations / bp->durationscount; + else + { + if ( coin->blocks.hwmchain.height >= coin->longestchain-1 ) + threshold = 10000; + else threshold = 5000; + if ( strcmp(coin->symbol,"BTC") == 0 ) + threshold *= 3; + } + if ( threshold < 1500 ) + threshold = 1500; + if ( coin->blocks.hwmchain.height < coin->longestchain && ((strcmp(coin->symbol,"BTC") != 0 && coin->backstop != coin->blocks.hwmchain.height+1) || lag > threshold) ) + { + coin->backstop = coin->blocks.hwmchain.height+1; + hash2 = iguana_blockhash(coin,coin->backstop); + bundlei = (coin->blocks.hwmchain.height+1) % coin->chain->bundlesize; + if ( bp != 0 && bits256_nonz(hash2) == 0 ) + { + hash2 = bp->hashes[bundlei]; + if ( bits256_nonz(hash2) == 0 && bp->speculative != 0 ) + { + hash2 = bp->speculative[bundlei]; + if ( bits256_nonz(hash2) > 0 ) + { + if ( (block= iguana_blockfind("reqblocks",coin,hash2)) != 0 && bits256_cmp(block->RO.prev_block,coin->blocks.hwmchain.RO.hash2) == 0 ) + { + //printf("speculative is next at %d\n",coin->backstop); + if ( _iguana_chainlink(coin,block) != 0 ) + lflag++, flag++;//, printf("NEWHWM.%d\n",coin->backstop); + } + } + } + } + if ( bits256_nonz(hash2) > 0 ) //strcmp("BTC",coin->symbol) == 0 && + { + coin->backstopmillis = OS_milliseconds(); + iguana_blockQ("mainchain",coin,0,-1,hash2,1);//lag > threshold); + flag++; + char str[65]; + if ( 1 && (rand() % 100000) == 0 )//|| bp->bundleheight > coin->longestchain-coin->chain->bundlesize ) + printf("%s %s MAIN.%d t %.3f lag %.3f\n",coin->symbol,bits256_str(str,hash2),coin->blocks.hwmchain.height+1,threshold,lag); + } + if ( 0 && bp != 0 && bundlei < bp->n-1 && (bits256_nonz(bp->hashes[bundlei+1]) != 0 || (bp->speculative != 0 && bits256_nonz(bp->speculative[bundlei+1]) != 0)) ) + { + int32_t j; + //memset(bp->hashes[bundlei].bytes,0,sizeof(bp->hashes[bundlei])); + //bp->blocks[bundlei] = 0; + for (j=0; j<1&&bundlei+j+1n; j++) + { + if ( time(NULL) > bp->issued[bundlei+1+j]+10 ) + { + bp->issued[bundlei+1+j] = (uint32_t)time(NULL); + printf("MAINCHAIN skip issue %d\n",bp->bundleheight+bundlei+1+j); + if ( bits256_nonz(bp->hashes[bundlei+1+j]) != 0 ) + iguana_blockQ("mainskip",coin,bp,bundlei+1+j,bp->hashes[bundlei+1+j],1); + else if ( bp->speculative != 0 && bundlei+1+j < bp->numspec ) + iguana_blockQ("mainskip",coin,bp,bundlei+1+j,bp->speculative[bundlei+1+j],1); + } + } + } + } + } + } + return(flag); +} + +int32_t iguana_processrecvQ(struct iguana_info *coin,int32_t *newhwmp) // single threaded { int32_t flag = 0; struct iguana_bundlereq *req; *newhwmp = 0; - while ( flag < IGUANA_BUNDLELOOP && (req= queue_dequeue(&coin->bundlesQ,0)) != 0 ) + while ( flag < IGUANA_MAXITERATIONS && coin->active != 0 && (req= queue_dequeue(&coin->recvQ,0)) != 0 ) { - //printf("%s bundlesQ.%p type.%c n.%d\n",req->addr != 0 ? req->addr->ipaddr : "0",req,req->type,req->n); + flag++; + //fprintf(stderr,"flag.%d %s recvQ.%p type.%c n.%d\n",flag,req->addr != 0 ? req->addr->ipaddr : "0",req,req->type,req->n); if ( req->type == 'B' ) // one block with all txdata + { + netBLOCKS--; req = iguana_recvblock(coin,req->addr,req,&req->block,req->numtx,req->datalen,req->recvlen,newhwmp); + } else if ( req->type == 'H' ) // blockhdrs (doesnt have txn_count!) { + HDRnet--; if ( (req= iguana_recvblockhdrs(coin,req,req->blocks,req->n,newhwmp)) != 0 ) { if ( req->blocks != 0 ) @@ -658,9 +1295,8 @@ int32_t iguana_processbundlesQ(struct iguana_info *coin,int32_t *newhwmp) // sin if ( (req= iguana_recvtxids(coin,req,req->hashes,req->n)) != 0 ) myfree(req->hashes,(req->n+1) * sizeof(*req->hashes)), req->hashes = 0; } - else printf("iguana_updatebundles unknown type.%c\n",req->type); - flag++; - //printf("done %s bundlesQ.%p type.%c n.%d\n",req->addr != 0 ? req->addr->ipaddr : "0",req,req->type,req->n); + else printf("iguana_updatebundles unknown type.%c\n",req->type);//, getchar(); + //fprintf(stderr,"finished coin->recvQ\n"); if ( req != 0 ) myfree(req,req->allocsize), req = 0; } @@ -677,92 +1313,134 @@ int32_t iguana_needhdrs(struct iguana_info *coin) int32_t iguana_reqhdrs(struct iguana_info *coin) { int32_t i,lag,n = 0; struct iguana_bundle *bp; char hashstr[65]; - if ( iguana_needhdrs(coin) > 0 && queue_size(&coin->hdrsQ) == 0 ) + if ( queue_size(&coin->hdrsQ) == 0 ) { - ///if ( coin->zcount++ > 1 ) + if ( coin->active != 0 ) { for (i=0; ibundlescount; i++) { - if ( (bp= coin->bundles[i]) != 0 && bp->emitfinish < coin->startutc ) + if ( (bp= coin->bundles[i]) != 0 && (bp == coin->current || bp->hdrsi == coin->longestchain/coin->chain->bundlesize || i == coin->bundlescount-1 || (bp->numhashes < bp->n && bp->speculative == 0)) ) { - if ( i == coin->bundlescount-1 ) - lag = 60; - else lag = 60 + (rand() % 30); - //if ( i < coin->bundlescount-1 && (bp->numhashes >= (rand() % bp->n) || time(NULL) < bp->hdrtime+lag) ) - // continue; - if ( bp->numhashes < bp->n && bp->bundleheight+bp->numhashes < coin->longestchain && time(NULL) > bp->issuetime+lag ) + if ( bp == coin->current ) + lag = 7; + else lag = 13; + if ( time(NULL) > bp->issuetime+lag ) { - printf("LAG.%ld hdrsi.%d numhashes.%d:%d needhdrs.%d qsize.%d zcount.%d\n",time(NULL)-bp->hdrtime,i,bp->numhashes,bp->n,iguana_needhdrs(coin),queue_size(&coin->hdrsQ),coin->zcount); + if ( 0 && bp == coin->current ) + printf("LAG.%ld hdrsi.%d numhashes.%d:%d needhdrs.%d qsize.%d zcount.%d\n",time(NULL)-bp->hdrtime,i,bp->numhashes,bp->n,iguana_needhdrs(coin),queue_size(&coin->hdrsQ),coin->zcount); if ( bp->issuetime == 0 ) coin->numpendings++; - char str[65]; - bits256_str(str,bp->hashes[0]); - //printf("(%s %d).%d ",str,bp->bundleheight,i); - //printf("%d ",bp->bundleheight); init_hexbytes_noT(hashstr,bp->hashes[0].bytes,sizeof(bits256)); queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr),1); - iguana_blockQ(coin,bp,0,bp->hashes[0],0); + //printf("hdrsi.%d reqHDR.(%s) numhashes.%d\n",bp->hdrsi,hashstr,bp->numhashes); + if ( 1 ) + { + iguana_blockQ("reqhdrs0",coin,bp,0,bp->hashes[0],1); + if ( bits256_nonz(bp->hashes[1]) > 0 ) + iguana_blockQ("reqhdrs1",coin,bp,1,bp->hashes[1],1); + } n++; bp->hdrtime = bp->issuetime = (uint32_t)time(NULL); } } } - if ( n > 0 ) + if ( 0 && n > 0 ) printf("REQ HDRS pending.%d\n",n); coin->zcount = 0; } - } else coin->zcount = 0; + } //else coin->zcount = 0; return(n); } -struct iguana_blockreq { struct queueitem DL; bits256 hash2,*blockhashes; struct iguana_bundle *bp; int32_t n,height,bundlei; }; - -int32_t iguana_blockQ(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t priority) +int32_t iguana_blockQ(char *argstr,struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t priority) { - queue_t *Q; char *str; int32_t height = -1; struct iguana_blockreq *req; struct iguana_block *block = 0; + queue_t *Q; char *str; uint32_t now; int32_t n,height = -1; struct iguana_blockreq *req,*ptr; struct iguana_block *block = 0; if ( bits256_nonz(hash2) == 0 ) { - printf("cant queue zerohash bundlei.%d\n",bundlei); + printf("%s.cant queue zerohash bundlei.%d\n",argstr,bundlei); + //getchar(); return(-1); } - block = iguana_blockfind(coin,hash2); - if ( priority != 0 || block == 0 || (block->queued == 0 && block->fpipbits == 0) ) + if ( 1 && coin->enableCACHE != 0 && iguana_speculativesearch(coin,&block,hash2) != 0 && block != 0 && block->txvalid != 0 ) + { + //printf("found valid [%d:%d] in blockQ\n",block!=0?block->hdrsi:-1,block!=0?block->bundlei:-1); + return(0); + } + //lag = (priority == 0) ? IGUANA_DEFAULTLAG*3 : IGUANA_DEFAULTLAG; + now = (uint32_t)time(NULL); + block = iguana_blockfind("blockQ",coin,hash2); + if ( priority != 0 || block == 0 )//|| iguana_blockstatus(coin,block) == 0 ) { - if ( block != 0 && bits256_cmp(coin->APIblockhash,hash2) != 0 ) + if ( bp != 0 ) { - if ( block->fpipbits != 0 || block->queued != 0 || block->issued > time(NULL)-10 ) + if ( bits256_cmp(coin->APIblockhash,hash2) != 0 && bp->emitfinish != 0 ) return(0); - } - if ( priority != 0 ) - str = "priorityQ", Q = &coin->priorityQ; - else str = "blocksQ", Q = &coin->blocksQ; - if ( Q != 0 ) - { - if ( bp != 0 && bundlei >= 0 && bundlei < bp->n ) + //if ( now < bp->issued[bundlei]+lag ) + // return(0); + if ( bundlei >= 0 && bundlei < bp->n ) + { + if ( block == 0 ) + block = bp->blocks[bundlei]; + height = bp->bundleheight + bundlei; + } + else { - if ( bp->issued[bundlei] == 0 || time(NULL) > bp->issued[bundlei]+3 ) + if ( priority == 0 && -bundlei >= 0 && -bundlei < bp->n && bp->speculative != 0 ) { - bp->issued[bundlei] = (uint32_t)time(NULL); - if ( bp->bundleheight >= 0 ) - height = (bp->bundleheight + bundlei); + if ( bp->speculativecache[-bundlei] != 0 ) + return(0); } - else + bp = 0; + bundlei = -1; + } + } + if ( block != 0 ) + { + if ( bits256_cmp(coin->APIblockhash,hash2) != 0 && (block->fpipbits != 0 || block->req != 0 || block->queued != 0) ) + { + if ( block->fpipbits == 0 && block->queued == 0 && block->req != 0 ) { - return(1); + block->queued = 1; + queue_enqueue("cacheQ",&coin->cacheQ,&block->req->DL,0); + block->req = 0; + //char str2[65]; printf("already have.(%s)\n",bits256_str(str2,block->RO.hash2)); } + return(0); } + if ( block->queued != 0 || block->txvalid != 0 )//|| now < block->issued+lag ) + return(0); + height = block->height; + } + if ( bp != 0 && bp->emitfinish != 0 ) + return(0); + if ( priority != 0 ) + str = "priorityQ", Q = &coin->priorityQ; + else str = "blocksQ", Q = &coin->blocksQ; + if ( Q != 0 ) + { req = mycalloc('y',1,sizeof(*req)); req->hash2 = hash2; - req->bp = bp; + if ( (req->bp= bp) != 0 && bundlei >= 0 ) + { + height = bp->bundleheight + bundlei; + bp->issued[bundlei] = 1; + } req->height = height; req->bundlei = bundlei; char str2[65]; - if ( 0 && (bundlei % 250) == 0 ) - printf("%s %d %s %d numranked.%d qsize.%d\n",str,req->height,bits256_str(str2,hash2),coin->blocks.recvblocks,coin->peers.numranked,queue_size(Q)); + //printf("%s %s %s [%d:%d] %d %s %d numranked.%d qsize.%d\n",coin->symbol,argstr,str,bp!=0?bp->hdrsi:-1,bundlei,req->height,bits256_str(str2,hash2),coin->blocks.recvblocks,coin->peers.numranked,queue_size(Q)); + if ( (n= queue_size(Q)) > 100000 ) + { + if ( 1 && n > 200000 ) + printf("%s %s %s [%d:%d] %d %s %d numranked.%d qsize.%d\n",coin->symbol,argstr,str,bp!=0?bp->hdrsi:-1,bundlei,req->height,bits256_str(str2,hash2),coin->blocks.recvblocks,coin->peers.numranked,queue_size(Q)); + while ( (ptr= queue_dequeue(Q,0)) != 0 ) + myfree(ptr,sizeof(*ptr)); + coin->backlog = n*10 + 1000000; + } else coin->backlog >>= 1; if ( block != 0 ) { - block->numrequests++; - block->issued = (uint32_t)time(NULL); + //block->numrequests++; + block->issued = now; } queue_enqueue(str,Q,&req->DL,0); return(1); @@ -774,10 +1452,13 @@ int32_t iguana_blockQ(struct iguana_info *coin,struct iguana_bundle *bp,int32_t int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) { uint8_t serialized[sizeof(struct iguana_msghdr) + sizeof(uint32_t)*32 + sizeof(bits256)]; - char *hashstr=0; bits256 hash2; uint32_t now; struct iguana_block *block; struct iguana_blockreq *req=0; - struct iguana_bundle *bp; struct iguana_peer *ptr; int32_t priority,i,m,z,pend,limit,height=-1,bundlei,datalen,flag = 0; + struct iguana_block *block; struct iguana_blockreq *req=0; char *hashstr=0; bits256 hash2; + int32_t bundlei,priority,i,m,z,pend,limit,height=-1,datalen,flag = 0; + uint32_t now; struct iguana_bundle *bp; struct iguana_peer *ptr; if ( addr->msgcounts.verack == 0 ) return(0); + //if ( netBLOCKS > IGUANA_NUMHELPERS*1000 ) + // usleep(netBLOCKS); now = (uint32_t)time(NULL); if ( iguana_needhdrs(coin) != 0 && addr->pendhdrs < IGUANA_MAXPENDHDRS ) { @@ -792,7 +1473,7 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) bp = 0, bundlei = -2; bp = iguana_bundlefind(coin,&bp,&bundlei,hash2); z = m = 0; - if ( bp != 0 && bp->queued == 0 ) + if ( bp != 0 ) { if ( bp->bundleheight+coin->chain->bundlesize < coin->longestchain ) { @@ -800,32 +1481,39 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) if ( bp->numhashes < m ) z = 1; } - else if ( bp->numhashes < 3 ) + else if ( bp->numhashes < bp->n ) z = 1; } - //if ( bp == 0 || z != 0 ) + if ( bp == 0 || bp->speculative == 0 || bp == coin->current || bp->hdrsi == coin->bundlescount-1 || bp->numhashes < bp->n ) { - //printf("%s request HDR.(%s) numhashes.%d\n",addr!=0?addr->ipaddr:"local",hashstr,bp->numhashes); + if ( 0 && bp == coin->current ) + printf("%s request HDR.(%s) numhashes.%d [%d]\n",addr!=0?addr->ipaddr:"local",hashstr,bp!=0?bp->numhashes:0,bp!=0?bp->hdrsi:-1); iguana_send(coin,addr,serialized,datalen); addr->pendhdrs++; flag++; - } //else printf("skip hdrreq.%s m.%d z.%d\n",hashstr,m,z); + } //else printf("skip hdrreq.%s m.%d z.%d bp.%p longest.%d queued.%d\n",hashstr,m,z,bp,bp->coin->longestchain,bp->queued); } - free_queueitem(hashstr); - return(flag); + //free_queueitem(hashstr); + //return(flag); } else printf("datalen.%d from gethdrs\n",datalen); free_queueitem(hashstr); hashstr = 0; } } - if ( (limit= addr->recvblocks) > coin->MAXPENDING ) - limit = coin->MAXPENDING; + //if ( netBLOCKS > coin->MAXPEERS*coin->MAXPENDING ) + // usleep(netBLOCKS); + if ( (limit= addr->recvblocks) > coin->MAXPENDINGREQUESTS ) + limit = coin->MAXPENDINGREQUESTS; if ( limit < 1 ) limit = 1; - //if ( addr->pendblocks >= limit ) - // printf("%s %d overlimit.%d\n",addr->ipaddr,addr->pendblocks,limit); + if ( addr->pendblocks >= limit ) + { + //printf("%s %d overlimit.%d\n",addr->ipaddr,addr->pendblocks,limit); + return(0); + } + priority = 1; req = queue_dequeue(&coin->priorityQ,0); - if ( addr->rank != 1 && req == 0 && addr->pendblocks < limit ) + if ( flag == 0 && req == 0 && addr->pendblocks < limit ) { priority = 0; for (i=m=pend=0; ipeers.numranked; i++) @@ -833,27 +1521,32 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) if ( (ptr= coin->peers.ranked[i]) != 0 && ptr->msgcounts.verack > 0 ) pend += ptr->pendblocks, m++; } - if ( pend < coin->MAXPENDING*m ) + if ( pend < coin->MAXPENDINGREQUESTS*m ) req = queue_dequeue(&coin->blocksQ,0); - } else priority = 1; + } if ( req != 0 ) { hash2 = req->hash2; height = req->height; - block = 0; - if ( priority == 0 && (bp= req->bp) != 0 && req->bundlei >= 0 && req->bundlei < bp->n && req->bundlei < coin->chain->bundlesize && (block= bp->blocks[req->bundlei]) != 0 && (block->fpipbits != 0 || block->queued != 0) ) + if ( (bp= req->bp) != 0 && req->bundlei >= 0 && req->bundlei < bp->n ) + { + if ( bp->emitfinish != 0 ) + { + //printf("skip emitting bundle [%d:%d]\n",bp->hdrsi,req->bundlei); + return(0); + } + block = bp->blocks[req->bundlei]; + } else block = 0; + if ( priority == 0 && bp != 0 && req->bundlei >= 0 && req->bundlei < bp->n && req->bundlei < coin->chain->bundlesize && block != 0 && (block->fpipbits != 0 || block->queued != 0) ) { if ( 1 && priority != 0 ) printf("SKIP %p[%d] %d\n",bp,bp!=0?bp->bundleheight:-1,req->bundlei); } else { - //char str[65]; - //if ( 0 && priority != 0 ) - // printf(" issue.%s\n",bits256_str(str,hash2)); - if ( block != 0 ) - block->numrequests++; - iguana_sendblockreqPT(coin,addr,req->bp,req->bundlei,hash2,0); + //if ( block != 0 ) + // block->numrequests++; + iguana_sendblockreqPT(coin,addr,bp,req->bundlei,hash2,0); } flag++; myfree(req,sizeof(*req)); @@ -861,112 +1554,49 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) return(flag); } -int32_t iguana_reqblocks(struct iguana_info *coin) +int32_t iguana_processrecv(struct iguana_info *coin) // single threaded { - int32_t hdrsi,lflag,bundlei,flag = 0; bits256 hash2; struct iguana_block *next,*block; struct iguana_bundle *bp; - hdrsi = (coin->blocks.hwmchain.height+1) / coin->chain->bundlesize; - if ( (bp= coin->bundles[hdrsi]) != 0 ) + int32_t i,newhwm = 0,hwmheight,flag = 0; char str[2000]; + hwmheight = coin->blocks.hwmchain.height; + coin->RTramchain_busy = 1; + if ( coin->balanceflush != 0 ) { - bundlei = (coin->blocks.hwmchain.height+1) % coin->chain->bundlesize; - if ( (next= bp->blocks[bundlei]) != 0 || (next= iguana_blockfind(coin,bp->hashes[bundlei])) != 0 ) - { - if ( bits256_nonz(next->RO.prev_block) > 0 ) - _iguana_chainlink(coin,next); - else if ( next->queued == 0 && next->fpipbits == 0 ) - { - //printf("HWM next %d\n",coin->blocks.hwmchain.height+1); - iguana_blockQ(coin,bp,bundlei,next->RO.hash2,0); - } - } - else + if ( iguana_balanceflush(coin,coin->balanceflush) > 0 ) + printf("balanceswritten.%d flushed coin->balanceflush %d vs %d coin->longestchain/coin->chain->bundlesize\n",coin->balanceswritten,coin->balanceflush,coin->longestchain/coin->chain->bundlesize); + coin->balanceflush = 0; + } + //printf("recvQ\n"); + flag += iguana_processrecvQ(coin,&newhwm); + //printf("reqhdrs\n"); + flag += iguana_reqhdrs(coin); + if ( coin->spendvectorsaved > 1 ) + { + if ( time(NULL) > coin->laststats+5 ) { - if ( bits256_nonz(bp->hashes[bundlei]) > 0 ) - { - //printf("next %d\n",coin->blocks.hwmchain.height+1); - iguana_blockQ(coin,bp,bundlei,bp->hashes[bundlei],0); - } - else if ( bp->speculative != 0 && bits256_nonz(bp->speculative[bundlei]) > 0 ) - { - //printf("speculative next %d\n",coin->blocks.hwmchain.height+1); - iguana_blockQ(coin,0,-1,bp->speculative[bundlei],0); - } + //printf("reqblocks\n"); + flag += iguana_reqblocks(coin); + //printf("bundlestats\n"); + iguana_bundlestats(coin,str,IGUANA_DEFAULTLAG); + coin->laststats = (uint32_t)time(NULL); } } - else if ( (bp= coin->bundles[--hdrsi]) != 0 ) + else { - char str[65]; - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); + flag += iguana_reqblocks(coin); + iguana_bundlestats(coin,str,IGUANA_DEFAULTLAG); } - lflag = 1; - while ( lflag != 0 ) + if ( time(NULL) > coin->spendvectorsaved ) { - lflag = 0; - hdrsi = (coin->blocks.hwmchain.height+1) / coin->chain->bundlesize; - bundlei = (coin->blocks.hwmchain.height+1) % coin->chain->bundlesize; - if ( (next= iguana_blockfind(coin,iguana_blockhash(coin,coin->blocks.hwmchain.height+1))) == 0 ) + for (i=0; ichain->bundlesize; i++) { - if ( (block= iguana_blockfind(coin,coin->blocks.hwmchain.RO.hash2)) != 0 ) - next = block->hh.next, block->mainchain = 1; - } - if ( next == 0 && hdrsi < coin->bundlescount && (bp= coin->bundles[hdrsi]) != 0 && (next= bp->blocks[bundlei]) != 0 ) - { - if ( bits256_nonz(next->RO.prev_block) == 0 ) - next = 0; - } - if ( next != 0 ) - { - //printf("have next\n"); - if ( memcmp(next->RO.prev_block.bytes,coin->blocks.hwmchain.RO.hash2.bytes,sizeof(bits256)) == 0 ) - { - if ( _iguana_chainlink(coin,next) != 0 ) - lflag++, flag++; - //else printf("chainlink error for %d\n",coin->blocks.hwmchain.height+1); - } - if ( 1 && queue_size(&coin->blocksQ) == 0 ) - { - double threshold,lag = OS_milliseconds() - coin->backstopmillis; - threshold = (10 + coin->longestchain - coin->blocksrecv); - if ( threshold < 1 ) - threshold = 1.; - if ( (bp= coin->bundles[(coin->blocks.hwmchain.height+1)/coin->chain->bundlesize]) != 0 ) - threshold = (bp->avetime + coin->avetime) * .5; - else threshold = coin->avetime; - threshold *= 100. * sqrt(threshold) * .000777; - if ( strcmp(coin->symbol,"BTC") != 0 ) - threshold = 1000; - else threshold = 10000; - if ( coin->blocks.hwmchain.height < coin->longestchain && (coin->backstop != coin->blocks.hwmchain.height+1 || lag > threshold) ) - { - coin->backstop = coin->blocks.hwmchain.height+1; - hash2 = iguana_blockhash(coin,coin->backstop); - if ( bits256_nonz(hash2) > 0 ) - { - bp = coin->bundles[(coin->blocks.hwmchain.height+1)/coin->chain->bundlesize]; - bundlei = (coin->blocks.hwmchain.height+1) % coin->chain->bundlesize; - if ( bp != 0 ) - { - coin->backstopmillis = OS_milliseconds(); - iguana_blockQ(coin,bp,bundlei,hash2,0); - flag++; - //if ( (rand() % 100) == 0 ) - char str[65]; printf("%s MAINCHAIN.%d threshold %.3f %.3f lag %.3f\n",bits256_str(str,hash2),coin->blocks.hwmchain.height+1,threshold,coin->backstopmillis,lag); - } - } - } - else if ( 0 && bits256_nonz(next->RO.prev_block) > 0 ) - printf("next prev cmp error nonz.%d\n",bits256_nonz(next->RO.prev_block)); - } + if ( coin->RTdatabad != 0 || iguana_realtime_update(coin) <= 0 ) + break; } } - return(flag); -} - -int32_t iguana_processrecv(struct iguana_info *coin) // single threaded -{ - int32_t newhwm = 0,flag = 0; - //printf("process bundlesQ\n"); - flag += iguana_processbundlesQ(coin,&newhwm); - flag += iguana_reqhdrs(coin); - flag += iguana_reqblocks(coin); + coin->RTramchain_busy = 0;//(coin->RTgenesis == 0); + flag += iguana_process_msgrequestQ(coin); + iguana_jsonQ(); + if ( hwmheight != coin->blocks.hwmchain.height ) + flag = 1; return(flag); } diff --git a/iguana/iguana_rpc.c b/iguana/iguana_rpc.c index 7f85bca53..e4dc0bfc7 100755 --- a/iguana/iguana_rpc.c +++ b/iguana/iguana_rpc.c @@ -16,22 +16,51 @@ #include "iguana777.h" #include "SuperNET.h" -#define RPCARGS struct supernet_info *myinfo,struct iguana_info *coin,cJSON *params[],int32_t n,cJSON *json,char *remoteaddr +#define RPCARGS struct supernet_info *myinfo,uint16_t port,struct iguana_info *coin,cJSON *params[],int32_t n,cJSON *json,char *remoteaddr,cJSON *array +#define GLUEARGS cJSON *json,struct supernet_info *myinfo,uint16_t port,struct iguana_info *coin,char *remoteaddr,cJSON *params[] -char *sglue(cJSON *json,struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,char *agent,char *method) +#define CALLGLUE myinfo,port,coin,remoteaddr,params + +char *sglue(GLUEARGS,char *agent,char *method) { - char *retstr,*rpcretstr; cJSON *retjson,*result,*error; int32_t i,j,len; + char *retstr,*rpcretstr,*walletstr; cJSON *retjson,*tmpjson,*result,*error,*wallet; int32_t i,j,len; if ( json == 0 ) json = cJSON_CreateObject(); + //printf("sglue.(%s)\n",jprint(json,0)); jaddstr(json,"agent",agent); jaddstr(json,"method",method); jaddstr(json,"coin",coin->symbol); - if ( (retstr= SuperNET_JSON(myinfo,json,remoteaddr)) != 0 ) + if ( (retstr= SuperNET_JSON(myinfo,json,remoteaddr,port)) != 0 ) { if ( (retjson= cJSON_Parse(retstr)) != 0 ) { - jdelete(retjson,"tag"); - //printf("RPCret.(%s) n.%d\n",jprint(retjson,0),cJSON_GetArraySize(retjson)); + if ( myinfo->dirty != 0 && myinfo->secret[0] != 0 ) + { + if ( (wallet= iguana_walletjson(myinfo)) != 0 ) + { + //printf("WALLETSTR.(%s)\n",jprint(wallet,0)); + if ( (walletstr= SuperNET_login(myinfo,coin,json,remoteaddr,myinfo->handle,myinfo->secret,myinfo->permanentfile,0)) != 0 ) + { + free(walletstr); + walletstr = myinfo->decryptstr, myinfo->decryptstr = 0; + if ( walletstr != 0 && (tmpjson= cJSON_Parse(walletstr)) != 0 ) + { + jdelete(tmpjson,"wallet"); + jadd(tmpjson,"wallet",wallet); + if ( iguana_payloadupdate(myinfo,coin,jprint(tmpjson,1),0,0) == 0 ) + { + printf("wallet updated\n"); + myinfo->dirty = 0; + } else printf("iguana_payloadupdate error\n"); + } else printf("error parsing decryptstr\n"); + if ( walletstr != 0 ) + free(walletstr); + } else printf("ERROR: dirty wallet is unsaved, iguana_payloadupdate error\n"); + } else printf("ERROR: dirty wallet is unsaved, unlock wallet\n"); + } + if ( jobj(retjson,"tag") != 0 ) + jdelete(retjson,"tag"); + ///printf("RPCret.(%s) n.%d\n",jprint(retjson,0),cJSON_GetArraySize(retjson)); result = cJSON_GetObjectItem(retjson,"result"); error = cJSON_GetObjectItem(retjson,"error"); if ( result != 0 && cJSON_GetArraySize(retjson) == 1 ) @@ -44,8 +73,7 @@ char *sglue(cJSON *json,struct supernet_info *myinfo,struct iguana_info *coin,ch { for (i=1,j=0; i version 0.8 Attempts add or remove from the addnode list or try a connection to once. N return(clonestr("{\"error\":\"invalid addnode parameter\"}")); @@ -182,295 +219,311 @@ static char *addnode(RPCARGS) // address and pubkeys static char *validateaddress(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","validateaddress","address",params[0])); + return(sglue1(0,CALLGLUE,"bitcoinrpc","validateaddress","address",params[0])); } static char *validatepubkey(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","validatepubkey","pubkey",params[0])); + return(sglue1(0,CALLGLUE,"bitcoinrpc","validatepubkey","pubkey",params[0])); } static char *createmultisig(RPCARGS) { - return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","createmultisig","M",params[0],"pubkeys",params[1])); + return(sglue2(0,CALLGLUE,"bitcoinrpc","createmultisig","M",params[0],"pubkeys",params[1])); } static char *addmultisigaddress(RPCARGS) { - return(sglue3(0,myinfo,coin,remoteaddr,"ramchain","createmultisig","M",params[0],"pubkeys",params[1],"account",params[2])); + return(sglue3(0,CALLGLUE,"bitcoinrpc","addmultisigaddress","M",params[0],"pubkeys",params[1],"account",params[2])); } // blockchain static char *getinfo(RPCARGS) { - return(sglue(0,myinfo,coin,remoteaddr,"ramchain","status")); + return(sglue(0,CALLGLUE,"bitcoinrpc","getinfo")); } static char *getbestblockhash(RPCARGS) { - return(sglue(0,myinfo,coin,remoteaddr,"ramchain","getbestblockhash")); + return(sglue(0,CALLGLUE,"bitcoinrpc","getbestblockhash")); } static char *getblockcount(RPCARGS) { - return(sglue(0,myinfo,coin,remoteaddr,"ramchain","getblockcount")); + return(sglue(0,CALLGLUE,"bitcoinrpc","getblockcount")); } static char *getblock(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","getblock","blockhash",params[0])); + cJSON *obj; + if ( params[1] == 0 ) + params[1] = cJSON_CreateNumber(1); + else + { + obj = params[1]; + if ( is_cJSON_False(params[1]) != 0 ) + params[1] = cJSON_CreateNumber(0); + else params[1] = cJSON_CreateNumber(1); + free_json(obj); + } + return(sglue3(0,CALLGLUE,"bitcoinrpc","getblock","blockhash",params[0],"verbose",params[1],"remoteonly",params[2])); } static char *getblockhash(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","getblockhash","height",params[0])); + return(sglue1(0,CALLGLUE,"bitcoinrpc","getblockhash","height",params[0])); } static char *gettransaction(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","tx","txid",params[0])); + return(sglue1(0,CALLGLUE,"bitcoinrpc","gettransaction","txid",params[0])); } static char *listtransactions(RPCARGS) { - return(sglue3(0,myinfo,coin,remoteaddr,"ramchain","listtransactions","account",params[0],"count",params[1],"from",params[2])); + return(sglue3(0,CALLGLUE,"bitcoinrpc","listtransactions","account",params[0],"count",params[1],"from",params[2])); } static char *getreceivedbyaddress(RPCARGS) { - return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","getreceivedbyaddress","address",params[0],"minconfs",params[1])); + return(sglue2(0,CALLGLUE,"bitcoinrpc","getreceivedbyaddress","address",params[0],"minconfs",params[1])); } static char *listreceivedbyaddress(RPCARGS) { - return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","listreceivedbyaddress","minconf",params[0],"includeempty",params[1])); + return(sglue2(0,CALLGLUE,"bitcoinrpc","listreceivedbyaddress","minconf",params[0],"includeempty",params[1])); } static char *listsinceblock(RPCARGS) { - return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","listsinceblock","blockhash",params[0],"target",params[1])); + return(sglue2(0,CALLGLUE,"bitcoinrpc","listsinceblock","blockhash",params[0],"target",params[1])); } // waccount and waddress funcs static char *getreceivedbyaccount(RPCARGS) { - return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","getreceivedbyaccount","account",params[0],"minconfs",params[1])); + return(sglue2(0,CALLGLUE,"bitcoinrpc","getreceivedbyaccount","account",params[0],"minconfs",params[1])); } static char *listreceivedbyaccount(RPCARGS) { - return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","listreceivedbyaccount","account",params[0],"includeempty",params[1])); + return(sglue2(0,CALLGLUE,"bitcoinrpc","listreceivedbyaccount","account",params[0],"includeempty",params[1])); } static char *getnewaddress(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","getnewaddress","account",params[0])); + return(sglue1(0,CALLGLUE,"bitcoinrpc","getnewaddress","account",params[0])); } static char *vanitygen(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","vanitygen","vanity",params[0])); + return(sglue1(0,CALLGLUE,"bitcoinrpc","vanitygen","vanity",params[0])); } static char *makekeypair(RPCARGS) { - return(sglue(0,myinfo,coin,remoteaddr,"ramchain","makekeypair")); + return(sglue(0,CALLGLUE,"bitcoinrpc","makekeypair")); } static char *getaccountaddress(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","getaccountaddress","account",params[0])); + return(sglue1(0,CALLGLUE,"bitcoinrpc","getaccountaddress","account",params[0])); } -static char *setaccount(RPCARGS) +static char *setaccountrpc(RPCARGS) { - return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","setaccount","address",params[0],"account",params[1])); + return(sglue2(0,CALLGLUE,"bitcoinrpc","setaccount","address",params[0],"account",params[1])); } static char *getaccount(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","getaccount","address",params[0])); + return(sglue1(0,CALLGLUE,"bitcoinrpc","getaccount","address",params[0])); } static char *getaddressesbyaccount(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","getaddressesbyaccount","account",params[0])); + return(sglue1(0,CALLGLUE,"bitcoinrpc","getaddressesbyaccount","account",params[0])); } static char *listaddressgroupings(RPCARGS) { - return(sglue(0,myinfo,coin,remoteaddr,"ramchain","listaddressgroupings")); + return(sglue(0,CALLGLUE,"bitcoinrpc","listaddressgroupings")); } static char *getbalance(RPCARGS) { - return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","getbalance","account",params[0],"minconf",params[1])); + return(sglue2(0,CALLGLUE,"bitcoinrpc","getbalance","account",params[0],"minconf",params[1])); } // wallet static char *listaccounts(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","listaccounts","minconf",params[0])); + return(sglue1(0,CALLGLUE,"bitcoinrpc","listaccounts","minconf",params[0])); } static char *dumpprivkey(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","dumpprivkey","address",params[0])); + return(sglue1(0,CALLGLUE,"bitcoinrpc","dumpprivkey","address",params[0])); } static char *importprivkey(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","importprivkey","wif",params[0])); + return(sglue1(0,CALLGLUE,"bitcoinrpc","importprivkey","wif",params[0])); } static char *dumpwallet(RPCARGS) { - return(sglue(0,myinfo,coin,remoteaddr,"ramchain","dumpwallet")); + return(sglue(0,CALLGLUE,"bitcoinrpc","dumpwallet")); } static char *importwallet(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","importwallet","wallet",params[0])); + return(sglue1(0,CALLGLUE,"bitcoinrpc","importwallet","wallet",params[0])); } static char *walletpassphrase(RPCARGS) { - return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","walletpassphrase","passphrase",params[0],"timeout",params[1])); + return(sglue3(0,CALLGLUE,"bitcoinrpc","walletpassphrase","password",params[0],"permanentfile",params[2],"timeout",params[1])); } static char *walletpassphrasechange(RPCARGS) { - return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","walletpassphrasechange","oldpassphrase",params[0],"newpassphrase",params[1])); + return(sglue4(0,CALLGLUE,"bitcoinrpc","walletpassphrasechange","oldpassphrase",params[0],"newpassphrase",params[1],"oldpermanentfile",params[2],"oldpermanentfile",params[3])); } static char *walletlock(RPCARGS) { - return(sglue(0,myinfo,coin,remoteaddr,"ramchain","walletlock")); + return(sglue(0,CALLGLUE,"bitcoinrpc","walletlock")); } static char *encryptwallet(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","encryptwallet","passphrase",params[0])); + return(sglue2(0,CALLGLUE,"bitcoinrpc","encryptwallet","passphrase",params[0],"password",params[1])); } static char *checkwallet(RPCARGS) { - return(sglue(0,myinfo,coin,remoteaddr,"ramchain","checkwallet")); + return(sglue(0,CALLGLUE,"bitcoinrpc","checkwallet")); } static char *repairwallet(RPCARGS) { - return(sglue(0,myinfo,coin,remoteaddr,"ramchain","repairwallet")); + return(sglue(0,CALLGLUE,"bitcoinrpc","repairwallet")); } static char *backupwallet(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","backupwallet","filename",params[0])); + return(sglue1(0,CALLGLUE,"bitcoinrpc","backupwallet","filename",params[0])); } // messages static char *signmessage(RPCARGS) { - return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","signmessage","address",params[0],"message",params[1])); + return(sglue2(0,CALLGLUE,"bitcoinrpc","signmessage","address",params[0],"message",params[1])); } static char *verifymessage(RPCARGS) { - return(sglue3(0,myinfo,coin,remoteaddr,"ramchain","verifymessage","address",params[0],"sig",params[1],"message",params[2])); + return(sglue3(0,CALLGLUE,"bitcoinrpc","verifymessage","address",params[0],"sig",params[1],"message",params[2])); } // unspents static char *listunspent(RPCARGS) { - return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","listunspent","minconf",params[0],"maxconf",params[1])); + return(sglue3(0,CALLGLUE,"bitcoinrpc","listunspent","minconf",params[0],"maxconf",params[1],"array",params[2])); } static char *lockunspent(RPCARGS) { - return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","lockunspent","flag",params[0],"array",params[1])); + return(sglue2(0,CALLGLUE,"bitcoinrpc","lockunspent","flag",params[0],"array",params[1])); } static char *listlockunspent(RPCARGS) { - return(sglue(0,myinfo,coin,remoteaddr,"ramchain","listlockunspent")); + return(sglue(0,CALLGLUE,"bitcoinrpc","listlockunspent")); } static char *gettxout(RPCARGS) { - return(sglue3(0,myinfo,coin,remoteaddr,"ramchain","gettxout","txid",params[0],"vout",params[1],"mempool",params[2])); + return(sglue3(0,CALLGLUE,"bitcoinrpc","gettxout","txid",params[0],"vout",params[1],"mempool",params[2])); } static char *gettxoutsetinfo(RPCARGS) { - return(sglue(0,myinfo,coin,remoteaddr,"ramchain","gettxoutsetinfo")); + return(sglue(0,CALLGLUE,"bitcoinrpc","gettxoutsetinfo")); } // payments static char *sendtoaddress(RPCARGS) { - return(sglue4(0,myinfo,coin,remoteaddr,"ramchain","sendtoaddress","address",params[0],"amount",params[1],"comment",params[2],"comment2",params[3])); + return(sglue4(0,CALLGLUE,"bitcoinrpc","sendtoaddress","address",params[0],"amount",params[1],"comment",params[2],"comment2",params[3])); } static char *movecmd(RPCARGS) { - return(sglue5(0,myinfo,coin,remoteaddr,"ramchain","move","fromaccount",params[0],"toaccount",params[1],"amount",params[2],"minconf",params[3],"comment",params[4])); + return(sglue5(0,CALLGLUE,"bitcoinrpc","move","fromaccount",params[0],"toaccount",params[1],"amount",params[2],"minconf",params[3],"comment",params[4])); } static char *sendfrom(RPCARGS) { - return(sglue6(0,myinfo,coin,remoteaddr,"ramchain","sendfrom","fromaccount",params[0],"toaddress",params[1],"amount",params[2],"minconf",params[3],"comment",params[4],"comment2",params[5])); + return(sglue6(0,CALLGLUE,"bitcoinrpc","sendfrom","fromaccount",params[0],"toaddress",params[1],"amount",params[2],"minconf",params[3],"comment",params[4],"comment2",params[5])); } static char *sendmany(RPCARGS) { - return(sglue4(0,myinfo,coin,remoteaddr,"ramchain","sendmany","fromaccount",params[0],"payments",params[1],"minconf",params[2],"comment",params[3])); + return(sglue4(0,CALLGLUE,"bitcoinrpc","sendmany","fromaccount",params[0],"payments",params[1],"minconf",params[2],"comment",params[3])); } static char *settxfee(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","settxfee","amount",params[0])); + return(sglue1(0,CALLGLUE,"bitcoinrpc","settxfee","amount",params[0])); } // rawtransaction static char *getrawtransaction(RPCARGS) { - return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","getrawtransaction","txid",params[0],"verbose",params[1])); + return(sglue2(0,CALLGLUE,"bitcoinrpc","getrawtransaction","txid",params[0],"verbose",params[1])); } static char *createrawtransaction(RPCARGS) { - return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","createrawtransaction","vins",params[0],"vouts",params[1])); + return(sglue3(0,CALLGLUE,"bitcoinrpc","createrawtransaction","vins",params[0],"vouts",params[1],"locktime",params[2])); } static char *decoderawtransaction(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","decoderawtransaction","rawtx",params[0])); + return(sglue1(0,CALLGLUE,"bitcoinrpc","decoderawtransaction","rawtx",params[0])); } static char *decodescript(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","decodescript","script",params[0])); + return(sglue1(0,CALLGLUE,"bitcoinrpc","decodescript","scriptstr",params[0])); } static char *signrawtransaction(RPCARGS) { - return(sglue3(0,myinfo,coin,remoteaddr,"ramchain","signrawtransaction","rawtx",params[0],"vins",params[1],"privkeys",params[2])); + return(sglue4(0,CALLGLUE,"bitcoinrpc","signrawtransaction","rawtx",params[0],"vins",params[1],"privkeys",params[2],"sighash",params[3])); } static char *sendrawtransaction(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","sendrawtransaction","rawtx",params[0])); + return(sglue1(0,CALLGLUE,"bitcoinrpc","sendrawtransaction","rawtx",params[0])); } static char *getrawchangeaddress(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","getrawchangeaddress","account",params[0])); + return(sglue1(0,CALLGLUE,"bitcoinrpc","getrawchangeaddress","account",params[0])); } #define true 1 #define false 0 struct RPC_info { char *name; char *(*rpcfunc)(RPCARGS); int32_t flag0,remoteflag; } RPCcalls[] = { + { "validatepubkey", &validatepubkey, true, true }, + { "makekeypair", &makekeypair, false, false }, + { "listunspent", &listunspent, false, false }, + { "getblockhash", &getblockhash, false, true }, + { "walletpassphrase", &walletpassphrase, true, false }, { "SuperNET", &SuperNET, false, true }, //{ "SuperNETb", &SuperNET, false, true }, { "help", &help, true, false }, @@ -483,7 +536,7 @@ struct RPC_info { char *name; char *(*rpcfunc)(RPCARGS); int32_t flag0,remotefla { "getnewaddress", &getnewaddress, true, false }, { "getnewpubkey", &makekeypair, true, false }, { "getaccountaddress", &getaccountaddress, true, false }, - { "setaccount", &setaccount, true, false }, + { "setaccount", &setaccountrpc, true, false }, { "getaccount", &getaccount, false, false }, { "getaddressesbyaccount", &getaddressesbyaccount, true, false }, { "sendtoaddress", &sendtoaddress, false, false }, @@ -492,19 +545,17 @@ struct RPC_info { char *name; char *(*rpcfunc)(RPCARGS); int32_t flag0,remotefla { "listreceivedbyaddress", &listreceivedbyaddress, false, false }, { "listreceivedbyaccount", &listreceivedbyaccount, false, false }, { "backupwallet", &backupwallet, true, false }, - { "walletpassphrase", &walletpassphrase, true, false }, { "walletpassphrasechange", &walletpassphrasechange, false, false }, { "walletlock", &walletlock, true, false }, { "encryptwallet", &encryptwallet, false, false }, { "validateaddress", &validateaddress, true, true }, - { "validatepubkey", &validatepubkey, true, true }, { "getbalance", &getbalance, false, false }, { "move", &movecmd, false, false }, { "sendfrom", &sendfrom, false, false }, { "sendmany", &sendmany, false, false }, + { "addmultisig", &addmultisigaddress, false, false }, { "addmultisigaddress", &addmultisigaddress, false, false }, { "getblock", &getblock, false, true }, - { "getblockhash", &getblockhash, false, true }, { "gettransaction", &gettransaction, false, true }, { "listtransactions", &listtransactions, false, false }, { "listaddressgroupings", &listaddressgroupings, false, false }, @@ -517,7 +568,6 @@ struct RPC_info { char *name; char *(*rpcfunc)(RPCARGS); int32_t flag0,remotefla { "dumpwallet", &dumpwallet, true, false }, { "importwallet", &importwallet, false, false }, { "importprivkey", &importprivkey, false, false }, - { "listunspent", &listunspent, false, false }, { "getrawtransaction", &getrawtransaction, false, false }, { "createrawtransaction", &createrawtransaction, false, false }, { "decoderawtransaction", &decoderawtransaction, false, true }, @@ -526,7 +576,6 @@ struct RPC_info { char *name; char *(*rpcfunc)(RPCARGS); int32_t flag0,remotefla { "sendrawtransaction", &sendrawtransaction, false, true }, { "checkwallet", &checkwallet, false, false }, { "repairwallet", &repairwallet, false, false }, - { "makekeypair", &makekeypair, false, false }, { "sendalert", &sendalert, false, false }, // { "createmultisig", &createmultisig, false, false }, @@ -560,59 +609,90 @@ struct RPC_info { char *name; char *(*rpcfunc)(RPCARGS); int32_t flag0,remotefla // { "reservebalance", &reservebalance, false, true}, }; -int32_t is_bitcoinrpc(char *method,char *remoteaddr) +int32_t is_bitcoinrpc(struct supernet_info *myinfo,char *method,char *remoteaddr) { int32_t i; for (i=0; ipublicRPC != 0 ) return(i); } } return(-1); } -char *iguana_bitcoinrpc(struct supernet_info *myinfo,struct iguana_info *coin,char *method,cJSON *params[16],int32_t n,cJSON *json,char *remoteaddr) +char *iguana_bitcoinrpc(struct supernet_info *myinfo,uint16_t port,struct iguana_info *coin,char *method,cJSON *params[16],int32_t n,cJSON *json,char *remoteaddr,cJSON *array) { int32_t i; for (i=0; irpcsymbol; - if ( method != 0 && symbol != 0 && (coin= iguana_coinfind(symbol)) != 0 ) + if ( port == myinfo->rpcport ) + { + if ( jstr(json,"coin") == 0 ) + { + strcpy(symbol,myinfo->rpcsymbol); + if ( symbol[0] == 0 ) + { + c = 'B'; + sprintf(symbol,"%c%c%c%c",c,'T',c+1,c+2); + } + } + else safecopy(symbol,jstr(json,"coin"),sizeof(symbol)); + if ( myinfo->rpcsymbol[0] == 0 ) + strcpy(myinfo->rpcsymbol,symbol); + } + else + { + for (i=0; ichain->rpcport == port ) + break; + if ( i == IGUANA_MAXCOINS ) + coin = 0; + } + if ( coin == 0 && symbol[0] != 0 ) + coin = iguana_coinfind(symbol); + //printf("method.(%s) (%s) remote.(%s) symbol.(%s)\n",method,jprint(json,0),remoteaddr,symbol); + if ( method != 0 && symbol[0] != 0 && (coin != 0 || (coin= iguana_coinfind(symbol)) != 0) ) { if ( (array= jarray(&n,json,"params")) == 0 ) { - n = 1; - params[0] = jobj(json,"params"); + i= 0, n = 0; } - else + else if ( n > 0 ) { - params[0] = jitem(array,0); - if ( n > 1 ) - for (i=1; i=0; i--) + { + params[i] = cJSON_DetachItemFromArray(array,i);//; + //printf("add params[%d] of %d <- (%s) %p.(%p %p)\n",i,n,jprint(params[i],0),params[i],params[i]->next,params[i]->prev); + } } - retstr = iguana_bitcoinrpc(myinfo,coin,method,params,n,json,remoteaddr); + retstr = iguana_bitcoinrpc(myinfo,IGUANA_RPCPORT,coin,method,params,n,json,remoteaddr,array); + if ( n > 0 ) + for (i=0; i0; i--) + if ( url[i] == '.' || url[i] == '/' ) + break; + if ( url[i] == '.' ) + strcpy(filetype,url+i+1); + //printf("return filetype.(%s) size.%ld\n",filetype,filesize); return(filestr); + } if ( strncmp(&url[i],"/api",strlen("/api")) == 0 ) { *jsonflagp = 1; @@ -751,7 +843,7 @@ char *SuperNET_rpcparse(struct supernet_info *myinfo,char *retbuf,int32_t bufsiz //printf("URL.(%s)\n",url); if ( strcmp(url,"/favicon.ico") == 0 ) { - *jsonflagp = -1; + *jsonflagp = 1; return(0); } if ( url[i] != '/' ) @@ -884,11 +976,12 @@ char *SuperNET_rpcparse(struct supernet_info *myinfo,char *retbuf,int32_t bufsiz free_json(argjson); return(0); } - retstr = SuperNET_JSON(myinfo,argjson,remoteaddr); + retstr = SuperNET_JSON(myinfo,argjson,remoteaddr,port); //printf("(%s) {%s} -> (%s) postflag.%d (%s)\n",urlstr,jprint(argjson,0),cJSON_Print(json),*postflagp,retstr); free_json(argjson); return(retstr); } + *jsonflagp = 1; return(clonestr("{\"error\":\"couldnt process packet\"}")); } @@ -916,16 +1009,21 @@ int32_t iguana_getheadersize(char *buf,int32_t recvlen) void iguana_rpcloop(void *args) { static char *jsonbuf; - uint16_t port; struct supernet_info *myinfo = args; + uint16_t port; struct supernet_info *myinfo = args; char filetype[128],content_type[128]; int32_t recvlen,flag,bindsock,postflag,contentlen,sock,remains,numsent,jsonflag,hdrsize,len; - socklen_t clilen; char remoteaddr[64],*buf,*retstr,*space;//,*retbuf; ,n,i,m + socklen_t clilen; char helpname[512],remoteaddr[64],*buf,*retstr,*space;//,*retbuf; ,n,i,m struct sockaddr_in cli_addr; uint32_t ipbits,i,size = IGUANA_WIDTH*IGUANA_HEIGHT*16 + 512; - port = IGUANA_RPCPORT; + if ( (port= myinfo->argport) == 0 ) + port = myinfo->rpcport; + else myinfo->argport = 0; if ( jsonbuf == 0 ) jsonbuf = calloc(1,IGUANA_MAXPACKETSIZE); while ( (bindsock= iguana_socket(1,"127.0.0.1",port)) < 0 ) - exit(-1); - printf("iguana_rpcloop 127.0.0.1:%d bind sock.%d\n",port,bindsock); + { + //exit(-1); + sleep(3); + } + printf(">>>>>>>>>> iguana_rpcloop 127.0.0.1:%d bind sock.%d iguana API enabled <<<<<<<<<\n",port,bindsock); space = calloc(1,size); while ( bindsock >= 0 ) { @@ -939,8 +1037,6 @@ void iguana_rpcloop(void *args) } memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); expand_ipbits(remoteaddr,ipbits); - //printf("RPC.%d for %x (%s)\n",sock,ipbits,ipaddr); - //printf("%p got.(%s) from %s | usock.%d ready.%u dead.%u\n",addr,H.command,addr->ipaddr,addr->usock,addr->ready,addr->dead); memset(jsonbuf,0,IGUANA_MAXPACKETSIZE); remains = (int32_t)(IGUANA_MAXPACKETSIZE - 1); buf = jsonbuf; @@ -975,7 +1071,7 @@ void iguana_rpcloop(void *args) remains = (hdrsize + contentlen) - len; buf = &buf[len]; flag = 1; - printf("got.(%s) %d remains.%d of len.%d contentlen.%d hdrsize.%d remains.%d\n",buf,recvlen,remains,len,contentlen,hdrsize,(hdrsize+contentlen)-len); + //printf("got.(%s) %d remains.%d of len.%d contentlen.%d hdrsize.%d remains.%d\n",buf,recvlen,remains,len,contentlen,hdrsize,(hdrsize+contentlen)-len); continue; } } @@ -997,15 +1093,34 @@ void iguana_rpcloop(void *args) } } } + content_type[0] = 0; if ( recvlen > 0 ) - retstr = SuperNET_rpcparse(myinfo,space,size,&jsonflag,&postflag,jsonbuf,remoteaddr); + { + retstr = SuperNET_rpcparse(myinfo,space,size,&jsonflag,&postflag,jsonbuf,remoteaddr,filetype,port); + if ( filetype[0] != 0 ) + { + static cJSON *mimejson; char *tmp,*typestr=0; long tmpsize; + sprintf(helpname,"%s/mime.json",GLOBAL_HELPDIR); + if ( (tmp= OS_filestr(&tmpsize,helpname)) != 0 ) + { + mimejson = cJSON_Parse(tmp); + free(tmp); + } + if ( mimejson != 0 ) + { + if ( (typestr= jstr(mimejson,filetype)) != 0 ) + sprintf(content_type,"Content-Type: %s\r\n",typestr); + } else printf("parse error.(%s)\n",tmp); + //printf("filetype.(%s) json.%p type.%p tmp.%p [%s]\n",filetype,mimejson,typestr,tmp,content_type); + } + } if ( retstr != 0 ) { char *response,hdrs[1024]; if ( jsonflag != 0 || postflag != 0 ) { response = malloc(strlen(retstr)+1024+1); - sprintf(hdrs,"HTTP/1.1 200 OK\r\nAccess-Control-Allow-Origin: *\r\nAccess-Control-Allow-Credentials: true\r\nAccess-Control-Allow-Methods: GET, POST\r\nCache-Control : no-cache, no-store, must-revalidate\r\nContent-Length : %8d\r\n\r\n",(int32_t)strlen(retstr)); + sprintf(hdrs,"HTTP/1.1 200 OK\r\nAccess-Control-Allow-Origin: *\r\nAccess-Control-Allow-Credentials: true\r\nAccess-Control-Allow-Methods: GET, POST\r\nCache-Control : no-cache, no-store, must-revalidate\r\n%sContent-Length : %8d\r\n\r\n",content_type,(int32_t)strlen(retstr)); response[0] = '\0'; strcat(response,hdrs); strcat(response,retstr); diff --git a/iguana/iguana_scripts.c b/iguana/iguana_scripts.c new file mode 100755 index 000000000..a816322ed --- /dev/null +++ b/iguana/iguana_scripts.c @@ -0,0 +1,1031 @@ +/****************************************************************************** + * 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" +#include "exchanges/bitcoin.h" + +int32_t bitcoin_pubkeyspend(uint8_t *script,int32_t n,uint8_t pubkey[66]) +{ + int32_t plen = bitcoin_pubkeylen(pubkey); + script[n++] = plen; + memcpy(&script[n],pubkey,plen); + n += plen; + script[n++] = SCRIPT_OP_CHECKSIG; + return(n); +} + +int32_t bitcoin_p2shspend(uint8_t *script,int32_t n,uint8_t rmd160[20]) +{ + script[n++] = SCRIPT_OP_HASH160; + script[n++] = 0x14; memcpy(&script[n],rmd160,0x14); n += 0x14; + script[n++] = SCRIPT_OP_EQUAL; + return(n); +} + +int32_t bitcoin_revealsecret160(uint8_t *script,int32_t n,uint8_t secret160[20]) +{ + script[n++] = SCRIPT_OP_HASH160; + script[n++] = 0x14; memcpy(&script[n],secret160,0x14); n += 0x14; + script[n++] = SCRIPT_OP_EQUALVERIFY; + return(n); +} + +int32_t bitcoin_standardspend(uint8_t *script,int32_t n,uint8_t rmd160[20]) +{ + script[n++] = SCRIPT_OP_DUP; + script[n++] = SCRIPT_OP_HASH160; + script[n++] = 0x14; memcpy(&script[n],rmd160,0x14); n += 0x14; + script[n++] = SCRIPT_OP_EQUALVERIFY; + script[n++] = SCRIPT_OP_CHECKSIG; + return(n); +} + +int32_t bitcoin_checklocktimeverify(uint8_t *script,int32_t n,uint32_t locktime) +{ + script[n++] = (locktime >> 24), script[n++] = (locktime >> 16), script[n++] = (locktime >> 8), script[n++] = locktime; + script[n++] = SCRIPT_OP_CHECKLOCKTIMEVERIFY; + script[n++] = SCRIPT_OP_DROP; + return(n); +} + +int32_t bitcoin_MofNspendscript(uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,const struct vin_info *vp) +{ + int32_t i,plen; + script[n++] = 0x50 + vp->M; + for (i=0; iN; i++) + { + if ( (plen= bitcoin_pubkeylen(vp->signers[i].pubkey)) < 0 ) + return(-1); + script[n++] = plen; + memcpy(&script[n],vp->signers[i].pubkey,plen); + n += plen; + } + script[n++] = 0x50 + vp->N; + script[n++] = SCRIPT_OP_CHECKMULTISIG; + calc_rmd160_sha256(p2sh_rmd160,script,n); + return(n); +} + +int32_t bitcoin_p2shscript(uint8_t *script,int32_t n,const uint8_t *p2shscript,const int32_t p2shlen) +{ + if ( p2shlen >= 0xfd ) + { + script[n++] = 0x4d; + script[n++] = (p2shlen & 0xff); + script[n++] = ((p2shlen >> 8) & 0xff); + } + else + { + script[n++] = 0x4c; + script[n++] = p2shlen; + } + memcpy(&script[n],p2shscript,p2shlen), n += p2shlen; + return(n); +} + +int32_t bitcoin_changescript(struct iguana_info *coin,uint8_t *changescript,int32_t n,uint64_t *changep,char *changeaddr,uint64_t inputsatoshis,uint64_t satoshis,uint64_t txfee) +{ + uint8_t addrtype,rmd160[20]; int32_t len; + *changep = 0; + if ( inputsatoshis >= (satoshis + txfee) ) + { + *changep = inputsatoshis - (satoshis + txfee); + if ( changeaddr != 0 && changeaddr[0] != 0 ) + { + bitcoin_addr2rmd160(&addrtype,rmd160,changeaddr); + if ( addrtype == coin->chain->pubtype ) + len = bitcoin_standardspend(changescript,0,rmd160); + else if ( addrtype == coin->chain->p2shtype ) + len = bitcoin_standardspend(changescript,0,rmd160); + else + { + printf("error with mismatched addrtype.%02x vs (%02x %02x)\n",addrtype,coin->chain->pubtype,coin->chain->p2shtype); + return(-1); + } + return(len); + } + else printf("error no change address when there is change\n"); + } + return(-1); +} + +int32_t bitcoin_scriptsig(struct iguana_info *coin,uint8_t *script,int32_t n,const struct vin_info *vp,struct iguana_msgtx *msgtx) +{ + int32_t i,siglen,plen; + if ( vp->N > 1 ) + script[n++] = SCRIPT_OP_NOP; + for (i=0; iN; i++) + { + if ( (siglen= vp->signers[i].siglen) != 0 ) + { + script[n++] = siglen; + memcpy(&script[n],vp->signers[i].sig,siglen), n += siglen; + } + } + if ( (plen= bitcoin_pubkeylen(vp->signers[0].pubkey)) > 0 && vp->type == IGUANA_SCRIPT_76A988AC ) + { + script[n++] = plen; + memcpy(&script[n],vp->signers[0].pubkey,plen), n += plen; + } + if ( vp->type == IGUANA_SCRIPT_P2SH ) + { + printf("add p2sh script to sig\n"); + n = bitcoin_p2shscript(script,n,vp->p2shscript,vp->p2shlen); + } + return(n); +} + +int32_t bitcoin_cltvscript(uint8_t p2shtype,char *ps2h_coinaddr,uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,char *senderaddr,char *otheraddr,uint8_t secret160[20],uint32_t locktime) +{ + // OP_IF + // OP_CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG + // OP_ELSE + // OP_HASH160 secret160 OP_EQUALVERIFY OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG // standard spend + // OP_ENDIF + uint8_t rmd160A[20],rmd160B[20],addrtypeA,addrtypeB; + bitcoin_addr2rmd160(&addrtypeA,rmd160A,senderaddr); + bitcoin_addr2rmd160(&addrtypeB,rmd160B,otheraddr); + script[n++] = SCRIPT_OP_IF; + n = bitcoin_checklocktimeverify(script,n,locktime); + n = bitcoin_standardspend(script,n,rmd160A); + script[n++] = SCRIPT_OP_ELSE; + n = bitcoin_revealsecret160(script,n,secret160); + n = bitcoin_standardspend(script,n,rmd160B); + script[n++] = SCRIPT_OP_ENDIF; + calc_rmd160_sha256(p2sh_rmd160,script,n); + bitcoin_address(ps2h_coinaddr,p2shtype,p2sh_rmd160,20); + return(n); +} + +uint8_t iguana_addrtype(struct iguana_info *coin,uint8_t script_type) +{ + if ( script_type == IGUANA_SCRIPT_76A988AC || script_type == IGUANA_SCRIPT_AC || script_type == IGUANA_SCRIPT_76AC ) + return(coin->chain->pubtype); + else return(coin->chain->p2shtype); +} + +int32_t iguana_scriptgen(struct iguana_info *coin,int32_t *Mp,int32_t *nump,char *coinaddr,uint8_t *script,char *asmstr,uint8_t rmd160[20],uint8_t type,const struct vin_info *vp,int32_t txi) +{ + uint8_t addrtype; char rmd160str[41],pubkeystr[256]; int32_t plen,i,m,n,flag = 0,scriptlen = 0; + m = n = 0; + if ( asmstr != 0 ) + asmstr[0] = 0; + addrtype = iguana_addrtype(coin,type); + if ( type == IGUANA_SCRIPT_76A988AC || type == IGUANA_SCRIPT_AC || type == IGUANA_SCRIPT_76AC || type == IGUANA_SCRIPT_P2SH ) + { + init_hexbytes_noT(rmd160str,rmd160,20); + bitcoin_address(coinaddr,addrtype,rmd160,20); + } + switch ( type ) + { + case IGUANA_SCRIPT_NULL: + if ( asmstr != 0 ) + strcpy(asmstr,txi == 0 ? "coinbase " : "PoSbase "); + flag++; + coinaddr[0] = 0; + break; + case IGUANA_SCRIPT_76AC: + case IGUANA_SCRIPT_AC: + if ( (plen= bitcoin_pubkeylen(vp->signers[0].pubkey)) < 0 ) + return(0); + init_hexbytes_noT(pubkeystr,(uint8_t *)vp->signers[0].pubkey,plen); + if ( asmstr != 0 ) + { + if ( type == IGUANA_SCRIPT_76AC ) + strcpy(asmstr,"OP_DUP "); + sprintf(asmstr + strlen(asmstr),"%s OP_CHECKSIG // %s",pubkeystr,coinaddr); + } + if ( type == IGUANA_SCRIPT_76AC ) + script[scriptlen++] = 0x76; + scriptlen = bitcoin_pubkeyspend(script,scriptlen,(uint8_t *)vp->signers[0].pubkey); + //printf("[%02x] type.%d scriptlen.%d\n",vp->signers[0].pubkey[0],type,scriptlen); + break; + case IGUANA_SCRIPT_76A988AC: + if ( asmstr != 0 ) + sprintf(asmstr,"OP_DUP OP_HASH160 %s OP_EQUALVERIFY OP_CHECKSIG // %s",rmd160str,coinaddr); + scriptlen = bitcoin_standardspend(script,0,rmd160); + break; + case IGUANA_SCRIPT_P2SH: + if ( asmstr != 0 ) + sprintf(asmstr,"OP_HASH160 %s OP_EQUAL // %s",rmd160str,coinaddr); + scriptlen = bitcoin_p2shspend(script,0,rmd160); + break; + case IGUANA_SCRIPT_OPRETURN: + if ( asmstr != 0 ) + strcpy(asmstr,"OP_RETURN "); + bitcoin_address(coinaddr,addrtype,(uint8_t *)&vp->spendscript[0],vp->spendlen); + flag++; + break; + case IGUANA_SCRIPT_3of3: m = 3, n = 3; break; + case IGUANA_SCRIPT_2of3: m = 2, n = 3; break; + case IGUANA_SCRIPT_1of3: m = 1, n = 3; break; + case IGUANA_SCRIPT_2of2: m = 2, n = 2; break; + case IGUANA_SCRIPT_1of2: m = 1, n = 2; break; + case IGUANA_SCRIPT_1of1: m = 1, n = 1; break; + case IGUANA_SCRIPT_MSIG: m = vp->M, n = vp->N; break; + case IGUANA_SCRIPT_DATA: + if ( asmstr != 0 ) + strcpy(asmstr,"DATA ONLY"); + bitcoin_address(coinaddr,addrtype,(uint8_t *)&vp->spendscript[0],vp->spendlen); + flag++; + break; + case IGUANA_SCRIPT_STRANGE: + if ( asmstr != 0 ) + strcpy(asmstr,"STRANGE SCRIPT "); + bitcoin_address(coinaddr,addrtype,(uint8_t *)&vp->spendscript[0],vp->spendlen); + flag++; + break; + default: break;//printf("unexpected script type.%d\n",type); break; + } + if ( n > 0 ) + { + scriptlen = bitcoin_MofNspendscript(rmd160,script,0,vp); + bitcoin_address(coinaddr,coin->chain->p2shtype,script,scriptlen); + if ( asmstr != 0 ) + { + sprintf(asmstr,"%d ",m); + for (i=0; isigners[i].pubkey)) > 0 ) + { + init_hexbytes_noT(asmstr + strlen(asmstr),(uint8_t *)vp->signers[i].pubkey,plen); + if ( asmstr != 0 ) + strcat(asmstr," "); + } + else if ( asmstr != 0 ) + strcat(asmstr,"NOPUBKEY "); + sprintf(asmstr + strlen(asmstr),"%d // M.%d of N.%d [",n,m,n); + for (i=0; isigners[i].coinaddr,ispendlen > 0 ) + init_hexbytes_noT(asmstr + strlen(asmstr),(uint8_t *)vp->spendscript,vp->spendlen); + *Mp = m, *nump = n; + return(scriptlen); +} + +int32_t _iguana_calcrmd160(struct iguana_info *coin,struct vin_info *vp) +{ + static uint8_t zero_rmd160[20]; + char hexstr[8192]; uint8_t sha256[32],*script,type; int32_t i,n,m,plen; + vp->N = 1; + vp->M = 1; + type = IGUANA_SCRIPT_STRANGE; + init_hexbytes_noT(hexstr,vp->spendscript,vp->spendlen); + //char str[65]; printf("script.(%s).%d in %s len.%d plen.%d spendlen.%d cmp.%d\n",hexstr,vp->spendlen,bits256_str(str,vp->vin.prev_hash),vp->spendlen,bitcoin_pubkeylen(&vp->spendscript[1]),vp->spendlen,vp->spendscript[vp->spendlen-1] == SCRIPT_OP_CHECKSIG); + if ( vp->spendlen == 0 ) + { + if ( zero_rmd160[0] == 0 ) + { + calc_rmd160_sha256(zero_rmd160,vp->spendscript,vp->spendlen); + //vcalc_sha256(0,sha256,vp->spendscript,vp->spendlen); // e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 + //calc_rmd160(0,zero_rmd160,sha256,sizeof(sha256)); // b472a266d0bd89c13706a4132ccfb16f7c3b9fcb + init_hexbytes_noT(hexstr,zero_rmd160,20); + char str[65]; printf("iguana_calcrmd160 zero len %s -> %s\n",bits256_str(str,*(bits256 *)sha256),hexstr); + } + memcpy(vp->rmd160,zero_rmd160,sizeof(zero_rmd160)); + return(IGUANA_SCRIPT_NULL); + } + else if ( vp->spendscript[0] == SCRIPT_OP_RETURN ) + type = IGUANA_SCRIPT_OPRETURN; + else if ( vp->spendscript[0] == SCRIPT_OP_DUP && vp->spendscript[1] == SCRIPT_OP_HASH160 && vp->spendscript[2] == 20 && vp->spendscript[vp->spendscript[2]+3] == SCRIPT_OP_EQUALVERIFY && vp->spendscript[vp->spendscript[2]+4] == SCRIPT_OP_CHECKSIG ) + { + //printf("IGUANA_SCRIPT_76A988AC plen.%d vs %d vp->spendlen\n",vp->spendscript[2]+4,vp->spendlen); + // 76a9145f69cb73016264270dae9f65c51f60d0e4d6fd4488ac + memcpy(vp->rmd160,&vp->spendscript[3],20); + if ( (plen= vp->spendscript[2]+5) != vp->spendlen ) + { + return(IGUANA_SCRIPT_STRANGE); + while ( plen < vp->spendlen ) + if ( vp->spendscript[plen++] != 0x61 ) // nop + return(IGUANA_SCRIPT_STRANGE); + } + return(IGUANA_SCRIPT_76A988AC); + } + // 21035f1321ed17d387e4433b2fa229c53616057964af065f98bfcae2233c5108055eac + else if ( vp->spendscript[0] == SCRIPT_OP_DUP && (plen= bitcoin_pubkeylen(&vp->spendscript[2])) > 0 && vp->spendscript[vp->spendlen-1] == SCRIPT_OP_CHECKSIG && vp->spendscript[0] == plen && vp->spendlen == plen+3 ) + { + memcpy(vp->signers[0].pubkey,&vp->spendscript[2],plen); + calc_rmd160_sha256(vp->rmd160,vp->signers[0].pubkey,plen); + //printf("found IGUANA_SCRIPT_76AC\n"); + return(IGUANA_SCRIPT_76AC); + } + else if ( (plen= bitcoin_pubkeylen(&vp->spendscript[1])) > 0 && vp->spendscript[vp->spendlen-1] == SCRIPT_OP_CHECKSIG && vp->spendscript[0] == plen && vp->spendlen == plen+2 ) + { + memcpy(vp->signers[0].pubkey,&vp->spendscript[1],plen); + calc_rmd160_sha256(vp->rmd160,vp->signers[0].pubkey,plen); + //printf("found IGUANA_SCRIPT_AC\n"); + return(IGUANA_SCRIPT_AC); + } + else if ( vp->spendscript[0] == SCRIPT_OP_HASH160 && vp->spendscript[1] == 0x14 && vp->spendlen == 23 && vp->spendscript[22] == SCRIPT_OP_EQUAL ) + { + memcpy(vp->rmd160,vp->spendscript+2,20); + return(IGUANA_SCRIPT_P2SH); + } + else if ( vp->spendlen > 34 && vp->spendscript[vp->spendlen-1] == SCRIPT_OP_CHECKMULTISIG && (n= vp->spendscript[vp->spendlen-2]) >= 0x51 && n <= 0x60 && (m= vp->spendscript[0]) >= 0x51 && m <= n ) // m of n multisig + { + m -= 0x50, n -= 0x50; + script = vp->spendscript+1; + for (i=0; isigners[i].pubkey,script,plen); + calc_rmd160_sha256(vp->signers[i].rmd160,vp->signers[i].pubkey,plen); + bitcoin_address(vp->signers[i].coinaddr,coin->chain->pubtype,vp->signers[i].pubkey,plen); + } + if ( (int32_t)((long)script - (long)vp->spendscript) == vp->spendlen-2 ) + { + vp->N = n; + vp->M = m; + //printf("M.%d N.%d\n",m,n); + } + calc_rmd160_sha256(vp->rmd160,vp->spendscript,vp->spendlen); + if ( n == 3 ) + { + if ( m == 3 ) + return(IGUANA_SCRIPT_3of3); + else if ( m == 2 ) + return(IGUANA_SCRIPT_2of3); + else if ( m == 1 ) + return(IGUANA_SCRIPT_1of3); + } + else if ( n == 2 ) + { + if ( m == 2 ) + return(IGUANA_SCRIPT_2of2); + else if ( m == 1 ) + return(IGUANA_SCRIPT_1of2); + } + else if ( m == 1 && n == 1 ) + return(IGUANA_SCRIPT_1of1); + //printf("strange msig M.%d of N.%d\n",m,n); + return(IGUANA_SCRIPT_MSIG); + } + else if ( vp->spendlen == vp->spendscript[0]+1 ) + { + //printf("just data.%d\n",vp->spendlen); + memcpy(vp->rmd160,zero_rmd160,sizeof(zero_rmd160)); + return(IGUANA_SCRIPT_DATA); + } + if ( type != IGUANA_SCRIPT_OPRETURN && type != IGUANA_SCRIPT_DATA ) + { + if ( vp->spendlen > 0 && vp->spendlen < sizeof(hexstr)/2-1 ) + { + static FILE *fp; + init_hexbytes_noT(hexstr,vp->spendscript,vp->spendlen); + //char str[65]; printf("unparsed script.(%s).%d in %s len.%d\n",hexstr,vp->spendlen,bits256_str(str,vp->vin.prev_hash),vp->spendlen); + if ( 1 && fp == 0 ) + fp = fopen("unparsed.txt","w"); + if ( fp != 0 ) + fprintf(fp,"%s\n",hexstr), fflush(fp); + } else sprintf(hexstr,"pkscript overflowed %ld\n",(long)sizeof(hexstr)); + } + calc_rmd160_sha256(vp->rmd160,vp->spendscript,vp->spendlen); + return(type); +} + +int32_t iguana_calcrmd160(struct iguana_info *coin,char *asmstr,struct vin_info *vp,uint8_t *pk_script,int32_t pk_scriptlen,bits256 debugtxid,int32_t vout,uint32_t sequence) +{ + int32_t scriptlen; uint8_t script[IGUANA_MAXSCRIPTSIZE]; + memset(vp,0,sizeof(*vp)); + vp->vin.prev_hash = debugtxid, vp->vin.prev_vout = vout; + vp->spendlen = pk_scriptlen; + vp->vin.sequence = sequence; + memcpy(vp->spendscript,pk_script,pk_scriptlen); + if ( (vp->type= _iguana_calcrmd160(coin,vp)) >= 0 ) + { + scriptlen = iguana_scriptgen(coin,&vp->M,&vp->N,vp->coinaddr,script,asmstr,vp->rmd160,vp->type,(const struct vin_info *)vp,vout); + if ( vp->M == 0 && vp->N == 0 ) + { + vp->M = vp->N = 1; + strcpy(vp->signers[0].coinaddr,vp->coinaddr); + memcpy(vp->signers[0].rmd160,vp->rmd160,20); + } + if ( scriptlen != pk_scriptlen || (scriptlen != 0 && memcmp(script,pk_script,scriptlen) != 0) ) + { + if ( vp->type != IGUANA_SCRIPT_OPRETURN && vp->type != IGUANA_SCRIPT_DATA && vp->type != IGUANA_SCRIPT_STRANGE ) + { + int32_t i; + printf("\n--------------------\n"); + for (i=0; itype,scriptlen,pk_scriptlen); + } + } + } + return(vp->type); +} + +//error memalloc mem.0x7f6fc6e4a2a8 94.242.229.158 alloc 1 used 2162688 totalsize.2162688 -> 94.242.229.158 (nil) + +int32_t bitcoin_scriptget(struct iguana_info *coin,int32_t *hashtypep,uint32_t *sigsizep,uint32_t *pubkeysizep,uint32_t *suffixp,struct vin_info *vp,uint8_t *scriptsig,int32_t len,int32_t spendtype) +{ + char asmstr[IGUANA_MAXSCRIPTSIZE*3]; int32_t j,n,siglen,plen; + j = n = 0; + *suffixp = *pubkeysizep = 0; + *hashtypep = SIGHASH_ALL; + while ( (siglen= scriptsig[n]) >= 70 && siglen <= 73 && n+siglen < len && j < 16 ) + { + vp->signers[j].siglen = siglen; + memcpy(vp->signers[j].sig,&scriptsig[n+1],siglen); + if ( j == 0 ) + *hashtypep = vp->signers[j].sig[siglen-1]; + else if ( vp->signers[j].sig[siglen-1] != *hashtypep ) + { + //printf("SIGHASH.%d mismatch %d vs %d\n",j,vp->signers[j].sig[siglen-1],*hashtypep); + break; + } + (*sigsizep) += siglen; + //printf("sigsize %d [%02x]\n",*sigsizep,vp->signers[j].sig[siglen-1]); + n += (siglen + 1); + j++; + if ( spendtype == 0 && j > 1 ) + spendtype = IGUANA_SCRIPT_MSIG; + } + vp->numsigs = j; + vp->type = spendtype; + if ( j == 0 ) + { + *suffixp = len; + vp->spendlen = len; + return(vp->spendlen); + } + j = 0; + while ( ((plen= scriptsig[n]) == 33 || plen == 65) && j < 16 && plen+n <= len ) + { + memcpy(vp->signers[j].pubkey,&scriptsig[n+1],plen); + calc_rmd160_sha256(vp->signers[j].rmd160,vp->signers[j].pubkey,plen); + if ( j == 0 ) + memcpy(vp->rmd160,vp->signers[j].rmd160,20); + n += (plen + 1); + (*pubkeysizep) += plen; + j++; + } + vp->numpubkeys = j; + if ( n+2 < len && (scriptsig[n] == 0x4c || scriptsig[n] == 0x4d) ) + { + if ( scriptsig[n] == 0x4c ) + vp->p2shlen = scriptsig[n+1], n += 2; + else vp->p2shlen = ((uint32_t)scriptsig[n+1] + ((uint32_t)scriptsig[n+2] << 8)), n += 3; + //printf("p2sh opcode.%02x %02x %02x scriptlen.%d\n",scriptsig[n],scriptsig[n+1],scriptsig[n+2],vp->p2shlen); + if ( vp->p2shlen < IGUANA_MAXSCRIPTSIZE && n+vp->p2shlen <= len ) + { + memcpy(vp->p2shscript,&scriptsig[n],vp->p2shlen); + n += vp->p2shlen; + vp->type = IGUANA_SCRIPT_P2SH; + } else vp->p2shlen = 0; + } + if ( n < len ) + *suffixp = (len - n); + /*if ( len == 0 ) + { + // txid.(eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2).v1 + decode_hex(vp->rmd160,20,"010966776006953d5567439e5e39f86a0d273bee");//3564a74f9ddb4372301c49154605573d7d1a88fe"); + vp->type = IGUANA_SCRIPT_76A988AC; + }*/ + vp->spendlen = iguana_scriptgen(coin,&vp->M,&vp->N,vp->coinaddr,vp->spendscript,asmstr,vp->rmd160,vp->type,(const struct vin_info *)vp,vp->vin.prev_vout); + //printf("type.%d asmstr.(%s) spendlen.%d\n",vp->type,asmstr,vp->spendlen); + return(vp->spendlen); +} + +int32_t iguana_vinscriptparse(struct iguana_info *coin,struct vin_info *vp,uint32_t *sigsizep,uint32_t *pubkeysizep,uint32_t *p2shsizep,uint32_t *suffixp,uint8_t *vinscript,int32_t scriptlen) +{ + int32_t hashtype; + *sigsizep = *pubkeysizep = *p2shsizep = *suffixp = 0; + if ( bitcoin_scriptget(coin,&hashtype,sigsizep,pubkeysizep,suffixp,vp,vinscript,scriptlen,0) < 0 ) + { + printf("iguana_vinscriptparse: error parsing vinscript?\n"); + return(-1); + } + if ( vp->type == IGUANA_SCRIPT_P2SH ) + { + *p2shsizep = vp->p2shlen + 1 + (vp->p2shlen >= 0xfd)*2; + //printf("P2SHSIZE.%d\n",*p2shsizep); + } + return(hashtype); +} + +char *iguana_scriptget(struct iguana_info *coin,char *scriptstr,char *asmstr,int32_t max,int32_t hdrsi,uint32_t unspentind,bits256 txid,int32_t vout,uint8_t *rmd160,int32_t type,uint8_t *pubkey33) +{ + int32_t scriptlen; uint8_t script[IGUANA_MAXSCRIPTSIZE]; struct vin_info V,*vp = &V; + memset(vp,0,sizeof(*vp)); + scriptstr[0] = asmstr[0] = 0; + if ( pubkey33 != 0 && bitcoin_pubkeylen(pubkey33) > 0 ) + memcpy(vp->signers[0].pubkey,pubkey33,33); + scriptlen = iguana_scriptgen(coin,&vp->M,&vp->N,vp->coinaddr,script,asmstr,rmd160,type,(const struct vin_info *)vp,vout); + init_hexbytes_noT(scriptstr,script,scriptlen); + return(scriptstr); +} + + +#ifdef later + +uint32_t iguana_ramchain_pubkeyoffset(struct iguana_info *coin,RAMCHAIN_FUNC,int32_t createflag,uint32_t *pkindp,uint32_t *scriptoffsetp,uint8_t *pubkey,uint8_t rmd160[20]) +{ + uint32_t pkind; int32_t plen; struct iguana_kvitem *ptr; + if ( (ptr= iguana_hashfind(ramchain,'P',rmd160)) == 0 ) + { + if ( createflag != 0 ) + { + //printf("from pubkeyoffset\n"); + pkind = iguana_ramchain_addpkhash(coin,RAMCHAIN_ARG,rmd160,0,0,0); + //int32_t i; for (i=0; i<33; i++) + // printf("%02x",pubkey[i]); + //printf(" pkind.%d created from pubkeyoffset\n",pkind); + *pkindp = pkind + 1; + } else return(0); + } else pkind = ptr->hh.itemind; + if ( P[pkind].pubkeyoffset == 0 ) + { + plen = bitcoin_pubkeylen(pubkey); + if ( plen > 0 ) + { + if ( *scriptoffsetp == 0 ) + *scriptoffsetp++ = 0; + P[pkind].pubkeyoffset = *scriptoffsetp, *scriptoffsetp += plen; + // printf(" plen.%d -> new offset.%d\n",plen,*scriptoffsetp); + memcpy(&Kspace[P[pkind].pubkeyoffset],pubkey,plen); + } + else + { + //int32_t i; for (i=0; iscriptoffset]; uint32_t poffset; int32_t totalsize,sigslen,plen,stacksize=0,p2shlen=0,scriptlen = 0; + if ( s->scriptoffset == 0 ) + { + //printf("iguana_vinscriptdecode: null scriptoffset\n"); + return(0); + } + len += iguana_rwvarint32(0,&metascript[len],(void *)&totalsize); + *metalenp = 0; + if ( s->rawmode != 0 ) + { + *metalenp = 0; + if ( totalsize < IGUANA_MAXSCRIPTSIZE ) + { + //printf("rawmode.%d\n",totalsize); + memcpy(_script,&metascript[len],totalsize); + return(totalsize); + } + printf("illegal rawmode vinscript totalsize.%d\n",totalsize); + return(-1); + } + if ( totalsize > IGUANA_MAXSCRIPTSIZE ) + { + fprintf(stderr,"totalsize too big %d\n",totalsize); + return(0); + } + // expand metascript!! + totalsize += len; + len += iguana_rwvarint32(0,&metascript[len],(void *)&sigslen); + //printf("totalsize %d, len %d sigslen %d numpubs.%d p2sh.%d\n",totalsize,len,sigslen,s->numpubkeys,s->p2sh); + if ( sigslen > 0 && sigslen < 74*16 ) + { + len += iguana_rwvarint32(0,&metascript[len],(void *)&stacksize); + if ( ramchain->sigsfileptr != 0 && stacksize < ramchain->sigsfilesize ) + memcpy(&_script[scriptlen],(void *)((long)ramchain->sigsfileptr + ramchain->sigsfilesize - stacksize),sigslen); + else + { + diff = (long)Kstackend - (long)Kspace; + if ( stacksize < diff ) + memcpy(&_script[scriptlen],&Kspace[diff - stacksize],sigslen); + } + scriptlen += sigslen; + } + if ( s->numpubkeys > 0 ) + { + for (i=0; inumpubkeys; i++) + { + len += iguana_rwvarint32(0,&metascript[len],(void *)&poffset); + if ( poffset > ramchain->H.data->scriptspace-33 ) + { + printf("illegal poffset.%d/%d\n",poffset,ramchain->H.data->scriptspace); + return(-1); + } + //printf("poffset[%d] of %d poffset %x\n",i,s->numpubkeys,poffset); + pubkey = &Kspace[poffset]; + if ( (plen= bitcoin_pubkeylen(pubkey)) <= 0 ) + { + /*int32_t j; + for (j=0; jnumpubkeys,s->numsigs);*/ + *metalenp = len; + return(scriptlen); + } + else + { + _script[scriptlen++] = plen; + //printf("plen.%d\n",i); + memcpy(&_script[scriptlen],pubkey,plen), scriptlen += plen; + } + } + } + if ( s->p2sh != 0 ) + { + len += iguana_rwvarint32(0,&metascript[len],(void *)&p2shlen); + if ( p2shlen > 0 && p2shlen < IGUANA_MAXSCRIPTSIZE ) + { + if ( p2shlen <= 75 ) + _script[scriptlen++] = 0x4c, _script[scriptlen++] = p2shlen; + else _script[scriptlen++] = 0x4d, _script[scriptlen++] = p2shlen & 0xff, _script[scriptlen++] = (p2shlen>>8) & 0xff; + //printf("p2shlen.%d\n",p2shlen); + memcpy(&_script[scriptlen],&metascript[len],p2shlen), scriptlen += p2shlen, len += p2shlen; + } + } + if ( (suffixlen= (totalsize - len)) != 0 ) + { + if ( suffixlen < 0 || suffixlen >= IGUANA_MAXSCRIPTSIZE ) + printf("suffixlen.%d totalsize.%d vs len.%d\n",suffixlen,totalsize,len); + else memcpy(&_script[scriptlen],&metascript[len],suffixlen), scriptlen += suffixlen, len += suffixlen; + } + *metalenp = len - 1 - (len>=0xfd ? 2 : 0); + return(scriptlen); +} + +int32_t iguana_vinscriptencode(struct iguana_info *coin,int32_t *metalenp,uint8_t *Kstackend,uint32_t stacksize,uint8_t *Kspace,uint32_t scriptoffset,struct iguana_spend *s,uint8_t *sigsbuf,int32_t sigslen,uint32_t *poffsets,uint8_t *p2shscript,int32_t p2shlen,uint8_t *suffix,int32_t suffixlen) +{ + int32_t i,len = 0; long diff; uint8_t metascript[IGUANA_MAXSCRIPTSIZE]; uint32_t origoffset = scriptoffset; + *metalenp = 0; + //printf("vinencode[%d] <- stacksize.%d sigslen.%d numsigs.%d numpubs.%d p2shlen.%d suffixlen.%d\n",scriptoffset,stacksize,sigslen,s->numsigs,s->numpubkeys,p2shlen,suffixlen); + if ( sigslen == 0 && s->numpubkeys == 0 && p2shlen == 0 && suffixlen == 0 ) + { + printf("spendencode: null script??\n"); + return(0); + } + len += iguana_rwvarint32(1,&metascript[len],(void *)&sigslen); + if ( sigslen > 0 ) + { + diff = (long)Kstackend - (long)Kspace; + if ( diff < stacksize ) + { + printf("vinscriptencode error diff.%ld < stacksize.%u\n",diff,stacksize); + return(0); + } + memcpy(&Kspace[diff - stacksize],sigsbuf,sigslen); + //printf("Kspace.%p Kstackend.%p diff.%ld stacksize.%d sigsbuf.%p sigslen.%d [%02x]\n",Kspace,Kstackend,diff,stacksize,sigsbuf,sigslen,Kspace[diff - stacksize + sigslen - 1]); + for (i=0; i %p stacksize.%d\n",len,&Kspace[diff - stacksize],stacksize); + } + if ( s->numpubkeys > 0 ) + { + //printf("metalen.%d\n",len); + for (i=0; inumpubkeys; i++) + { + len += iguana_rwvarint32(1,&metascript[len],&poffsets[i]); + //printf("EMIT pubkey poffsets.[%x] len.%d\n",poffsets[0],len); + } + } + if ( p2shlen != 0 ) + { + len += iguana_rwvarint32(1,&metascript[len],(void *)&p2shlen); + memcpy(&metascript[len],p2shscript,p2shlen), len += p2shlen; + } + if ( suffixlen > 0 && suffixlen < IGUANA_MAXSCRIPTSIZE ) + { + //printf("[%d] <- SUFFIX.(%02x) len.%d\n",len,suffix[0],suffixlen); + memcpy(&metascript[len],suffix,suffixlen), len += suffixlen; + } + scriptoffset += iguana_rwvarint32(1,&Kspace[scriptoffset],(void *)&len); + memcpy(&Kspace[scriptoffset],metascript,len); + //for (i=0; i 0 && vinscriptlen < IGUANA_MAXSCRIPTSIZE ) + { + memset(&V,0,sizeof(V)); + if ( rawflag == 0 ) + { + memset(&V,0,sizeof(V)); + s->sighash = iguana_vinscriptparse(coin,&V,&sigsize,&pubkeysize,&p2shsize,&suffixlen,vinscript,vinscriptlen); + //for (i=0; i<33; i++) + // printf("%02x",V.signers[0].pubkey[i]); + //printf(" parsed pubkey0\n"); + //for (i=0; i<20; i++) + // printf("%02x",V.signers[0].rmd160[i]); + //printf(" parsed rmd160_0\n"); + memset(sigsbuf,0,sizeof(sigsbuf)); + memset(poffsets,0,sizeof(poffsets)); + for (i=sigslen=0; i 0 ) + { + sigsbuf[sigslen++] = V.signers[i].siglen; + memcpy(&sigsbuf[sigslen],V.signers[i].sig,V.signers[i].siglen); + sigslen += V.signers[i].siglen; + } + } + for (i=0; ipkind,&ramchain->H.scriptoffset,V.signers[i].pubkey,V.signers[i].rmd160)) == 0 ) + { + //printf("addspend: error couldnt get pubkeyoffset\n"); + return(-1); + } //else printf("poffset[%d] <- 0x%x (%02x %02x)\n",i,poffsets[i],Kspace[poffsets[i]],Kspace[poffsets[i]+32]); + } + } + s->numsigs = V.numsigs; + s->numpubkeys = V.numpubkeys; + if ( p2shsize != 0 ) + s->p2sh = 1; + suffix = &vinscript[vinscriptlen-suffixlen]; + if ( sigslen+V.numsigs+V.numpubkeys+suffixlen != 0 ) + { + ramchain->H.stacksize += sigslen; + s->scriptoffset = ramchain->H.scriptoffset; + len = iguana_vinscriptencode(coin,&metalen,&Kspace[ramchain->H.data->scriptspace],ramchain->H.stacksize,Kspace,ramchain->H.scriptoffset,s,sigsbuf,sigslen,poffsets,V.p2shscript,V.p2shlen,suffix,suffixlen); + } else printf("sigslen.%d numsigs.%d numpubs.%d suffixlen.%d\n",sigslen,V.numsigs,V.numpubkeys,suffixlen); + } + else + { + metalen = sigslen = 0; + s->sighash = s->numsigs = s->numpubkeys = s->p2sh = 0; + suffix = vinscript; + suffixlen = vinscriptlen; + //for (i=0; iscriptoffset = ramchain->H.scriptoffset; + s->rawmode = 1; + ramchain->H.scriptoffset += iguana_rwvarint32(1,&Kspace[s->scriptoffset],(void *)&vinscriptlen); + memcpy(&Kspace[ramchain->H.scriptoffset],vinscript,vinscriptlen); + ramchain->H.scriptoffset += vinscriptlen; + } + } + //printf("checklen.%d scriptoffset.%d\n",checklen,ramchain->H.scriptoffset); + if ( (decodelen= iguana_vinscriptdecode(coin,ramchain,&checkmetalen,_script,&Kspace[ramchain->H.data->scriptspace],Kspace,s)) != vinscriptlen || (vinscript != 0 && memcmp(_script,vinscript,vinscriptlen) != 0) || checkmetalen != metalen ) + { + //static uint64_t counter; + //if ( counter++ < 100 ) + { + for (i=0; iH.stacksize -= sigslen; + return(-1); + } //else s->coinbase = 1;//, printf("vin reconstructed metalen.%d vinlen.%d\n",metalen,checklen); + ramchain->H.scriptoffset += len; + return(metalen); +} + +int32_t iguana_scriptspaceraw(struct iguana_info *coin,int32_t *scriptspacep,int32_t *sigspacep,int32_t *pubkeyspacep,struct iguana_msgtx *txarray,int32_t txn_count) +{ + uint32_t i,j,sigspace,suffixlen,scriptspace,pubkeyspace,p2shspace,p2shsize,sigsize,pubkeysize,type,scriptlen; //struct iguana_spend256 *s; struct iguana_unspent20 *u; + struct iguana_msgtx *tx; struct vin_info V; uint8_t rmd160[20],scriptdata[IGUANA_MAXSCRIPTSIZE]; char asmstr[IGUANA_MAXSCRIPTSIZE*2+1]; + return(1); + for (i=sigspace=scriptspace=pubkeyspace=p2shspace=0; itx_out; j++) + { + memset(&V,0,sizeof(V)); + type = iguana_calcrmd160(coin,asmstr,&V,tx->vouts[j].pk_script,tx->vouts[j].pk_scriptlen,tx->txid,j,0xffffffff); + if ( type != 0 ) // IGUANA_SCRIPT_NULL + { + memcpy(rmd160,V.rmd160,sizeof(rmd160)); + memset(&V,0,sizeof(V)); + scriptlen = iguana_scriptgen(coin,&V.M,&V.N,V.coinaddr,scriptdata,asmstr,rmd160,type,(const struct vin_info *)&V,j); + if ( (scriptlen != tx->vouts[j].pk_scriptlen || (scriptdata != 0 && memcmp(scriptdata,tx->vouts[j].pk_script,scriptlen) != 0)) ) //tx->vouts[j].pk_scriptlen > sizeof(u->script) && + { + scriptspace += tx->vouts[j].pk_scriptlen; + //printf("type.%d scriptspace.%d <= %d + 2\n",type,scriptspace,tx->vouts[j].pk_scriptlen); + } + } + } + for (j=0; jtx_in; j++) + { + memset(&V,0,sizeof(V)); + iguana_vinscriptparse(coin,&V,&sigsize,&pubkeysize,&p2shsize,&suffixlen,tx->vins[j].vinscript,tx->vins[j].scriptlen); + pubkeyspace += pubkeysize; + p2shspace += p2shsize; + //if ( tx->vins[j].scriptlen > sizeof(s->vinscript) ) + sigspace += tx->vins[j].scriptlen; + } + } + *scriptspacep = scriptspace + p2shspace, *sigspacep = sigspace, *pubkeyspacep = pubkeyspace; + return(scriptspace + sigspace); +} + +int32_t iguana_ramchain_scriptspace(struct iguana_info *coin,int32_t *sigspacep,int32_t *pubkeyspacep,struct iguana_ramchain *ramchain) +{ + RAMCHAIN_DECLARE; + int32_t j,scriptlen; struct vin_info V; + uint32_t sequence,p2shspace,altspace,sigspace,pubkeyspace,spendind,unspentind,p2shsize,pubkeysize,sigsize,scriptspace,suffixlen; + struct iguana_txid *tx; struct iguana_ramchaindata *rdata; uint8_t *scriptdata; + _iguana_ramchain_setptrs(RAMCHAIN_PTRS,ramchain->H.data); + *sigspacep = *pubkeyspacep = altspace = 0; + return(1); + if ( (rdata= ramchain->H.data) == 0 || ramchain->expanded != 0 ) + { + printf("iguana_ramchain_scriptspace cant iterate without data and requires simple ramchain\n"); + return(-1); + } + sigspace = pubkeyspace = p2shspace = 0; + scriptspace = 1; + for (ramchain->H.txidind=rdata->firsti; ramchain->H.txidindnumtxids; ramchain->H.txidind++) + { + tx = &T[ramchain->H.txidind]; + for (j=0; jnumvouts; j++) + { + if ( (unspentind= ramchain->H.unspentind++) < rdata->numunspents ) + if ( U[unspentind].scriptlen != 0 ) + scriptspace += U[unspentind].scriptlen + 3; + } + for (j=0; jnumvins; j++) + {break; + if ( (spendind= ramchain->H.spendind++) < rdata->numspends ) + { + sequence = S[spendind].sequenceid; + scriptlen = S[spendind].vinscriptlen; + if ( S[spendind].scriptoffset != 0 && S[spendind].scriptoffset+scriptlen < ramchain->H.data->scriptspace ) + { + scriptdata = &Kspace[S[spendind].scriptoffset]; + altspace += scriptlen; + if ( scriptdata != 0 ) + { + memset(&V,0,sizeof(V)); + iguana_vinscriptparse(coin,&V,&sigsize,&pubkeysize,&p2shsize,&suffixlen,scriptdata,scriptlen); + p2shspace += p2shsize; + sigspace += sigsize; + pubkeyspace += pubkeysize; + sigspace += suffixlen; + // fprintf(stderr,"(%d %d %d %d).%d ",sigsize,pubkeysize,p2shsize,suffixlen,scriptlen); + } //else fprintf(stderr,"(none)" ); + } + } + } + //altspace += tx->numvins * 16 + 128; // for metascripts + //scriptspace += tx->numvins * 16 + 128; // for metascripts + //fprintf(stderr,"scriptspace.%u altspace.%u, ",scriptspace,altspace); + } + *sigspacep = sigspace, *pubkeyspacep = pubkeyspace; + //printf("altspace.%d numvouts.%d numvins.%d scriptspace.%d p2shspace.%d sigspace.%d pubkeyspace.%d\n",altspace,tx->numvouts,tx->numvins,scriptspace,p2shspace,sigspace,pubkeyspace); + return(scriptspace + p2shspace); +} + +uint32_t iguana_ramchain_scriptencode(struct iguana_info *coin,uint8_t *Kspace,uint32_t *offsetp,int32_t type,uint8_t *script,int32_t scriptlen,uint32_t *pubkeyoffsetp) +{ + uint32_t uoffset,starti,offset = *offsetp,pubkeyoffset = *pubkeyoffsetp; int32_t plen; + if ( type == IGUANA_SCRIPT_76AC || type == IGUANA_SCRIPT_AC ) + { + starti = (type == IGUANA_SCRIPT_76AC); + plen = bitcoin_pubkeylen(script + starti); + /*if ( plen <= 0 ) + { + char buf[1025]; + buf[0] = 0; + for (i=0; i<33; i++) + sprintf(buf+strlen(buf),"%02x",script[1+i]); + printf("%s pubkey -> pubkeyoffset.%d offset.%d plen.%d\n",buf,pubkeyoffset,offset,plen); + }*/ + if ( plen > 0 ) + { + if ( pubkeyoffset == 0 ) + { + if ( offset == 0 ) + offset = 1; + *pubkeyoffsetp = pubkeyoffset = offset; + memcpy(&Kspace[pubkeyoffset],script + starti,plen); + offset += plen; + *offsetp = offset; + return(0); + } + if ( memcmp(script + starti,&Kspace[pubkeyoffset],plen) != 0 ) + { + /*for (i=-1; i<=plen; i++) + printf("%02x",script[1+i]); + printf(" script arg\n"); + for (i=0; iH.scriptoffset; + if ( type != IGUANA_SCRIPT_STRANGE && type != IGUANA_SCRIPT_DATA && type != IGUANA_SCRIPT_OPRETURN && scriptlen > 0 && script != 0 ) + { + if ( Kspace != 0 && ramchain->H.scriptoffset+scriptlen+3 <= ramchain->H.data->scriptspace-ramchain->H.stacksize ) + { + if ( (u->scriptoffset= iguana_ramchain_scriptencode(coin,Kspace,&ramchain->H.scriptoffset,type,script,scriptlen,&pubkeyoffset)) > 0 || type == IGUANA_SCRIPT_76AC ) + { + fprintf(stderr,"new offset.%d from scriptlen.%d pubkeyoffset.%d\n",ramchain->H.scriptoffset,scriptlen,pubkeyoffset); + } + //printf("[%d] u%d offset.%u len.%d\n",hdrsi,unspentind,u->scriptoffset,scriptlen); + } else printf("[%d] u%d Kspace.%p scriptspace overflow! %d + %d vs space.%d - stack.%d\n",hdrsi,unspentind,Kspace,ramchain->H.scriptoffset,scriptlen,ramchain->H.data->scriptspace,ramchain->H.stacksize); + checkscript = iguana_ramchain_scriptdecode(&metalen,&checklen,Kspace,u->type,_script,u->scriptoffset,P[pkind].pubkeyoffset < ramchain->H.scriptoffset ? P[pkind].pubkeyoffset : 0); + if ( checklen != scriptlen || (script != 0 && checkscript != 0 && memcmp(checkscript,script,scriptlen) != 0) ) + { + //printf("create script mismatch len.%d vs %d or cmp error.%d\n",scriptlen,checklen,(script!=0&&checkscript!=0)?memcmp(checkscript,script,scriptlen):0); + type = IGUANA_SCRIPT_STRANGE; + } //else printf("RO spendscript match.%d\n",scriptlen); + } + if ( type == IGUANA_SCRIPT_DATA || type == IGUANA_SCRIPT_OPRETURN || type == IGUANA_SCRIPT_STRANGE ) + { + if ( script != 0 && scriptlen > 0 ) + { + u->scriptoffset = origoffset; + origoffset += iguana_rwvarint32(1,&Kspace[origoffset],(void *)&scriptlen); + memcpy(&Kspace[origoffset],script,scriptlen); + ramchain->H.scriptoffset = origoffset + scriptlen; + } + } + else if ( type == IGUANA_SCRIPT_76AC && pubkeyoffset != 0 && P[pkind].pubkeyoffset == 0 ) + P[pkind].pubkeyoffset = pubkeyoffset;*/ + +#endif diff --git a/iguana/iguana_secp.c b/iguana/iguana_secp.c new file mode 100755 index 000000000..29d563527 --- /dev/null +++ b/iguana/iguana_secp.c @@ -0,0 +1,461 @@ +/****************************************************************************** + * 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 +#include +#include +#include +#include "../includes/curve25519.h" +#include "secp256k1/include/secp256k1.h" +#include "secp256k1/include/secp256k1_recovery.h" + +//#include "../../secp256k1-zkp/include/secp256k1.h" +//#include "../../secp256k1-zkp/include/secp256k1_recovery.h" + +bits256 bitcoin_randkey(secp256k1_context *ctx) +{ + int32_t i,flag = 0; bits256 privkey; + if ( ctx == 0 ) + ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY), flag++; + if ( ctx != 0 ) + { + for (i=0; i<100; i++) + { + privkey = rand256(0); + if ( secp256k1_ec_seckey_verify(ctx,privkey.bytes) > 0 ) + { + if ( flag != 0 ) + secp256k1_context_destroy(ctx); + return(privkey); + } + } + if ( flag != 0 ) + secp256k1_context_destroy(ctx); + } + fprintf(stderr,"couldnt generate valid bitcoin privkey. something is REALLY wrong. exiting\n"); + exit(-1); +} + +bits256 bitcoin_pubkey33(secp256k1_context *ctx,uint8_t *data,bits256 privkey) +{ + int32_t flag=0; size_t plen; bits256 pubkey; secp256k1_pubkey secppub; + memset(pubkey.bytes,0,sizeof(pubkey)); + if ( ctx == 0 ) + ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY), flag++; + if ( ctx != 0 ) + { + if ( secp256k1_ec_seckey_verify(ctx,privkey.bytes) == 0 ) + { + printf("bitcoin_sign illegal privkey\n"); + return(pubkey); + } + if ( secp256k1_ec_pubkey_create(ctx,&secppub,privkey.bytes) > 0 ) + { + plen = 33; + secp256k1_ec_pubkey_serialize(ctx,data,&plen,&secppub,SECP256K1_EC_COMPRESSED); + if ( plen == 33 ) + memcpy(pubkey.bytes,data+1,sizeof(pubkey)); + } + if ( flag != 0 ) + secp256k1_context_destroy(ctx); + } + return(pubkey); +} + +int32_t bitcoin_sign(void *ctx,char *symbol,uint8_t *sig,bits256 txhash2,bits256 privkey,int32_t recoverflag) +{ + int32_t fCompressed = 1; + secp256k1_ecdsa_signature SIG; secp256k1_ecdsa_recoverable_signature rSIG; bits256 extra_entropy,seed; int32_t flag = 0,recid,retval = -1; size_t siglen = 72; secp256k1_pubkey SECPUB,CHECKPUB; + seed = rand256(0); + extra_entropy = rand256(0); + if ( ctx == 0 ) + ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY), flag++; + if ( ctx != 0 ) + { + if ( secp256k1_ec_seckey_verify(ctx,privkey.bytes) == 0 ) + { + printf("bitcoin_sign illegal privkey\n"); + return(-1); + } + if ( secp256k1_context_randomize(ctx,seed.bytes) > 0 ) + { + if ( recoverflag != 0 ) + { + if ( secp256k1_ecdsa_sign_recoverable(ctx,&rSIG,txhash2.bytes,privkey.bytes,secp256k1_nonce_function_rfc6979,extra_entropy.bytes) > 0 ) + { + recid = -1; + secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx,sig+1,&recid,&rSIG); + if ( secp256k1_ecdsa_recover(ctx,&SECPUB,&rSIG,txhash2.bytes) > 0 ) + { + if ( secp256k1_ec_pubkey_create(ctx,&CHECKPUB,privkey.bytes) > 0 ) + { + if ( memcmp(&SECPUB,&CHECKPUB,sizeof(SECPUB)) == 0 ) + { + sig[0] = 27 + recid + (fCompressed != 0 ? 4 : 0); + retval = 64 + 1; + } + else printf("secpub mismatch\n"); + } else printf("pubkey create error\n"); + } else printf("recover error\n"); + } else printf("secp256k1_ecdsa_sign_recoverable error\n"); + } + else + { + if ( secp256k1_ecdsa_sign(ctx,&SIG,txhash2.bytes,privkey.bytes,secp256k1_nonce_function_rfc6979,extra_entropy.bytes) > 0 ) + { + if ( secp256k1_ecdsa_signature_serialize_der(ctx,sig,&siglen,&SIG) > 0 ) + retval = (int32_t)siglen; + } + } + } + if ( flag != 0 ) + secp256k1_context_destroy(ctx); + } + return(retval); +} + +int32_t bitcoin_recoververify(void *ctx,char *symbol,uint8_t *sig65,bits256 messagehash2,uint8_t *pubkey) +{ + size_t plen; int32_t retval = -1,flag = 0; secp256k1_pubkey PUB; secp256k1_ecdsa_signature SIG; secp256k1_ecdsa_recoverable_signature rSIG; + pubkey[0] = 0; + if ( ctx == 0 ) + ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY), flag++; + if ( ctx != 0 ) + { + plen = (sig65[0] <= 31) ? 65 : 33; + secp256k1_ecdsa_recoverable_signature_parse_compact(ctx,&rSIG,sig65 + 1,0); + secp256k1_ecdsa_recoverable_signature_convert(ctx,&SIG,&rSIG); + if ( secp256k1_ecdsa_recover(ctx,&PUB,&rSIG,messagehash2.bytes) > 0 ) + { + secp256k1_ec_pubkey_serialize(ctx,pubkey,&plen,&PUB,plen == 65 ? SECP256K1_EC_UNCOMPRESSED : SECP256K1_EC_COMPRESSED); + if ( secp256k1_ecdsa_verify(ctx,&SIG,messagehash2.bytes,&PUB) > 0 ) + retval = 0; + else printf("secp256k1_ecdsa_verify error\n"); + } else printf("secp256k1_ecdsa_recover error\n"); + if ( flag != 0 ) + secp256k1_context_destroy(ctx); + } + return(retval); +} + +int32_t bitcoin_verify(void *ctx,uint8_t *sig,int32_t siglen,bits256 txhash2,uint8_t *pubkey,int32_t plen) +{ + int32_t flag=0,retval = -1; secp256k1_pubkey PUB; secp256k1_ecdsa_signature SIG; + if ( ctx == 0 ) + ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY), flag++; + if ( ctx != 0 ) + { + if ( secp256k1_ec_pubkey_parse(ctx,&PUB,pubkey,plen) > 0 ) + { + secp256k1_ecdsa_signature_parse_der(ctx,&SIG,sig,siglen); + if ( secp256k1_ecdsa_verify(ctx,&SIG,txhash2.bytes,&PUB) > 0 ) + retval = 0; + } + if ( flag != 0 ) + secp256k1_context_destroy(ctx); + } + return(retval); +} + +#ifdef oldway +#include "../includes/openssl/ec.h" +#include "../includes/openssl/ecdsa.h" +#include "../includes/openssl/obj_mac.h" + +static const char base58_chars[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; + +struct bp_key { EC_KEY *k; }; + +EC_KEY *oldbitcoin_privkeyset(uint8_t *oddevenp,bits256 *pubkeyp,bits256 privkey) +{ + BIGNUM *bn; BN_CTX *ctx = NULL; uint8_t *ptr,tmp[33]; EC_POINT *pub_key = NULL; const EC_GROUP *group; + EC_KEY *KEY = EC_KEY_new_by_curve_name(NID_secp256k1); + *oddevenp = 0; + EC_KEY_set_conv_form(KEY,POINT_CONVERSION_COMPRESSED); + { + if ( (group= EC_KEY_get0_group(KEY)) != 0 && (ctx= BN_CTX_new()) != 0 ) + { + if ( (pub_key= EC_POINT_new(group)) != 0 ) + { + if ( (bn= BN_bin2bn(privkey.bytes,sizeof(privkey),BN_new())) != 0 ) + { + if ( EC_POINT_mul(group,pub_key,bn,NULL,NULL,ctx) > 0 ) + { + EC_KEY_set_private_key(KEY,bn); + EC_KEY_set_public_key(KEY,pub_key); + ptr = tmp; + i2o_ECPublicKey(KEY,&ptr); + *oddevenp = tmp[0]; + memcpy(pubkeyp->bytes,&tmp[1],sizeof(*pubkeyp)); + } + BN_clear_free(bn); + } + EC_POINT_free(pub_key); + } + BN_CTX_free(ctx); + } + } + return(KEY); +} + +int32_t oldbitcoin_verify(uint8_t *sig,int32_t siglen,uint8_t *data,int32_t datalen,uint8_t *pubkey,int32_t len) +{ + ECDSA_SIG *esig; int32_t retval = -1; uint8_t tmp[33],*ptr,*sigptr = sig; EC_KEY *KEY = 0; + if ( len < 0 ) + return(-1); + if ( (esig= ECDSA_SIG_new()) != 0 ) + { + if ( d2i_ECDSA_SIG(&esig,(const uint8_t **)&sigptr,siglen) != 0 ) + { + if ( (KEY= EC_KEY_new_by_curve_name(NID_secp256k1)) != 0 ) + { + EC_KEY_set_conv_form(KEY,POINT_CONVERSION_COMPRESSED); + if ( len == 32 ) + { + memcpy(tmp+1,pubkey,len); + for (tmp[0]=2; tmp[0]<=3; tmp[0]++) + { + ptr = tmp; + o2i_ECPublicKey(&KEY,(const uint8_t **)&ptr,33); + if ( ECDSA_do_verify(data,datalen,esig,KEY) > 0 ) + { + retval = 0; + break; + } + } + } + else + { + ptr = pubkey; + o2i_ECPublicKey(&KEY,(const uint8_t **)&ptr,len); + if ( ECDSA_do_verify(data,datalen,esig,KEY) > 0 ) + retval = 0; + } + EC_KEY_free(KEY); + } + } + ECDSA_SIG_free(esig); + } + return(retval); +} + +int32_t oldbitcoin_sign(uint8_t *sig,int32_t maxlen,uint8_t *data,int32_t datalen,bits256 privkey) +{ + EC_KEY *KEY; uint8_t oddeven; bits256 pubkey; uint8_t *ptr; int32_t siglen,retval = -1; + ECDSA_SIG *SIG; BN_CTX *ctx; const EC_GROUP *group; BIGNUM *order,*halforder; + if ( (KEY= oldbitcoin_privkeyset(&oddeven,&pubkey,privkey)) != 0 ) + { + if ( (SIG= ECDSA_do_sign(data,datalen,KEY)) != 0 ) + { + ctx = BN_CTX_new(); + BN_CTX_start(ctx); + group = EC_KEY_get0_group(KEY); + order = BN_CTX_get(ctx); + halforder = BN_CTX_get(ctx); + EC_GROUP_get_order(group,order,ctx); + BN_rshift1(halforder,order); + if ( BN_cmp(SIG->s,halforder) > 0 ) + { + // enforce low S values, by negating the value (modulo the order) if above order/2. + BN_sub(SIG->s,order,SIG->s); + } + ptr = 0; + siglen = i2d_ECDSA_SIG(SIG,&ptr); + if ( ptr != 0 ) + { + if ( siglen > 0 ) + { + memcpy(sig,ptr,siglen); + retval = siglen; + } + free(ptr); + } + BN_CTX_end(ctx); + BN_CTX_free(ctx); + ECDSA_SIG_free(SIG); + } + //if ( ECDSA_sign(0,data,datalen,sig,&siglen,KEY) > 0 && siglen <= maxlen ) + // retval = siglen; + EC_KEY_free(KEY); + } + return(retval); +} + +bits256 oldbitcoin_pubkey33(void *_ctx,uint8_t *data,bits256 privkey) +{ + uint8_t oddeven,data2[65]; size_t plen; bits256 pubkey; secp256k1_pubkey secppub; secp256k1_context *ctx; + EC_KEY *KEY; + if ( (KEY= oldbitcoin_privkeyset(&oddeven,&pubkey,privkey)) != 0 ) + { + data[0] = oddeven; + memcpy(data+1,pubkey.bytes,sizeof(pubkey)); + EC_KEY_free(KEY); + if ( (ctx= secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY)) != 0 ) + { + if ( secp256k1_ec_pubkey_create(ctx,&secppub,privkey.bytes) > 0 ) + { + secp256k1_ec_pubkey_serialize(ctx,data2,&plen,&secppub,1); + if ( memcmp(data2,data,plen) != 0 ) + printf("pubkey compare error plen.%d\n",(int32_t)plen); + else printf("pubkey verified\n"); + } //else printf("error secp256k1_ec_pubkey_create\n"); + secp256k1_context_destroy(ctx); + } + } else memset(pubkey.bytes,0,sizeof(pubkey)); + return(pubkey); +} + +void bn_mpi2bn(BIGNUM *vo,uint8_t *data,int32_t datalen) +{ + uint8_t vch2[64 + 4]; uint32_t i,vch2_len = (int32_t)datalen + 4; + if ( datalen < sizeof(vch2) ) + { + vch2[0] = (datalen >> 24) & 0xff; + vch2[1] = (datalen >> 16) & 0xff; + vch2[2] = (datalen >> 8) & 0xff; + vch2[3] = (datalen >> 0) & 0xff; + for (i=0; i= 4 && sz < sizeof(s_be) ) // get MPI format size + { + BN_bn2mpi(v,s_be); + // copy-swap MPI to little endian, sans 32-bit size prefix + sz -= 4; + for (i=0; i= 2 && revdata[len - 1] == 0 && revdata[len - 2] >= 0x80 ) + len--; + zeroes = 0; + for (p=coinaddr; *p==base58_chars[0]; p++) + zeroes++; + be_sz = (uint32_t)len + (uint32_t)zeroes; + memset(data,0,be_sz); + for (i=0; i> 1) ) + { + ctx = BN_CTX_new(); + BN_init(&bn58), BN_init(&bn0), BN_init(&bn), BN_init(&dv), BN_init(&rem); + BN_set_word(&bn58,58); + BN_set_word(&bn0,0); + for (i=0; i 0 ) + { + if ( BN_div(&dv,&rem,&bn,&bn58,ctx) == 0 ) + { + flag = -1; + break; + } + BN_copy(&bn,&dv); + rs[n++] = base58_chars[BN_get_word(&rem)]; + } + if ( flag == 0 ) + { + for (i=0; iprev_hash),msg->prev_hash.bytes); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->prev_vout),&msg->prev_vout); + if ( rwflag == 1 ) + tmp = msg->scriptlen; + len += iguana_rwvarint32(rwflag,&serialized[len],&tmp); + if ( rwflag == 0 ) + msg->scriptlen = tmp; + if ( msg->scriptlen > IGUANA_MAXSCRIPTSIZE ) + { + printf("iguana_vinparse illegal scriptlen.%d\n",msg->scriptlen); + return(-1); + } + if ( rwflag == 0 ) + { + msg->vinscript = &serialized[len]; + len += msg->scriptlen; + } + else if ( msg->vinscript != 0 && msg->scriptlen > 0 ) + { + memcpy(&serialized[len],msg->vinscript,msg->scriptlen), len += msg->scriptlen; // pubkeys here + if ( (p2shlen= msg->p2shlen) > 0 && msg->redeemscript != 0 ) + { + if ( p2shlen > msg->suffixlen ) + { + p2shlen -= msg->suffixlen; + if ( p2shlen < 76 ) + serialized[len++] = p2shlen; + else if ( p2shlen <= 0xff ) + { + serialized[len++] = 0x4c; + serialized[len++] = p2shlen; + } + else if ( p2shlen <= 0xffff ) + { + serialized[len++] = 0x4d; + serialized[len++] = (p2shlen & 0xff); + serialized[len++] = ((p2shlen >> 8) & 0xff); + } else return(-1); + memcpy(&serialized[len],msg->redeemscript,p2shlen), len += p2shlen; + } + if ( msg->suffixlen > 0 ) + memcpy(&serialized[len],&msg->redeemscript[msg->scriptlen - msg->suffixlen],msg->suffixlen), len += msg->suffixlen; + } + } + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->sequence),&msg->sequence); + if ( 0 ) + { + int32_t i; char str[65]; + for (i=0; iscriptlen; i++) + printf("%02x",msg->vinscript[i]); + printf(" prev_hash.(%s) vout.%d [%p] scriptlen.%d rwflag.%d\n",bits256_str(str,msg->prev_hash),msg->prev_vout,msg->vinscript,msg->scriptlen,rwflag); + } + return(len); +} + +int32_t iguana_voutparse(int32_t rwflag,uint8_t *serialized,struct iguana_msgvout *msg) +{ + int32_t len = 0; + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->value),&msg->value); + len += iguana_rwvarint32(rwflag,&serialized[len],&msg->pk_scriptlen); + if ( msg->pk_scriptlen > IGUANA_MAXSCRIPTSIZE ) + { + printf("iguana_voutparse illegal scriptlen.%d\n",msg->pk_scriptlen); + return(-1); + } + if ( rwflag == 0 ) + msg->pk_script = &serialized[len]; + else memcpy(&serialized[len],msg->pk_script,msg->pk_scriptlen); + if ( 0 ) + { + int32_t i; + for (i=0; ipk_scriptlen; i++) + printf("%02x",msg->pk_script[i]); + printf(" [%p] scriptlen.%d rwflag.%d %.8f\n",msg->pk_script,msg->pk_scriptlen,rwflag,dstr(msg->value)); + } + len += msg->pk_scriptlen; + return(len); +} + +cJSON *iguana_vinjson(struct iguana_info *coin,struct iguana_msgvin *vin) +{ + char str[65]; int32_t vout; cJSON *json = cJSON_CreateObject(); + vout = vin->prev_vout; + jaddnum(json,"sequence",vin->sequence); + if ( vout < 0 && bits256_nonz(vin->prev_hash) == 0 ) + iguana_addscript(coin,json,vin->vinscript,vin->scriptlen,"coinbase"); + else + { + jaddstr(json,"txid",bits256_str(str,vin->prev_hash)); + jaddnum(json,"vout",vout); + if ( vin->scriptlen > 0 ) + iguana_addscript(coin,json,vin->vinscript,vin->scriptlen,"scriptSig"); + if ( vin->spendlen > 0 ) + iguana_addscript(coin,json,vin->spendscript,vin->spendlen,"scriptPubKey"); + if ( vin->p2shlen > 0 ) + iguana_addscript(coin,json,vin->redeemscript,vin->p2shlen,"redeemScript"); + } + return(json); +} + +int32_t iguana_parsevinobj(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_msgvin *vin,cJSON *vinobj,struct vin_info *V) +{ + struct iguana_waddress *waddr; struct iguana_waccount *wacct; int32_t i,n,plen,len = 0; char *suffixstr,*pubkeystr,*hexstr = 0,*redeemstr = 0,*spendstr = 0; cJSON *scriptjson = 0,*obj,*pubkeysjson = 0; + //printf("PARSEVIN.(%s)\n",jprint(vinobj,0)); + if ( V == 0 ) + memset(vin,0,sizeof(*vin)); + vin->prev_vout = -1; + if ( jobj(vinobj,"sequence") != 0 ) + vin->sequence = juint(vinobj,"sequence"); + else vin->sequence = 0xffffffff; + if ( (hexstr= jstr(vinobj,"coinbase")) == 0 ) + { + vin->prev_hash = jbits256(vinobj,"txid"); + vin->prev_vout = jint(vinobj,"vout"); + if ( (scriptjson= jobj(vinobj,"scriptSig")) != 0 ) + hexstr = jstr(scriptjson,"hex"); + if ( ((spendstr= jstr(vinobj,"scriptPub")) == 0 && (spendstr= jstr(vinobj,"scriptPubkey")) == 0) || is_hexstr(spendstr,(int32_t)strlen(spendstr)) <= 0 ) + { + if ( (obj= jobj(vinobj,"scriptPub")) != 0 || (obj= jobj(vinobj,"scriptPubkey")) != 0 ) + spendstr = jstr(obj,"hex"); + } + if ( (redeemstr= jstr(vinobj,"redeemScript")) == 0 || is_hexstr(redeemstr,(int32_t)strlen(redeemstr)) <= 0 ) + { + if ( (obj= jobj(vinobj,"redeemScript")) != 0 ) + redeemstr = jstr(obj,"hex"); + } + } + if ( hexstr != 0 ) + { + n = (int32_t)strlen(hexstr) >> 1; + decode_hex(serialized,n,hexstr); + vin->vinscript = serialized; + vin->scriptlen = n; + } //else printf("iguana_parsevinobj: hex script missing (%s)\n",jprint(vinobj,0)); + if ( V != 0 ) + { + if ( vin->vinscript == 0 ) + { + if ( (V->unspentind= iguana_unspentindfind(coin,V->coinaddr,V->spendscript,&V->spendlen,&V->amount,&V->height,vin->prev_hash,vin->prev_vout,coin->bundlescount-1)) > 0 ) + { + if ( V->coinaddr[0] != 0 && (waddr= iguana_waddresssearch(myinfo,coin,&wacct,V->coinaddr)) != 0 ) + { + memcpy(V->signers[0].pubkey,waddr->pubkey,bitcoin_pubkeylen(waddr->pubkey)); + } + printf("V %.8f (%s) spendscript.[%d]\n",dstr(V->amount),V->coinaddr,V->spendlen); + } + } + if ( (pubkeysjson= jarray(&n,vinobj,"pubkeys")) != 0 ) + { + if ( vin->vinscript == 0 ) + { + vin->vinscript = serialized; + vin->vinscript[0] = 0; + vin->scriptlen = 1; + } + for (i=0; i> 1) > 0 ) + { + vin->vinscript[vin->scriptlen++] = plen; + decode_hex(&vin->vinscript[vin->scriptlen],plen,pubkeystr); + memcpy(V->signers[i].pubkey,&vin->vinscript[vin->scriptlen],plen); + vin->scriptlen += plen; + } + } + } + if ( vin->vinscript != 0 ) + serialized = &vin->vinscript[vin->scriptlen]; + len = vin->scriptlen; + if ( redeemstr != 0 ) + { + n = (int32_t)strlen(redeemstr) >> 1; + decode_hex(serialized,n,redeemstr); + vin->redeemscript = serialized; + V->p2shlen = vin->p2shlen = n; + memcpy(V->p2shscript,serialized,n); + } + if ( (suffixstr= jstr(vinobj,"suffix")) != 0 && is_hexstr(suffixstr,(int32_t)strlen(suffixstr)) > 0 ) + { + if ( vin->redeemscript == 0 ) + { + vin->redeemscript = serialized; + vin->redeemscript[0] = 0; + } + n = (int32_t)strlen(suffixstr) >> 1; + decode_hex(&vin->redeemscript[vin->p2shlen],n,suffixstr); + vin->p2shlen += n; + } + len += vin->p2shlen; + serialized = vin->redeemscript != 0 ? &vin->redeemscript[vin->p2shlen] : &serialized[len]; + if ( spendstr != 0 ) + { + n = (int32_t)strlen(spendstr) >> 1; + decode_hex(serialized,n,spendstr); + vin->spendscript = serialized; + vin->spendlen = n; + } + len += vin->spendlen; + } + return(len); +} + +int32_t iguana_parsevoutobj(struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_msgvout *vout,cJSON *voutobj) +{ + int32_t len = 0; cJSON *skey; char *hexstr; + memset(vout,0,sizeof(*vout)); + if ( jobj(voutobj,"satoshis") != 0 ) + vout->value = j64bits(voutobj,"satoshis"); + else vout->value = jdouble(voutobj,"value") * SATOSHIDEN; + if ( (skey= jobj(voutobj,"scriptPubKey")) != 0 ) + { + if ( (hexstr= jstr(skey,"hex")) != 0 ) + { + len = (int32_t)strlen(hexstr) >> 1; + decode_hex(serialized,len,hexstr); + vout->pk_script = serialized; + vout->pk_scriptlen = len; + } + } + return(len); +} + +cJSON *iguana_voutjson(struct iguana_info *coin,struct iguana_msgvout *vout,int32_t txi,bits256 txid) +{ + // 035f1321ed17d387e4433b2fa229c53616057964af065f98bfcae2233c5108055e OP_CHECKSIG + char scriptstr[IGUANA_MAXSCRIPTSIZE+1],asmstr[2*IGUANA_MAXSCRIPTSIZE+1]; int32_t i,m,n,scriptlen,asmtype; struct vin_info *vp; + uint8_t space[8192]; cJSON *addrs,*skey,*json = cJSON_CreateObject(); + vp = calloc(1,sizeof(*vp)); + jadd64bits(json,"satoshis",vout->value); + jaddnum(json,"n",txi); + //"scriptPubKey":{"asm":"OP_DUP OP_HASH160 5f69cb73016264270dae9f65c51f60d0e4d6fd44 OP_EQUALVERIFY OP_CHECKSIG","reqSigs":1,"type":"pubkeyhash","addresses":["RHyh1V9syARTf2pyxibz7v27D5paBeWza5"]} + if ( vout->pk_script != 0 && vout->pk_scriptlen*2+1 < sizeof(scriptstr) ) + { + memset(vp,0,sizeof(*vp)); + if ( (asmtype= iguana_calcrmd160(coin,asmstr,vp,vout->pk_script,vout->pk_scriptlen,txid,txi,0xffffffff)) >= 0 ) + { + skey = cJSON_CreateObject(); + scriptlen = iguana_scriptgen(coin,&m,&n,vp->coinaddr,space,asmstr,vp->rmd160,asmtype,vp,txi); + if ( asmstr[0] != 0 ) + jaddstr(skey,"asm",asmstr); + addrs = cJSON_CreateArray(); + if ( vp->N == 1 ) + { + if ( asmtype == 2 ) + { + jaddnum(skey,"reqSigs",1); + jaddstr(skey,"type","pubkeyhash"); + } + if ( vp->coinaddr[0] != 0 ) + jaddistr(addrs,vp->coinaddr); + } + else + { + jaddnum(skey,"reqSigs",vp->M); + for (i=0; iN; i++) + { + //btc_convrmd160(coinaddr,coin->chain->pubtype,V.signers[i].pubkey); + jaddistr(addrs,vp->signers[i].coinaddr); + } + } + jadd(skey,"addresses",addrs); + init_hexbytes_noT(scriptstr,vout->pk_script,vout->pk_scriptlen); + if ( scriptstr[0] != 0 ) + jaddstr(skey,"hex",scriptstr); + jadd(json,"scriptPubKey",skey); + } + } + return(json); +} + +int32_t iguana_rwmsgtx(struct iguana_info *coin,int32_t rwflag,cJSON *json,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,bits256 *txidp,char *vpnstr) +{ + int32_t i,n,len = 0; uint8_t *txstart = serialized; char txidstr[65]; cJSON *array=0; + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->version),&msg->version); + if ( json != 0 ) + { + jaddnum(json,"version",msg->version); + array = cJSON_CreateArray(); + } + //printf("version.%d\n",msg->version); + if ( coin->chain->hastimestamp != 0 ) + { + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->timestamp),&msg->timestamp); + //char str[65]; printf("version.%d timestamp.%08x %u %s\n",msg->version,msg->timestamp,msg->timestamp,utc_str(str,msg->timestamp)); + if ( json != 0 ) + jaddnum(json,"timestamp",msg->timestamp); + } + //for (i=len; itx_in); + //printf(" tx_in.%08x\n",msg->tx_in); + if ( rwflag == 0 ) + { + if ( len + sizeof(struct iguana_msgvin)*msg->tx_in > maxsize ) + { + printf("len.%d + tx_in.%d > maxsize.%d\n",len,msg->tx_in,maxsize); + return(-1); + } + maxsize -= (sizeof(struct iguana_msgvin) * msg->tx_in); + msg->vins = (struct iguana_msgvin *)&serialized[maxsize]; + memset(msg->vins,0,sizeof(struct iguana_msgvin) * msg->tx_in); + } + for (i=0; itx_in; i++) + { + if ( (n= iguana_vinparse(coin,rwflag,&serialized[len],&msg->vins[i])) < 0 ) + return(-1); + //printf("vin.%d n.%d len.%d\n",i,n,len); + len += n; + if ( len > maxsize ) + { + printf("invalid tx_in.%d len.%d vs maxsize.%d\n",msg->tx_in,len,maxsize); + return(-1); + } + if ( array != 0 ) + jaddi(array,iguana_vinjson(coin,&msg->vins[i])); + } + if ( array != 0 ) + { + jadd(json,"vin",array); + jaddnum(json,"numvins",msg->tx_in); + array = cJSON_CreateArray(); + } + //for (i=len; itx_out); + //printf(" txout.%d\n",msg->tx_out); + if ( rwflag == 0 ) + { + if ( len + sizeof(struct iguana_msgvout)*msg->tx_out > maxsize ) + { + printf("len.%d + tx_in.%d > maxsize.%d\n",len,msg->tx_in,maxsize); + return(-1); + } + maxsize -= (sizeof(struct iguana_msgvout) * msg->tx_out); + msg->vouts = (struct iguana_msgvout *)&serialized[maxsize]; + memset(msg->vouts,0,sizeof(struct iguana_msgvout) * msg->tx_out); + } + for (i=0; itx_out; i++) + { + if ( (n= iguana_voutparse(rwflag,&serialized[len],&msg->vouts[i])) < 0 ) + return(-1); + len += n; + if ( len > maxsize ) + { + printf("invalid tx_out.%d len.%d vs maxsize.%d\n",msg->tx_out,len,maxsize); + return(-1); + } + if ( array != 0 ) + jaddi(array,iguana_voutjson(coin,&msg->vouts[i],i,*txidp)); + } + if ( array != 0 ) + { + jadd(json,"vout",array); + jaddnum(json,"numvouts",msg->tx_out); + } + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->lock_time),&msg->lock_time); + //printf("lock_time.%08x\n",msg->lock_time); + if ( strcmp(coin->symbol,"VPN") == 0 ) + { + uint16_t ddosflag = 0; + len += iguana_rwnum(rwflag,&serialized[len],sizeof(ddosflag),&ddosflag); + for (i=0; serialized[len]!=0&&lenlock_time); + jaddnum(json,"size",len); + jaddbits256(json,"txid",*txidp); + //printf("TX.(%s) %p\n",jprint(json,0),json); + } + msg->allocsize = len; + return(len); +} + +bits256 iguana_parsetxobj(struct supernet_info *myinfo,struct iguana_info *coin,int32_t *txstartp,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,cJSON *txobj,struct vin_info *V) // json -> serialized + (msg,V) +{ + int32_t i,numvins,numvouts,len = 0; cJSON *array=0; bits256 txid; char vpnstr[64]; + memset(&txid,0,sizeof(txid)); + if ( txobj == 0 ) + return(txid); + memset(msg,0,sizeof(*msg)); + vpnstr[0] = 0; + if ( (msg->version= juint(txobj,"version")) == 0 ) + msg->version = 1; + if ( coin->chain->hastimestamp != 0 ) + { + if ( (msg->timestamp= juint(txobj,"timestamp")) == 0 ) + msg->timestamp = (uint32_t)time(NULL); + } + if ( (array= jarray(&numvins,txobj,"vin")) != 0 ) + { + msg->tx_in = numvins; + if ( len + sizeof(struct iguana_msgvin)*msg->tx_in > maxsize ) + return(msg->txid); + maxsize -= (sizeof(struct iguana_msgvin) * msg->tx_in); + msg->vins = (struct iguana_msgvin *)&serialized[maxsize]; + if ( msg->tx_in > 0 && msg->tx_in*sizeof(struct iguana_msgvin) < maxsize ) + { + for (i=0; itx_in; i++) + len += iguana_parsevinobj(myinfo,coin,&serialized[len],maxsize,&msg->vins[i],jitem(array,i),V!=0?&V[i]:0); + } + } + if ( (array= jarray(&numvouts,txobj,"vout")) != 0 ) + { + msg->tx_out = numvouts; + if ( len + sizeof(struct iguana_msgvout)*msg->tx_out > maxsize ) + return(msg->txid); + maxsize -= (sizeof(struct iguana_msgvout) * msg->tx_out); + msg->vouts = (struct iguana_msgvout *)&serialized[maxsize]; + if ( msg->tx_out > 0 && msg->tx_out*sizeof(struct iguana_msgvout) < maxsize ) + { + for (i=0; itx_out; i++) + len += iguana_parsevoutobj(coin,&serialized[len],maxsize,&msg->vouts[i],jitem(array,i)); + } + } + msg->lock_time = (int32_t)j64bits(txobj,"locktime"); + msg->txid = jbits256(txobj,"txid"); + *txstartp = len; + if ( (msg->allocsize= iguana_rwmsgtx(coin,1,0,&serialized[len],maxsize-len,msg,&txid,vpnstr)) < 0 ) + { + memset(txid.bytes,0,sizeof(txid)); + printf("error parsing txobj\n"); + msg->allocsize = 0; + } + //char str[65]; printf("json -> %s\n",bits256_str(str,txid)); + return(txid); +} + +char *iguana_rawtxbytes(struct iguana_info *coin,cJSON *json,struct iguana_msgtx *msgtx) +{ + int32_t n; char *txbytes = 0,vpnstr[64]; uint8_t *serialized; + serialized = malloc(IGUANA_MAXPACKETSIZE); + vpnstr[0] = 0; + //char str[65]; printf("%d of %d: %s\n",i,msg.txn_count,bits256_str(str,tx.txid)); + if ( (n= iguana_rwmsgtx(coin,1,json,serialized,IGUANA_MAXPACKETSIZE,msgtx,&msgtx->txid,vpnstr)) > 0 ) + { + txbytes = malloc(n*2+1); + init_hexbytes_noT(txbytes,serialized,n); + } + free(serialized); + return(txbytes); +} + +char *bitcoin_json2hex(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,cJSON *txjson,struct vin_info *V) +{ + int32_t txstart; uint8_t *serialized; struct iguana_msgtx msgtx; char *txbytes = 0; + if ( txjson == 0 ) + { + memset(txidp,0,sizeof(*txidp)); + return(0); + } + serialized = malloc(IGUANA_MAXPACKETSIZE*1.5); + *txidp = iguana_parsetxobj(myinfo,coin,&txstart,serialized,IGUANA_MAXPACKETSIZE*1.5,&msgtx,txjson,V); + if ( msgtx.allocsize > 0 ) + { + txbytes = malloc(msgtx.allocsize*2 + 1); + init_hexbytes_noT(txbytes,&serialized[txstart],msgtx.allocsize); + } else printf("bitcoin_txtest: zero msgtx allocsize.(%s)\n",jprint(txjson,0)); + free(serialized); + return(txbytes); +} + +cJSON *bitcoin_hex2json(struct iguana_info *coin,bits256 *txidp,struct iguana_msgtx *msgtx,char *txbytes) +{ + int32_t n,len; char vpnstr[64]; struct iguana_msgtx M; uint8_t *serialized; cJSON *txobj; + txobj = cJSON_CreateObject(); + if ( msgtx == 0 ) + { + msgtx = &M; + memset(msgtx,0,sizeof(M)); + } + len = (int32_t)strlen(txbytes) >> 1; + serialized = malloc(len + 32768); + decode_hex(serialized,len,txbytes); + vpnstr[0] = 0; + memset(txidp,0,sizeof(*txidp)); + if ( (n= iguana_rwmsgtx(coin,0,txobj,serialized,len + 32768,msgtx,txidp,vpnstr)) <= 0 ) + { + printf("error from rwmsgtx\n"); + free_json(txobj); + txobj = 0; + } + free(serialized); + return(txobj); +} + +bits256 bitcoin_sigtxid(struct iguana_info *coin,uint8_t *serialized,int32_t maxlen,struct iguana_msgtx *msgtx,int32_t vini,uint8_t *spendscript,int32_t spendlen,int32_t hashtype,char *vpnstr) +{ + int32_t i,len; bits256 sigtxid,txid,revsigtxid; struct iguana_msgtx dest; + dest = *msgtx; + memset(sigtxid.bytes,0,sizeof(sigtxid)); + if ( hashtype != SIGHASH_ALL ) + { + printf("currently only SIGHASH_ALL supported, not %d\n",hashtype); + return(sigtxid); + } + for (i=0; itx_in; i++) + { + if ( i == vini ) + { + dest.vins[i].vinscript = spendscript; + dest.vins[i].scriptlen = spendlen; + } + else + { + dest.vins[i].vinscript = (uint8_t *)""; + dest.vins[i].scriptlen = 0; + } + dest.vins[i].p2shlen = 0; + dest.vins[i].redeemscript = 0; + } + len = iguana_rwmsgtx(coin,1,0,serialized,maxlen,&dest,&txid,vpnstr); + if ( len > 0 ) + { + len += iguana_rwnum(1,&serialized[len],sizeof(hashtype),&hashtype); + revsigtxid = bits256_doublesha256(0,serialized,len); + for (i=0; itx_in; vini++) + { + vp = &V[vini]; + msgtx->vins[vini].vinscript = script = &serialized[len]; + msgtx->vins[vini].vinscript[0] = 0; + scriptlen = 0; + for (j=0; jN; j++) + { + if ( (siglen= vp->signers[j].siglen) > 0 ) + { + script[scriptlen++] = siglen; + memcpy(&script[scriptlen],vp->signers[j].sig,siglen); + scriptlen += siglen; + } + } + if ( vp->N > 1 || bitcoin_pubkeylen(&vp->spendscript[1]) != vp->spendscript[0] || vp->spendscript[vp->spendlen-1] != 0xac ) + { + for (j=0; jN; j++) + { + if ( (plen= bitcoin_pubkeylen(vp->signers[j].pubkey)) > 0 ) + { + script[scriptlen++] = plen; + memcpy(&script[scriptlen],vp->signers[j].pubkey,plen); + scriptlen += plen; + } + } + } + msgtx->vins[vini].scriptlen = scriptlen; + if ( (p2shlen= vp->p2shlen) > 0 ) + { + msgtx->vins[vini].redeemscript = &script[scriptlen]; + if ( p2shlen < 76 ) + script[scriptlen++] = p2shlen; + else if ( p2shlen <= 0xff ) + { + script[scriptlen++] = 0x4c; + script[scriptlen++] = p2shlen; + } + else if ( p2shlen <= 0xffff ) + { + script[scriptlen++] = 0x4d; + script[scriptlen++] = (p2shlen & 0xff); + script[scriptlen++] = ((p2shlen >> 8) & 0xff); + } else return(-1); + memcpy(&script[scriptlen],vp->p2shscript,p2shlen), scriptlen += p2shlen; + if ( (msgtx->vins[vini].suffixlen= vp->suffixlen) > 0 ) + { + memcpy(&script[scriptlen],&vp->p2shscript[vp->p2shlen - vp->suffixlen],vp->suffixlen); + scriptlen += vp->suffixlen; + } + } + len += scriptlen; + } + return(len); +} + +int32_t bitcoin_verifyvins(struct iguana_info *coin,bits256 *signedtxidp,char **signedtx,struct iguana_msgtx *msgtx,uint8_t *serialized,int32_t maxlen,struct vin_info *V,int32_t sighash) +{ + bits256 sigtxid; uint8_t *sig; struct vin_info *vp; char vpnstr[64]; int32_t complete=0,plen,j,vini=0,flag=0,siglen,numvouts,numsigs; + numvouts = msgtx->tx_out; + vpnstr[0] = 0; + *signedtx = 0; + memset(signedtxidp,0,sizeof(*signedtxidp)); + for (vini=0; vinitx_in; vini++) + { + sigtxid = bitcoin_sigtxid(coin,serialized,maxlen,msgtx,vini,msgtx->vins[vini].spendscript,msgtx->vins[vini].spendlen,sighash,vpnstr); + if ( bits256_nonz(sigtxid) != 0 ) + { + vp = &V[vini]; + vp->sigtxid = sigtxid; + for (j=numsigs=0; jN; j++) + { + sig = vp->signers[j].sig; + siglen = vp->signers[j].siglen; + if ( bits256_nonz(vp->signers[j].privkey) != 0 ) + { + siglen = bitcoin_sign(coin->ctx,coin->symbol,sig,sigtxid,vp->signers[j].privkey,0); + if ( (plen= bitcoin_pubkeylen(vp->signers[j].pubkey)) <= 0 ) + bitcoin_pubkey33(coin->ctx,vp->signers[j].pubkey,vp->signers[j].privkey); + sig[siglen++] = sighash; + vp->signers[j].siglen = siglen; + /*for (i=0; isigners[j].pubkey[i]);*/ + // s2 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1; + char str[65]; printf(" SIGNEDTX.[%02x] siglen.%d sigtxid.%s\n",sig[siglen-1],siglen,bits256_str(str,sigtxid)); + } + if ( sig == 0 || siglen == 0 ) + { + memset(vp->signers[j].pubkey,0,sizeof(vp->signers[j].pubkey)); + continue; + } + if ( bitcoin_verify(coin->ctx,sig,siglen-1,sigtxid,vp->signers[j].pubkey,bitcoin_pubkeylen(vp->signers[j].pubkey)) < 0 ) + { + + printf("SIG.%d.%d ERROR\n",vini,j); + } + else + { + printf("SIG.%d.%d VERIFIED \n",vini,j);//%s (%s)\n",vini,*signedtx,jprint(txobj,1)); + flag++; + numsigs++; + } + } + if ( numsigs >= vp->M ) + complete = 1; + } + } + iguana_msgtx_Vset(coin,serialized,maxlen,msgtx,V); + cJSON *txobj = cJSON_CreateObject(); + *signedtx = iguana_rawtxbytes(coin,txobj,msgtx); + //printf("SIGNEDTX.(%s)\n",jprint(txobj,1)); + *signedtxidp = msgtx->txid; + return(complete); +} + +int32_t bitcoin_verifytx(struct iguana_info *coin,bits256 *signedtxidp,char **signedtx,char *rawtxstr,struct vin_info *V,int32_t numinputs) +{ + int32_t len,maxsize,retval = -1; uint8_t *serialized,*serialized2; + struct iguana_msgtx msgtx; bits256 txid; char vpnstr[64]; + len = (int32_t)strlen(rawtxstr); + maxsize = len + 32768; + serialized = calloc(1,maxsize), serialized2 = calloc(1,maxsize); + len >>= 1; + vpnstr[0] = 0; + decode_hex(serialized,len,rawtxstr); + memset(&msgtx,0,sizeof(msgtx)); + if ( iguana_rwmsgtx(coin,0,0,serialized,maxsize,&msgtx,&txid,vpnstr) > 0 && numinputs == msgtx.tx_in ) + { + if ( bitcoin_verifyvins(coin,signedtxidp,signedtx,&msgtx,serialized2,maxsize,V,SIGHASH_ALL) == 0 ) + retval = 0; + else printf("bitcoin_verifytx: bitcoin_verifyvins error\n"); + } else printf("bitcoin_verifytx: error iguana_rwmsgtx\n"); + free(serialized), free(serialized2); + return(retval); +} + +cJSON *iguana_signtx(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,char **signedtxp,struct bitcoin_spend *spend,cJSON *txobj,cJSON *vins) +{ + int32_t i,j,m,n,plen; char *rawtxstr,*pubkeystr,*spendstr; struct vin_info *V,*vp; bits256 txid; struct iguana_waccount *wacct; struct iguana_waddress *waddr; cJSON *vitem,*vinsobj,*pubkeys; + V = calloc(spend->numinputs,sizeof(*V)); + if ( *signedtxp != 0 ) + { + if ( txobj != 0 ) + free_json(txobj); + txobj = bitcoin_hex2json(coin,&txid,0,*signedtxp); + if ( vins != 0 ) + { + if ( jobj(txobj,"vin") != 0 ) + jdelete(txobj,"vin"); + jadd(txobj,"vin",iguana_createvins(myinfo,coin,txobj,vins)); + } + //printf("bitcoin_hex2json (%s)\n",jprint(txobj,0)); + free(*signedtxp); + } + vinsobj = jarray(&n,txobj,"vin"); + for (i=0; inuminputs; i++) // N times less efficient, but for small number of inputs ok + { + vp = &V[i]; + if ( i < n ) + { + if ( (vitem= jitem(vinsobj,i)) != 0 && ((spendstr= jstr(vitem,"scriptPub")) != 0 || (spendstr= jstr(vitem,"scriptPubKey")) != 0) ) + { + vp->spendlen = (int32_t)strlen(spendstr) >> 1; + decode_hex(vp->spendscript,vp->spendlen,spendstr); + } else spendstr = 0; + } + else vitem = 0; + vp->N = vp->M = 1; + if ( (rawtxstr= bitcoin_json2hex(myinfo,coin,&txid,txobj,0)) != 0 ) + { + for (j=0; jinputs[i].privkeys)/sizeof(*spend->inputs[i].privkeys); j++) + { + if ( bits256_nonz(spend->inputs[i].privkeys[j]) != 0 ) + { + vp->signers[j].privkey = spend->inputs[i].privkeys[j]; + bitcoin_pubkey33(coin->ctx,vp->signers[j].pubkey,vp->signers[j].privkey); + } + else + { + vp->signers[j].pubkey[0] = 0; + break; + } + } + if ( vitem != 0 && (pubkeys= jarray(&m,vitem,"pubkeys")) != 0 )//spend->inputs[i].numpubkeys > 0 ) + { + for (j=0; jinputs[i].privkeys)/sizeof(*spend->inputs[i].privkeys); j++) + { + if ( j < m && (pubkeystr= jstr(jitem(pubkeys,j),0)) != 0 && is_hexstr(pubkeystr,(int32_t)strlen(pubkeystr)) > 0 ) + decode_hex(vp->signers[j].pubkey,(int32_t)strlen(pubkeystr)>>1,pubkeystr); + else if ( (plen= bitcoin_pubkeylen(spend->inputs[i].pubkeys[j])) > 0 ) + memcpy(vp->signers[j].pubkey,spend->inputs[i].pubkeys[j],plen); + } + } + /*if ( spend->inputs[i].spendlen > 0 ) + { + memcpy(vp->spendscript,spend->inputs[i].spendscript,spend->inputs[i].spendlen); + vp->spendlen = spend->inputs[i].spendlen; + }*/ + if ( spend->inputs[i].p2shlen > 0 ) + { + memcpy(vp->p2shscript,spend->inputs[i].p2shscript,spend->inputs[i].p2shlen); + vp->p2shlen = spend->inputs[i].p2shlen; + } + for (j=0; jinputs[i].privkeys)/sizeof(*spend->inputs[i].privkeys); j++) + { + if ( vp->signers[j].coinaddr[0] == 0 && (plen= bitcoin_pubkeylen(spend->inputs[i].pubkeys[j])) > 0 ) + { + bitcoin_address(vp->signers[j].coinaddr,coin->chain->pubtype,spend->inputs[i].pubkeys[j],plen); + } + } + if ( myinfo->expiration != 0 ) + { + for (j=0; jinputs[i].privkeys)/sizeof(*spend->inputs[i].privkeys); j++) + { + if ( bits256_nonz(vp->signers[j].privkey) == 0 && vp->signers[j].coinaddr[0] != 0 ) + { + if ( (waddr= iguana_waddresssearch(myinfo,coin,&wacct,vp->signers[j].coinaddr)) != 0 ) + vp->signers[j].privkey = waddr->privkey; + } + } + } + vp->sequence = spend->inputs[i].sequence; + //printf("json2hex.(%s)\n",rawtxstr); + } + } + bitcoin_verifytx(coin,txidp,signedtxp,rawtxstr,V,spend->numinputs); + //printf("json2hex.(%s)\n",rawtxstr); + free(rawtxstr); + if ( *signedtxp != 0 && i != spend->numinputs ) + free(*signedtxp), *signedtxp = 0; + free(V); + return(txobj); +} + +int32_t iguana_vininfo_create(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msgtx,cJSON *vins,int32_t numinputs,struct vin_info *V) +{ + int32_t i,plen,len = 0; struct vin_info *vp; struct iguana_waccount *wacct; struct iguana_waddress *waddr; uint32_t sigsize,pubkeysize,p2shsize,suffixlen; + msgtx->tx_in = numinputs; + maxsize -= (sizeof(struct iguana_msgvin) * msgtx->tx_in); + msgtx->vins = (struct iguana_msgvin *)&serialized[maxsize]; + memset(msgtx->vins,0,sizeof(struct iguana_msgvin) * msgtx->tx_in); + if ( msgtx->tx_in > 0 && msgtx->tx_in*sizeof(struct iguana_msgvin) < maxsize ) + { + for (i=0; itx_in; i++) + { + vp = &V[i]; + len += iguana_parsevinobj(myinfo,coin,&serialized[len],maxsize,&msgtx->vins[i],jitem(vins,i),vp); + if ( msgtx->vins[i].spendscript == 0 ) + { + if ( (vp->unspentind= iguana_unspentindfind(coin,vp->coinaddr,vp->spendscript,&vp->spendlen,&vp->amount,&vp->height,msgtx->vins[i].prev_hash,msgtx->vins[i].prev_vout,coin->bundlescount-1)) > 0 ) + { + msgtx->vins[i].spendscript = vp->spendscript; + msgtx->vins[i].spendlen = vp->spendlen; + vp->hashtype = iguana_vinscriptparse(coin,V,&sigsize,&pubkeysize,&p2shsize,&suffixlen,vp->spendscript,vp->spendlen); + vp->suffixlen = suffixlen; + printf("V %.8f (%s) spendscript.[%d]\n",dstr(vp->amount),vp->coinaddr,vp->spendlen); + } + } + else + { + memcpy(vp->spendscript,msgtx->vins[i].spendscript,msgtx->vins[i].spendlen); + vp->spendlen = msgtx->vins[i].spendlen; + _iguana_calcrmd160(coin,vp); + if ( (plen= bitcoin_pubkeylen(vp->signers[0].pubkey)) > 0 ) + bitcoin_address(vp->coinaddr,coin->chain->pubtype,vp->signers[0].pubkey,plen); + } + if ( vp->coinaddr[i] != 0 && (waddr= iguana_waddresssearch(myinfo,coin,&wacct,vp->coinaddr)) != 0 ) + { + vp->signers[0].privkey = waddr->privkey; + if ( (plen= bitcoin_pubkeylen(waddr->pubkey)) != vp->spendscript[1] || vp->spendscript[vp->spendlen-1] != 0xac ) + { + if ( plen > 0 && plen < sizeof(vp->signers[0].pubkey) ) + memcpy(vp->signers[0].pubkey,waddr->pubkey,plen); + } + } + if ( vp->M == 0 && vp->N == 0 ) + vp->M = vp->N = 1; + } + } + /*for (i=0; itx_out; i++) + { + if ( msgtx->vouts[i].pk_script != 0 ) + { + for (j=0; jvouts[i].pk_scriptlen; j++) + printf("%02x",msgtx->vouts[i].pk_script[j]); + printf(" pk_script[%d]\n",i); + } + }*/ + return(len); +} + +void iguana_ensure_privkey(struct supernet_info *myinfo,struct iguana_info *coin,bits256 privkey) +{ + uint8_t pubkey33[33]; struct iguana_waccount *wacct; struct iguana_waddress *waddr,addr; char coinaddr[128]; + bitcoin_pubkey33(myinfo->ctx,pubkey33,privkey); + bitcoin_address(coinaddr,coin->chain->pubtype,pubkey33,33); + //printf("privkey for (%s)\n",coinaddr); + if ( myinfo->expiration != 0 && ((waddr= iguana_waddresssearch(myinfo,coin,&wacct,coinaddr)) == 0 || bits256_nonz(waddr->privkey) == 0) ) + { + if ( waddr == 0 ) + { + memset(&addr,0,sizeof(addr)); + iguana_waddresscalc(myinfo,coin->chain->pubtype,coin->chain->wiftype,&addr,privkey); + if ( (wacct= iguana_waccountfind(myinfo,coin,"default")) != 0 ) + waddr = iguana_waddressadd(myinfo,coin,wacct,&addr,0); + } + if ( waddr != 0 ) + { + waddr->privkey = privkey; + if ( bitcoin_priv2wif(waddr->wifstr,waddr->privkey,coin->chain->wiftype) > 0 ) + { + if ( waddr->wiftype != coin->chain->wiftype ) + printf("ensurepriv warning: mismatched wiftype %02x != %02x\n",waddr->wiftype,coin->chain->wiftype); + if ( waddr->addrtype != coin->chain->pubtype ) + printf("ensurepriv warning: mismatched wiftype %02x != %02x\n",waddr->addrtype,coin->chain->pubtype); + } + } + } +} + +char *_setVsigner(struct iguana_info *coin,struct vin_info *V,int32_t ind,char *pubstr,char *wifstr) +{ + uint8_t addrtype; + decode_hex(V->signers[ind].pubkey,(int32_t)strlen(pubstr)/2,pubstr); + bitcoin_wif2priv(&addrtype,&V->signers[ind].privkey,wifstr); + if ( addrtype != coin->chain->pubtype ) + return(clonestr("{\"error\":\"invalid wifA\"}")); + else return(0); +} + +int32_t bitcoin_txaddspend(struct iguana_info *coin,cJSON *txobj,char *destaddress,uint64_t satoshis) +{ + uint8_t outputscript[128],addrtype,rmd160[20]; int32_t scriptlen; + if ( bitcoin_validaddress(coin,destaddress) == 0 && satoshis != 0 ) + { + bitcoin_addr2rmd160(&addrtype,rmd160,destaddress); + scriptlen = bitcoin_standardspend(outputscript,0,rmd160); + bitcoin_txoutput(coin,txobj,outputscript,scriptlen,satoshis); + return(0); + } else return(-1); +} + +cJSON *bitcoin_txscript(struct iguana_info *coin,char *asmstr,char **vardata,int32_t numvars) +{ + int32_t i; cJSON *scriptjson,*array; + scriptjson = cJSON_CreateObject(); + jaddstr(scriptjson,"asm",asmstr); + jaddnum(scriptjson,"numvars",numvars); + if ( numvars > 0 ) + { + array = cJSON_CreateArray(); + for (i=0; i= 0 ) + { + if ( (n= V.N) == 0 ) + n = 1; + for (i=0; i 0 ) + init_hexbytes_noT(pubkeystr,V.signers[i].pubkey,plen); + else pubkeystr[0] = 0; + jaddistr(pubkeys,pubkeystr); + } + } + return(pubkeys); +} + +void iguana_addscript(struct iguana_info *coin,cJSON *dest,uint8_t *script,int32_t scriptlen,char *fieldname) +{ + char *scriptstr,scriptbuf[8192+256]; int32_t maxlen; cJSON *scriptobj; + if ( scriptlen < 0 ) + return; + if ( scriptlen > sizeof(scriptbuf) ) + maxlen = (scriptlen << 1) + 2048, scriptstr = malloc(maxlen); + else scriptstr = scriptbuf, maxlen = sizeof(scriptbuf); + init_hexbytes_noT(scriptstr,script,scriptlen); + if ( strcmp(fieldname,"coinbase") == 0 ) + jaddstr(dest,"coinbase",scriptstr); + else + { + scriptobj = cJSON_CreateObject(); + jaddstr(scriptobj,"hex",scriptstr); + iguana_expandscript(coin,scriptstr,maxlen,script,scriptlen); + if ( scriptstr[0] != 0 ) + jaddstr(scriptobj,"asm",scriptstr); + if ( scriptstr != scriptbuf ) + free(scriptstr); + jadd(dest,fieldname,scriptobj); + } +} + +cJSON *iguana_pubkeysjson(uint8_t *pubkeyptrs[],int32_t numpubkeys) +{ + int32_t i,plen; char pubkeystr[256]; cJSON *pubkeysjson = cJSON_CreateArray(); + for (i=0; i 0 ) + init_hexbytes_noT(pubkeystr,pubkeyptrs[i],plen); + else pubkeystr[0] = 0; + jaddistr(pubkeysjson,pubkeystr); + } + return(pubkeysjson); +} + +cJSON *bitcoin_txinput(struct iguana_info *coin,cJSON *txobj,bits256 txid,int32_t vout,uint32_t sequenceid,uint8_t *spendscript,int32_t spendlen,uint8_t *redeemscript,int32_t p2shlen,uint8_t *pubkeys[],int32_t numpubkeys) +{ + cJSON *item,*vins; char p2shscriptstr[IGUANA_MAXSCRIPTSIZE*2+1]; uint8_t *script,len; + vins = jduplicate(jobj(txobj,"vin")); + jdelete(txobj,"vin"); + item = cJSON_CreateObject(); + if ( spendscript != 0 && spendscript > 0 ) + { + iguana_addscript(coin,item,spendscript,spendlen,"scriptPubKey"); + script = spendscript, len = spendlen; + } + else if ( redeemscript != 0 && p2shlen > 0 ) + { + init_hexbytes_noT(p2shscriptstr,redeemscript,p2shlen); + jaddstr(item,"redeemScript",p2shscriptstr); + script = redeemscript, len = p2shlen; + } else script = 0; + if ( script != 0 && numpubkeys == 0 ) + jadd(item,"pubkeys",iguana_scriptpubkeys(coin,script,len,txid,vout,sequenceid)); + else if ( pubkeys != 0 && numpubkeys > 0 ) + jadd(item,"pubkeys",iguana_pubkeysjson(pubkeys,numpubkeys)); + jaddbits256(item,"txid",txid); + jaddnum(item,"vout",vout); + jaddnum(item,"sequence",sequenceid); + jaddi(vins,item); + jadd(txobj,"vin",vins); + //printf("addvin -> (%s)\n",jprint(txobj,0)); + return(txobj); +} + +cJSON *bitcoin_txcreate(struct iguana_info *coin,int64_t locktime) +{ + cJSON *json = cJSON_CreateObject(); + if ( locktime == 0 ) + { + jaddnum(json,"version",1); + jadd64bits(json,"locktime",0); + } + else + { + jaddnum(json,"version",4); + jadd64bits(json,"locktime",locktime); + } + if ( coin->chain->hastimestamp != 0 ) + jaddnum(json,"timestamp",time(NULL)); + jadd(json,"vin",cJSON_CreateArray()); + jadd(json,"vout",cJSON_CreateArray()); + return(json); +} + +cJSON *bitcoin_txoutput(struct iguana_info *coin,cJSON *txobj,uint8_t *paymentscript,int32_t len,uint64_t satoshis) +{ + char *hexstr; cJSON *item,*skey,*vouts = jduplicate(jobj(txobj,"vout")); + jdelete(txobj,"vout"); + item = cJSON_CreateObject(); + jadd64bits(item,"satoshis",satoshis); + skey = cJSON_CreateObject(); + hexstr = malloc(len*2 + 1); + init_hexbytes_noT(hexstr,paymentscript,len); + jaddstr(skey,"hex",hexstr); + //printf("addoutput.(%s %s)\n",hexstr,jprint(skey,0)); + free(hexstr); + jadd(item,"scriptPubkey",skey); + jaddi(vouts,item); + jadd(txobj,"vout",vouts); + return(txobj); +} + +int32_t iguana_interpreter(struct iguana_info *coin,int64_t nLockTime,struct vin_info *V,int32_t numvins) +{ + uint8_t script[IGUANA_MAXSCRIPTSIZE]; int32_t vini,scriptlen,errs = 0; cJSON *spendscript; + for (vini=0; viniexpiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + if ( (active= iguana_coinfind(activecoin)) == 0 ) + return(clonestr("{\"error\":\"activecoin isnt active\"}")); + if ( M > N || N > 3 ) + return(clonestr("{\"error\":\"illegal M or N\"}")); + memset(&V,0,sizeof(V)); + txobj = bitcoin_txcreate(active,0); + if ( destaddress[0] != 0 && destamount > 0. ) + bitcoin_txaddspend(active,txobj,destaddress,destamount * SATOSHIDEN); + if ( destaddress2[0] != 0 && destamount2 > 0. ) + bitcoin_txaddspend(active,txobj,destaddress2,destamount2 * SATOSHIDEN); + if ( pubA[0] != 0 && (retstr= _setVsigner(active,&V,0,pubA,wifA)) != 0 ) + return(retstr); + if ( N >= 2 && pubB[0] != 0 && (retstr= _setVsigner(active,&V,1,pubB,wifB)) != 0 ) + return(retstr); + if ( N == 3 && pubC[0] != 0 && (retstr= _setVsigner(active,&V,2,pubC,wifC)) != 0 ) + return(retstr); + V.M = M, V.N = N, V.type = IGUANA_SCRIPT_P2SH; + V.p2shlen = bitcoin_MofNspendscript(p2sh_rmd160,V.p2shscript,0,&V); + spendlen = bitcoin_p2shspend(spendscript,0,p2sh_rmd160); + if ( pubA[0] != 0 ) + { + decode_hex(pubkeys[0],(int32_t)strlen(pubA)>>1,pubA); + pubkeyptrs[0] = pubkeys[0]; + } + if ( pubB[0] != 0 ) + { + decode_hex(pubkeys[1],(int32_t)strlen(pubB)>>1,pubB); + pubkeyptrs[1] = pubkeys[1]; + } + if ( pubC[0] != 0 ) + { + decode_hex(pubkeys[2],(int32_t)strlen(pubC)>>1,pubC); + pubkeyptrs[2] = pubkeys[2]; + } + bitcoin_txinput(active,txobj,vintxid,vinvout,0xffffffff,spendscript,spendlen,V.p2shscript,V.p2shlen,pubkeyptrs,N); + bitcoin_address(msigaddr,active->chain->p2shtype,V.p2shscript,V.p2shlen); + retjson = cJSON_CreateObject(); + if ( bitcoin_verifyvins(active,&signedtxid,&signedtx,&msgtx,serialized,sizeof(serialized),&V,SIGHASH_ALL) == 0 ) + { + jaddstr(retjson,"result","msigtx"); + if ( signedtx != 0 ) + jaddstr(retjson,"signedtx",signedtx), free(signedtx); + jaddbits256(retjson,"txid",signedtxid); + } else jaddstr(retjson,"error","couldnt sign tx"); + jaddstr(retjson,"msigaddr",msigaddr); + return(jprint(retjson,1)); +} + +int32_t iguana_signrawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_msgtx *msgtx,char **signedtxp,bits256 *signedtxidp,struct vin_info *V,int32_t numinputs,char *rawtx,cJSON *vins,cJSON *privkeys) +{ + uint8_t *serialized,*serialized2,*serialized3; int32_t i,len,n,maxsize,complete = 0; char *checkstr,*privkeystr,*signedtx = 0; bits256 privkey,txid; cJSON *item; cJSON *txobj = 0; + maxsize = 1000000; + if ( rawtx != 0 && rawtx[0] != 0 && (len= (int32_t)strlen(rawtx)>>1) < maxsize ) + { + serialized = malloc(maxsize); + serialized2 = malloc(maxsize); + serialized3 = malloc(maxsize); + memset(msgtx,0,sizeof(*msgtx)); + decode_hex(serialized,len,rawtx); + if ( (txobj= bitcoin_hex2json(coin,&txid,msgtx,rawtx)) != 0 ) + { + //printf("txobj.(%s)\n",jprint(txobj,0)); + if ( (checkstr= bitcoin_json2hex(myinfo,coin,&txid,txobj,0)) != 0 ) + { + if ( strcmp(rawtx,checkstr) != 0 ) + { + printf("RAW.(%s) ->\nNEW.(%s)\n",rawtx,checkstr); + free_json(txobj); + free(checkstr); + free(serialized), free(serialized2), free(serialized3); + return(-2); + } + free(checkstr); + } + } + if ( (numinputs= cJSON_GetArraySize(vins)) > 0 ) + { + memset(msgtx,0,sizeof(*msgtx)); + if ( iguana_rwmsgtx(coin,0,0,serialized,maxsize,msgtx,&txid,"") > 0 && numinputs == msgtx->tx_in ) + { + if ( (n= cJSON_GetArraySize(privkeys)) > 0 ) + { + for (i=0; i 0 ) + { + iguana_interpreter(coin,j64bits(txobj,"locktime"),V,numinputs); + } + } + } + } else return(-1); + if ( txobj != 0 ) + free_json(txobj); + *signedtxp = signedtx; + return(complete); +} + +STRING_ARRAY_OBJ_STRING(bitcoinrpc,signrawtransaction,rawtx,vins,privkeys,sighash) +{ + char *signedtx = 0; struct vin_info *V; bits256 signedtxid; int32_t complete,numinputs = 1; struct iguana_msgtx msgtx; cJSON *retjson; int uselessbitcoin_error = 0; + retjson = cJSON_CreateObject(); + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + //printf("rawtx.(%s) vins.(%s) privkeys.(%s) sighash.(%s)\n",rawtx,jprint(vins,0),jprint(privkeys,0),sighash); + if ( sighash == 0 || sighash[0] == 0 ) + sighash = "ALL"; + if ( strcmp(sighash,"ALL") != 0 ) + jaddstr(retjson,"error","only sighash all (ALL) supported for now"); + if ( (numinputs= cJSON_GetArraySize(vins)) > 0 ) + { + V = calloc(numinputs,sizeof(*V)); + memset(&msgtx,0,sizeof(msgtx)); + if ( (complete= iguana_signrawtransaction(myinfo,coin,&msgtx,&signedtx,&signedtxid,V,numinputs,rawtx,vins,privkeys)) >= 0 ) + { + if ( signedtx != 0 ) + { + jaddstr(retjson,"result",signedtx); + jadd(retjson,"complete",complete!=0?jtrue():jfalse()); + free(signedtx); + } else jaddstr(retjson,"error",uselessbitcoin_error != 0 ? "-22" : "no transaction from verifyvins"); + } + else if ( complete == -2 ) + jaddstr(retjson,"error",uselessbitcoin_error != 0 ? "-22" : "hex2json -> json2hex error"); + else if ( complete == -1 ) + jaddstr(retjson,"error",uselessbitcoin_error != 0 ? "-22" : "couldnt load serialized tx or mismatched numinputs"); + free(V); + } else jaddstr(retjson,"error",uselessbitcoin_error != 0 ? "-22" : "no rawtx or rawtx too big"); + return(jprint(retjson,1)); +} + +#include "../includes/iguana_apiundefs.h" + diff --git a/iguana/iguana_spendvectors.c b/iguana/iguana_spendvectors.c new file mode 100755 index 000000000..f63a71c1c --- /dev/null +++ b/iguana/iguana_spendvectors.c @@ -0,0 +1,1109 @@ +/****************************************************************************** + * 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" + +static inline int32_t _iguana_spendvectorconv(struct iguana_spendvector *ptr,struct iguana_unspent *u,int32_t numpkinds,int32_t hdrsi,uint32_t unspentind) +{ + uint32_t spent_pkind = 0; + if ( (spent_pkind= u->pkind) != 0 && spent_pkind < numpkinds ) + { + ptr->pkind = spent_pkind; + ptr->value = u->value; + ptr->tmpflag = 0; + return(spent_pkind); + } else printf("spendvectorconv [%d] u%d pkind.%u/num %u\n",hdrsi,unspentind,u->pkind,numpkinds); + return(0); +} + +uint32_t iguana_spendvectorconv(struct iguana_info *coin,struct iguana_spendvector *ptr,struct iguana_bundle *bp) +{ + static uint64_t count,converted,errs; + struct iguana_bundle *spentbp; struct iguana_unspent *spentU; uint32_t spent_pkind; + count++; + if ( 0 && (count % 1000000) == 0 ) + printf("iguana_spendvectorconv.[%llu] errs.%llu converted.%llu %.2f%%\n",(long long)count,(long long)errs,(long long)converted,100. * (long long)converted/count); + if ( ptr->tmpflag != 0 ) + { + if ( ptr->hdrsi >= 0 && ptr->hdrsi < coin->bundlescount && (spentbp= coin->bundles[ptr->hdrsi]) != 0 ) + { + spentU = RAMCHAIN_PTR(spentbp->ramchain.H.data,Uoffset); + //spentU = (void *)(long)((long)spentbp->ramchain.H.data + spentbp->ramchain.H.data->Uoffset); + if ( (spent_pkind= _iguana_spendvectorconv(ptr,&spentU[ptr->unspentind],spentbp->ramchain.H.data->numpkinds,ptr->hdrsi,ptr->unspentind)) != 0 ) + converted++; + else printf("illegal [%d].u%u pkind.%u vs %u\n",ptr->hdrsi,ptr->unspentind,spent_pkind,spentbp->ramchain.H.data->numpkinds); + } else printf("illegal [%d].u%u\n",ptr->hdrsi,ptr->unspentind); + errs++; + return(0); + } //else printf("[%d] tmpflag.%d u%d %.8f p%u\n",ptr->hdrsi,ptr->tmpflag,ptr->unspentind,dstr(ptr->value),ptr->pkind); + return(ptr->pkind); +} + +int32_t iguana_spendvectorsave(struct iguana_info *coin,struct iguana_bundle *bp,struct iguana_ramchain *ramchain,struct iguana_spendvector *ptr,int32_t emit,int32_t n) +{ + int32_t i,retval = -1; FILE *fp; char fname[1024],str[65]; long fsize; bits256 zero,sha256; + if ( ptr == 0 || (bp->hdrsi != 0 && ptr == bp->ramchain.Xspendinds) ) + { + //printf("iguana_spendvectorsave.[%d] ptr.%p Xspendinds\n",bp->hdrsi,ptr); + return(0); + } + memset(zero.bytes,0,sizeof(zero)); + for (i=0; ihdrsi,i,emit,n); + return(-1); + } + sprintf(fname,"%s/%s/spends/%s.%d",GLOBAL_DBDIR,coin->symbol,bits256_str(str,bp->hashes[0]),bp->bundleheight); + vcalc_sha256(0,sha256.bytes,(void *)ptr,(int32_t)(sizeof(*ptr) * emit)); + if ( (fp= fopen(fname,"wb")) != 0 ) + { + if ( fwrite(sha256.bytes,1,sizeof(sha256),fp) != sizeof(sha256) ) + printf("error writing hash for %d -> (%s)\n",(int32_t)(sizeof(*ptr) * emit),fname); + else if ( fwrite(ptr,sizeof(*ptr),emit,fp) != emit ) + printf("error writing %d of %d -> (%s)\n",emit,n,fname); + else + { + retval = 0; + fsize = ftell(fp); + fclose(fp), fp = 0; + bp->Xvalid = 0; + if ( iguana_Xspendmap(coin,ramchain,bp) < 0 ) + printf("error mapping Xspendmap.(%s)\n",fname); + else + { + printf("created.(%s) %p[%d]\n",fname,bp->ramchain.Xspendinds,bp->ramchain.numXspends); + retval = 0; + } + } + if ( fp != 0 ) + fclose(fp); + //int32_t i; for (i=0; inumXspends; i++) + // printf("(%d u%d) ",ramchain->Xspendinds[i].hdrsi,ramchain->Xspendinds[i].ind); + //printf("filesize %ld Xspendptr.%p %p num.%d\n",fsize,ramchain->Xspendptr,ramchain->Xspendinds,ramchain->numXspends); + } + else printf("iguana_spendvectors: Error creating.(%s)\n",fname); + return(retval); +} + +struct iguana_bundle *iguana_externalspent(struct iguana_info *coin,bits256 *prevhashp,uint32_t *unspentindp,struct iguana_ramchain *ramchain,int32_t spent_hdrsi,struct iguana_spend *s,int32_t prefetchflag) +{ + int32_t prev_vout,height,hdrsi; uint32_t sequenceid,unspentind; char str[65]; + struct iguana_bundle *spentbp=0; struct iguana_txid *T,TX,*tp; bits256 *X; bits256 prev_hash; + X = RAMCHAIN_PTR(ramchain->H.data,Xoffset); + T = RAMCHAIN_PTR(ramchain->H.data,Toffset); + //X = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Xoffset); + //T = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Toffset); + //printf("external X.%p %ld num.%d\n",X,(long)ramchain->H.data->Xoffset,(int32_t)ramchain->H.data->numexternaltxids); + sequenceid = s->sequenceid; + hdrsi = spent_hdrsi; + *unspentindp = 0; + memset(prevhashp,0,sizeof(*prevhashp)); + if ( s->prevout < 0 ) + { + //printf("n.%d coinbase at spendind.%d firstvin.%d -> firstvout.%d -> unspentind\n",m,spendind,nextT->firstvin,nextT->firstvout); + //nextT++; + //m++; + return(0); + } + else + { + prev_vout = s->prevout; + iguana_ramchain_spendtxid(coin,&unspentind,&prev_hash,T,ramchain->H.data->numtxids,X,ramchain->H.data->numexternaltxids,s); + *prevhashp = prev_hash; + *unspentindp = unspentind; + if ( unspentind == 0 ) + { + //double duration,startmillis = OS_milliseconds(); + if ( (tp= iguana_txidfind(coin,&height,&TX,prev_hash,spent_hdrsi-1)) != 0 ) + { + *unspentindp = unspentind = TX.firstvout + ((prev_vout > 0) ? prev_vout : 0); + hdrsi = height / coin->chain->bundlesize; + if ( hdrsi >= 0 && hdrsi < coin->bundlescount && (spentbp= coin->bundles[hdrsi]) != 0 ) + { + //printf("%s height.%d firstvout.%d prev.%d ->U%d\n",bits256_str(str,prev_hash),height,TX.firstvout,prev_vout,unspentind); + /*now = (uint32_t)time(NULL); + duration = (OS_milliseconds() - startmillis); + if ( 0 && ((uint64_t)coin->txidfind_num % 1000000) == 1 ) + printf("%p iguana_txidfind.[%.0f] ave %.2f micros, total %.2f seconds | duration %.3f millis\n",spentbp->ramchain.txbits,coin->txidfind_num,(coin->txidfind_totalmillis*1000.)/coin->txidfind_num,coin->txidfind_totalmillis/1000.,duration); + coin->txidfind_totalmillis += duration; + coin->txidfind_num += 1.;*/ + if ( 1 && coin->PREFETCHLAG > 0 ) + { + if ( spentbp->lastprefetch == 0 ) + { + iguana_ramchain_prefetch(coin,&spentbp->ramchain,prefetchflag); + spentbp->lastprefetch = (uint32_t)time(NULL); + } + /*else if ( 0 && (rand() % IGUANA_NUMHELPERS) == 0 && (duration > 10 || duration > (10 * coin->txidfind_totalmillis)/coin->txidfind_num) ) + { + printf("slow txidfind %.2f vs %.2f prefetch[%d] from.[%d] lag.%ld last.%u\n",duration,coin->txidfind_totalmillis/coin->txidfind_num,spentbp->hdrsi,ramchain->height/coin->chain->bundlesize,time(NULL) - spentbp->lastprefetch,spentbp->lastprefetch); + iguana_ramchain_prefetch(coin,ramchain,1); + //spentbp->lastprefetch = now; + }*/ + } + } + else + { + printf("illegal hdrsi.%d prev_hash.(%s) for bp.[%d]\n",hdrsi,bits256_str(str,prev_hash),spent_hdrsi); + exit(-1); + } + } + else + { + printf("cant find prev_hash.(%s) for bp.[%d]\n",bits256_str(str,prev_hash),spent_hdrsi); + if ( spent_hdrsi < coin->current->hdrsi ) + { + iguana_bundleremove(coin,spent_hdrsi,1); + exit(-1); + } + coin->RTdatabad = 1; + return(0); + } + } else printf("external spent unexpected nonz unspentind [%d]\n",spent_hdrsi); + } + if ( (spentbp= coin->bundles[hdrsi]) == 0 || hdrsi > spent_hdrsi ) + printf("illegal hdrsi.%d when [%d] spentbp.%p\n",hdrsi,spent_hdrsi,spentbp); + else if ( unspentind == 0 || unspentind >= spentbp->ramchain.H.data->numunspents ) + printf("illegal unspentind.%d vs max.%d spentbp.%p[%d]\n",unspentind,spentbp->ramchain.H.data->numunspents,spentbp,hdrsi); + else return(spentbp); + iguana_bundleremove(coin,spent_hdrsi,1); + exit(-1); + return(0); +} + +struct iguana_bundle *iguana_fastexternalspent(struct iguana_info *coin,bits256 *prevhashp,uint32_t *unspentindp,struct iguana_ramchain *ramchain,int32_t spent_hdrsi,struct iguana_spend *s) +{ + int32_t prev_vout,height,hdrsi,unspentind; uint32_t ind; + struct iguana_txid *T; bits256 *X; bits256 prev_hash; struct iguana_ramchaindata *rdata; + if ( (rdata= ramchain->H.data) == 0 ) + return(0); + hdrsi = spent_hdrsi; + *unspentindp = 0; + memset(prevhashp,0,sizeof(*prevhashp)); + if ( (prev_vout= s->prevout) >= 0 ) + { + ind = s->spendtxidind & ~(1 << 31); + if ( s->external != 0 ) + { + if ( ind < rdata->numexternaltxids ) + { + char str[65]; //double duration,startmillis = OS_milliseconds(); + X = RAMCHAIN_PTR(rdata,Xoffset); + //X = (void *)(long)((long)rdata + rdata->Xoffset); + *prevhashp = prev_hash = X[ind]; + if ( (unspentind= iguana_unspentindfind(coin,0,0,0,0,&height,prev_hash,prev_vout,spent_hdrsi-1)) != 0 ) + //if ( (firstvout= iguana_txidfastfind(coin,&height,prev_hash,spent_hdrsi-1)) >= 0 ) + { + /*duration = (OS_milliseconds() - startmillis); + if ( ((uint64_t)coin->txidfind_num % 100) == 1 ) + printf("[%d] iguana_fasttxidfind.[%.0f] ave %.2f micros, total %.2f seconds | duration %.3f millis\n",spent_hdrsi,coin->txidfind_num,(coin->txidfind_totalmillis*1000.)/coin->txidfind_num,coin->txidfind_totalmillis/1000.,duration); + coin->txidfind_totalmillis += duration; + coin->txidfind_num += 1.;*/ + *unspentindp = unspentind;//firstvout + prev_vout; + hdrsi = height / coin->chain->bundlesize; + if ( hdrsi >= 0 && hdrsi < coin->bundlescount ) + return(coin->bundles[hdrsi]); + } + else + { + printf("couldnt fastfind (%s)\n",bits256_str(str,prev_hash)); + } + } else return(0); + } + else if ( ind < rdata->numtxids ) + { + T = RAMCHAIN_PTR(rdata,Toffset); + //T = (void *)(long)((long)rdata + rdata->Toffset); + *prevhashp = T[ind].txid; + *unspentindp = T[ind].firstvout + s->prevout; + return(coin->bundles[hdrsi]); + } + } + return(0); +} + +int32_t iguana_spendvectors(struct iguana_info *coin,struct iguana_bundle *bp,struct iguana_ramchain *ramchain,int32_t starti,int32_t numblocks,int32_t convertflag,int32_t iterate) +{ + static uint64_t total,emitted; + int32_t iter,spendind,n=0,txidind,errs=0,emit=0,i,j,k; double startmillis; bits256 prevhash; + uint32_t spent_unspentind,spent_pkind,now,starttime; struct iguana_ramchaindata *rdata; + struct iguana_bundle *spentbp; struct iguana_blockRO *B; struct iguana_spendvector *ptr; + struct iguana_unspent *u,*spentU; struct iguana_txid *T; char str[65]; + struct iguana_spend *S,*s; //void *fastfind = 0; + //printf("iguana_spendvectors.[%d] gen.%d ramchain data.%p txbits.%p\n",bp->hdrsi,bp->bundleheight,ramchain->H.data,ramchain->txbits); + if ( (rdata= ramchain->H.data) == 0 || (n= rdata->numspends) < 1 ) + { + printf("iguana_spendvectors.[%d]: no rdata.%p %d\n",bp->hdrsi,rdata,n); + return(0); + } + B = (void *)(long)((long)rdata + rdata->Boffset); + S = (void *)(long)((long)rdata + rdata->Soffset); + T = (void *)(long)((long)rdata + rdata->Toffset); + if ( ramchain->Xspendinds != 0 ) + { + bp->tmpspends = ramchain->Xspendinds; + bp->numtmpspends = ramchain->numXspends; + bp->utxofinish = (uint32_t)time(NULL); + bp->balancefinish = 0; + //printf("iguana_spendvectors.[%d]: already have Xspendinds[%d]\n",bp->hdrsi,ramchain->numXspends); + return(0); + } + ptr = mycalloc('x',sizeof(*ptr),n); + total += n; + startmillis = OS_milliseconds(); + if ( 0 && strcmp(coin->symbol,"BTC") == 0 ) + printf("start UTXOGEN.%d max.%d ptr.%p millis.%.3f\n",bp->bundleheight,n,ptr,startmillis); + starttime = (uint32_t)time(NULL); + iguana_ramchain_prefetch(coin,&bp->ramchain,3); + for (iter=0; iter<=iterate; iter++) + { + if ( iterate != 0 ) + { + //fastfind = coin->fast[iter]; + //coin->fast[iter] = calloc(1,coin->fastsizes[iter]); + //memcpy(coin->fast[iter],fastfind,coin->fastsizes[iter]); + } + txidind = B[starti].firsttxidind; + spendind = B[starti].firstvin; + for (i=starti; icurrent && (spendind % 10000) == 0 ) + printf("iter.%02x [%-3d:%4d] spendvectors elapsed t.%-3d spendind.%d\n",iter,bp->hdrsi,i,(uint32_t)time(NULL)-starttime,spendind); +#endif + u = 0; + spentbp = 0; + s = &S[spendind]; + if ( s->external != 0 && s->prevout >= 0 ) + { + if ( coin->fastfind != 0 ) + { + spentbp = iguana_fastexternalspent(coin,&prevhash,&spent_unspentind,ramchain,bp->hdrsi,s); + } + else if ( spentbp == 0 ) + { + if ( (spentbp= iguana_externalspent(coin,&prevhash,&spent_unspentind,ramchain,bp->hdrsi,s,2)) != 0 ) + { + if ( coin->fastfind != 0 ) + printf("found prevhash using slow, not fast\n"); + } + } + if ( iterate != 0 && (spentbp == 0 || spentbp->hdrsi != iter) ) + continue; + if ( bits256_nonz(prevhash) == 0 ) + continue; + if ( spentbp != 0 && spentbp->ramchain.H.data != 0 ) + { + if ( spentbp == bp ) + { + char str[65]; + printf("unexpected spendbp: height.%d bp.[%d] U%d <- S%d.[%d] [ext.%d %s prev.%d]\n",bp->bundleheight+i,spentbp->hdrsi,spent_unspentind,spendind,bp->hdrsi,s->external,bits256_str(str,prevhash),s->prevout); + errs++; + break; + } + if ( convertflag != 0 ) + { + if ( coin->PREFETCHLAG > 0 && now >= spentbp->lastprefetch+coin->PREFETCHLAG ) + { + printf("prefetch[%d] from.[%d] lag.%d\n",spentbp->hdrsi,bp->hdrsi,now - spentbp->lastprefetch); + iguana_ramchain_prefetch(coin,&spentbp->ramchain,2); + spentbp->lastprefetch = now; + } + spentU = RAMCHAIN_PTR(spentbp->ramchain.H.data,Uoffset); + //spentU = (void *)(long)((long)spentbp->ramchain.H.data + spentbp->ramchain.H.data->Uoffset); + u = &spentU[spent_unspentind]; + if ( (spent_pkind= u->pkind) != 0 && spent_pkind < spentbp->ramchain.H.data->numpkinds ) + { + memset(&ptr[emit],0,sizeof(ptr[emit])); + if ( (ptr[emit].unspentind= spent_unspentind) != 0 && spentbp->hdrsi < bp->hdrsi ) + { + ptr[emit].fromheight = bp->bundleheight + i; + ptr[emit].hdrsi = spentbp->hdrsi; + ptr[emit].pkind = spent_pkind; + ptr[emit].value = u->value; + //printf("ht.%d [%d] SPENDVECTOR u%d %.8f p%u\n",ptr[emit].fromheight,ptr[emit].hdrsi,ptr[emit].unspentind,dstr(ptr[emit].value),ptr[emit].pkind); + //printf("(%d u%d).%d ",spentbp->hdrsi,unspentind,emit); + emit++; + } + else + { + printf("spendvectors: null unspentind for spendind.%d hdrsi.%d [%d]\n",spendind,spentbp->hdrsi,bp->hdrsi); + errs++; + break; + } + } + else + { + errs++; + printf("spendvectors: unresolved spendind.%d hdrsi.%d\n",spendind,bp->hdrsi); + break; + } + } + else + { + memset(&ptr[emit],0,sizeof(ptr[emit])); + ptr[emit].hdrsi = spentbp->hdrsi; + ptr[emit].unspentind = spent_unspentind; + ptr[emit].fromheight = bp->bundleheight + i; + ptr[emit].tmpflag = 1; + if ( 0 && bp == coin->current ) + printf("fromht.%d spends [%d] TMPVECTOR u%d s%u\n",ptr[emit].fromheight,ptr[emit].hdrsi,ptr[emit].unspentind,spendind); + emit++; + } + } + else + { + errs++; + printf("spendvectors: error resolving external spendind.%d hdrsi.%d\n",spendind,bp->hdrsi); + break; + } + } + } + } + } + /*if ( iterate != 0 ) + { + free(coin->fast[iter]); + coin->fast[iter] = fastfind; + }*/ + if ( txidind != ramchain->H.data->numtxids && txidind != ramchain->H.txidind ) + { + printf("spendvectors: numtxid.%d != bp numtxids %d/%d\n",txidind,ramchain->H.txidind,ramchain->H.data->numtxids); + errs++; + } + if ( spendind != ramchain->H.data->numspends && spendind != ramchain->H.spendind ) + { + printf("spendvectors: spendind.%d != bp numspends %d/%d\n",spendind,ramchain->H.spendind,ramchain->H.data->numspends); + errs++; + } + } + if ( errs == 0 && emit >= 0 ) + { + emitted += emit; + if ( convertflag == 0 ) + { + if ( bp->tmpspends != 0 ) + { + if ( bp->tmpspends != ramchain->Xspendinds && emit > 0 ) + { + // printf("spendvectors: RT [%d] numtmpspends.%d vs starti.%d emit.%d\n",bp->hdrsi,bp->numtmpspends,starti,emit); + bp->tmpspends = myrealloc('x',bp->tmpspends,sizeof(*ptr)*bp->numtmpspends,sizeof(*ptr)*(bp->numtmpspends+emit)); + memcpy(&bp->tmpspends[bp->numtmpspends],ptr,sizeof(*ptr)*emit); + bp->numtmpspends += emit; + } + } + else if ( emit > 0 ) + { + bp->tmpspends = myrealloc('x',ptr,sizeof(*ptr)*n,sizeof(*ptr)*emit); + bp->numtmpspends = emit; + //printf("ALLOC tmpspends.[%d]\n",bp->hdrsi); + ptr = 0; + } + if ( 0 && bp == coin->current ) + printf("spendvectors.[%d]: tmpspends.%p[%d] after += emit.%d X.%p\n",bp->hdrsi,bp->tmpspends,bp->numtmpspends,emit,bp->ramchain.Xspendinds); + } else errs = -iguana_spendvectorsave(coin,bp,ramchain,ptr!=0?ptr:bp->tmpspends,emit,n); + } + if ( ptr != 0 ) + myfree(ptr,sizeof(*ptr) * n); + //if ( bp != coin->current ) + printf("UTXO [%4d].%-6d dur.%-2d [milli %8.3f] vectors %-6d err.%d [%5.2f%%] %7d %9s of %d\n",bp->hdrsi,bp->numtmpspends,(uint32_t)time(NULL)-starttime,OS_milliseconds()-startmillis,spendind,errs,100.*(double)emitted/(total+1),emit,mbstr(str,sizeof(*ptr) * emit),n); + return(-errs); +} + +int32_t iguana_balancegen(struct iguana_info *coin,int32_t incremental,struct iguana_bundle *bp,int32_t starti,int32_t endheight,int32_t startemit) +{ + uint32_t spent_unspentind,spent_pkind,txidind,h,i,j,endi,k,now; uint64_t spent_value; + struct iguana_ramchain *ramchain; struct iguana_ramchaindata *rdata; + struct iguana_spendvector *spend; struct iguana_unspent *spentU,*u; struct iguana_spendvector *Xspendinds; + struct iguana_txid *T; struct iguana_blockRO *B; struct iguana_bundle *spentbp; + int32_t spent_hdrsi,spendind,n,numXspends,errs=0,emit=0; struct iguana_spend *S,*s; + ramchain = &bp->ramchain; //(bp == coin->current) ? &coin->RTramchain : &bp->ramchain; + if ( (rdata= ramchain->H.data) == 0 || (n= ramchain->H.data->numspends) < 1 ) + return(-1); + S = (void *)(long)((long)rdata + rdata->Soffset); + B = (void *)(long)((long)rdata + rdata->Boffset); + T = (void *)(long)((long)rdata + rdata->Toffset); + numXspends = ramchain->numXspends; + if ( (Xspendinds= ramchain->Xspendinds) == 0 ) + { + numXspends = bp->numtmpspends; + if ( (Xspendinds= bp->tmpspends) == 0 ) + { + //printf("iguana_balancegen.%d: no Xspendinds[%d]\n",bp->hdrsi,numXspends); + //return(-1); + } + } + endi = (endheight % bp->n); + txidind = B[starti].firsttxidind; + spendind = B[starti].firstvin; + emit = startemit; + if ( coin->RTheight == 0 || bp->bundleheight+bp->n < coin->RTheight ) + fprintf(stderr,"BALANCEGEN.[%d] %p[%d] starti.%d s%d <-> endi.%d s%d startemit.%d\n",bp->hdrsi,Xspendinds,numXspends,starti,spendind,endi,B[endi].firstvin+B[endi].numvins,startemit); + for (i=starti; i<=endi; i++) + { + now = (uint32_t)time(NULL); + if ( 0 && bp == coin->current ) + printf("hdrs.[%d] B[%d] 1st txidind.%d txn_count.%d firstvin.%d firstvout.%d\n",bp->hdrsi,i,B[i].firsttxidind,B[i].txn_count,B[i].firstvin,B[i].firstvout); + if ( txidind != B[i].firsttxidind || spendind != B[i].firstvin ) + { + printf("balancegen: txidind %u != %u B[%d].firsttxidind || spendind %u != %u B[%d].firstvin errs.%d\n",txidind,B[i].firsttxidind,i,spendind,B[i].firstvin,i,errs); + return(-1); + } + for (j=0; jcurrent ) + printf("starti.%d txidind.%d txi.%d numvins.%d spendind.%d\n",i,txidind,j,T[txidind].numvins,spendind); + for (k=0; kexternal != 0 && s->prevout >= 0 ) + { + if ( emit >= numXspends ) + errs++; + else if ( Xspendinds != 0 ) + { + spend = &Xspendinds[emit++]; + spent_unspentind = spend->unspentind; + spent_value = spend->value; + spent_pkind = spend->pkind; + spent_hdrsi = spend->hdrsi; + h = spend->fromheight; + } + if ( 0 && bp == coin->current ) + printf("external prevout.%d (emit.%d numX.%d) %p u%d p%d errs.%d spent_hdrsi.%d s%u\n",s->prevout,emit,numXspends,Xspendinds,spent_unspentind,spent_pkind,errs,spent_hdrsi,spendind); + } + else if ( s->prevout >= 0 ) + { + h = bp->bundleheight + i; + spent_hdrsi = bp->hdrsi; + if ( s->spendtxidind != 0 && s->spendtxidind < rdata->numtxids ) + { + spent_unspentind = T[s->spendtxidind].firstvout + s->prevout; + spentU = RAMCHAIN_PTR(rdata,Uoffset); + //spentU = (void *)(long)((long)rdata + rdata->Uoffset); + u = &spentU[spent_unspentind]; + if ( (spent_pkind= u->pkind) != 0 && spent_pkind < rdata->numpkinds ) + spent_value = u->value; + /*found spend d9151... txidind.1083097 [202] s3163977 + //found spend d9151... txidind.1083097 [202] s4033628 + if ( spent_hdrsi == 202 && (spendind == 3163977 || spendind == 4033628) ) + printf("internal spend.%d spendtxidind.%d 1st.%d U.(prevout.%d u%u pkind.%u %.8f)\n",spendind,txidind,T[s->spendtxidind].firstvout,s->prevout,spent_unspentind,u->pkind,dstr(u->value));*/ + } + else //if ( i > 0 || j > 0 || k > 0 ) + { + printf("iguana_balancegen [%d] txidind overflow %u vs %u (%d %d %d)\n",bp->hdrsi,s->spendtxidind,rdata->numtxids,i,j,k); + errs++; + } + } + else continue; + spentbp = 0; + if ( (spentbp= coin->bundles[spent_hdrsi]) != 0 && spent_unspentind > 0 && spent_pkind > 0 ) + { + if ( 0 && bp == coin->current ) + printf("[%d] spendind.%u -> [%d] u%d\n",bp->hdrsi,spendind,spent_hdrsi,spent_unspentind); + if ( iguana_volatileupdate(coin,incremental,spentbp == coin->current ? &coin->RTramchain : &spentbp->ramchain,spent_hdrsi,spent_unspentind,spent_pkind,spent_value,spendind,h) < 0 ) + errs++; + } + else //if ( Xspendinds != 0 ) + { + errs++; + printf("iguana_balancegen: spendind.%u external.%d error spentbp.%p with unspentind.%d pkind.%u [%d] (%d %d %d)\n",spendind,s->external,spentbp,spent_unspentind,spent_pkind,spent_hdrsi,i,j,k); + } + } + } + } + if ( txidind != bp->ramchain.H.data->numtxids && (bp != coin->current || txidind != ramchain->H.txidind) ) + { + printf("numtxid.%d != bp numtxids %d/%d\n",txidind,bp->ramchain.H.txidind,bp->ramchain.H.data->numtxids); + errs++; + } + if ( spendind != ramchain->H.data->numspends && (bp != coin->current || spendind != ramchain->H.spendind) ) + { + printf("spendind.%d != bp numspends %d/%d\n",spendind,bp->ramchain.H.spendind,bp->ramchain.H.data->numspends); + errs++; + } + if ( emit != numXspends ) + { + printf("iguana_balancegen: emit %d != %d ramchain->numXspends\n",emit,numXspends); + errs++; + } + if ( errs == 0 ) + bp->balancefinish = (uint32_t)time(NULL); + //printf(">>>>>>>> balances.%d done errs.%d spendind.%d\n",bp->hdrsi,errs,n); + return(-errs); +} + +void iguana_truncatebalances(struct iguana_info *coin) +{ + int32_t i; struct iguana_bundle *bp; + for (i=0; ibalanceswritten; i++) + { + if ( (bp= coin->bundles[i]) != 0 ) + { + bp->balancefinish = 0; + bp->Xvalid = 0; + iguana_volatilespurge(coin,&bp->ramchain); + } + } + coin->balanceswritten = 0; +} + +int32_t iguana_volatilesinit(struct iguana_info *coin) +{ + bits256 balancehash,allbundles; struct iguana_utxo *Uptr; struct iguana_account *Aptr; + struct sha256_vstate vstate,bstate; int32_t i,from_ro,numpkinds,numunspents; struct iguana_bundle *bp; struct iguana_block *block; + uint32_t crc,filecrc; FILE *fp; char crcfname[512],str[65],str2[65],buf[2048]; + from_ro = 1; + for (i=0; ibalanceswritten; i++) + { + if ( (bp= coin->bundles[i]) == 0 ) + break; + if ( bp->emitfinish <= 1 || (i > 0 && bp->utxofinish <= 1) ) + { + printf("hdrsi.[%d] emitfinish.%u utxofinish.%u\n",i,bp->emitfinish,bp->utxofinish); + break; + } + iguana_volatilesmap(coin,&bp->ramchain); + if ( from_ro != 0 && (bp->ramchain.from_ro == 0 || (bp->hdrsi > 0 && bp->ramchain.from_roX == 0) || bp->ramchain.from_roA == 0 || bp->ramchain.from_roU == 0) ) + { + printf("from_ro.[%d] %d %d %d %d\n",bp->hdrsi,bp->ramchain.from_ro,bp->ramchain.from_roX,bp->ramchain.from_roA,bp->ramchain.from_roU); + from_ro = 0; + } + } + if ( i < coin->balanceswritten-1 ) + { + printf("TRUNCATE balances written.%d -> %d\n",coin->balanceswritten,i); + iguana_truncatebalances(coin); + } + else + { + coin->balanceswritten = i; + //printf("verify crc and sha256 hash for %d of %d\n",i,coin->balanceswritten); + vupdate_sha256(balancehash.bytes,&vstate,0,0); + vupdate_sha256(allbundles.bytes,&bstate,0,0); + filecrc = 0; + sprintf(crcfname,"%s/%s/balancecrc.%d",GLOBAL_DBDIR,coin->symbol,coin->balanceswritten); + if ( (fp= fopen(crcfname,"rb")) != 0 ) + { + if ( fread(&filecrc,1,sizeof(filecrc),fp) != sizeof(filecrc) ) + filecrc = 0; + else if ( fread(&balancehash,1,sizeof(balancehash),fp) != sizeof(balancehash) ) + filecrc = 0; + else if ( memcmp(&balancehash,&coin->balancehash,sizeof(balancehash)) != 0 ) + filecrc = 0; + else if ( fread(&allbundles,1,sizeof(allbundles),fp) != sizeof(allbundles) ) + filecrc = 0; + else if ( memcmp(&allbundles,&coin->allbundles,sizeof(allbundles)) != 0 ) + filecrc = 0; + fclose(fp); + } + if ( filecrc != 0 ) + printf("have filecrc.%08x for %s milli.%.0f from_ro.%d\n",filecrc,bits256_str(str,balancehash),OS_milliseconds(),from_ro); + if ( from_ro == 0 || filecrc == 0 ) + { + if ( filecrc == 0 ) + { + vupdate_sha256(balancehash.bytes,&vstate,0,0); + vupdate_sha256(allbundles.bytes,&bstate,0,0); + } + for (i=crc=0; ibalanceswritten; i++) + { + numpkinds = numunspents = 0; + Aptr = 0, Uptr = 0; + if ( (bp= coin->bundles[i]) != 0 && bp->ramchain.H.data != 0 && (numpkinds= bp->ramchain.H.data->numpkinds) > 0 && (numunspents= bp->ramchain.H.data->numunspents) > 0 && (Aptr= bp->ramchain.A2) != 0 && (Uptr= bp->ramchain.Uextras) != 0 ) + { + if ( (bp->bundleheight % 10000) == 0 ) + fprintf(stderr,"."); + if ( filecrc == 0 ) + { + vupdate_sha256(balancehash.bytes,&vstate,(void *)Aptr,sizeof(*Aptr) * numpkinds); + vupdate_sha256(balancehash.bytes,&vstate,(void *)Uptr,sizeof(*Uptr) * numunspents); + vupdate_sha256(allbundles.bytes,&bstate,(void *)bp->hashes,sizeof(bp->hashes[0]) * bp->n); + } + crc = calc_crc32(crc,(void *)Aptr,(int32_t)(sizeof(*Aptr) * numpkinds)); + crc = calc_crc32(crc,(void *)Uptr,(int32_t)(sizeof(*Uptr) * numunspents)); + crc = calc_crc32(crc,(void *)bp->hashes,(int32_t)(sizeof(bp->hashes[0]) * bp->n)); + } //else printf("missing hdrs.[%d] data.%p num.(%u %d) %p %p\n",i,bp->ramchain.H.data,numpkinds,numunspents,Aptr,Uptr); + } + } else crc = filecrc; + printf("millis %.0f from_ro.%d written.%d crc.%08x/%08x balancehash.(%s) vs (%s)\n",OS_milliseconds(),from_ro,coin->balanceswritten,crc,filecrc,bits256_str(str,balancehash),bits256_str(str2,coin->balancehash)); + if ( (filecrc != 0 && filecrc != crc) || memcmp(balancehash.bytes,coin->balancehash.bytes,sizeof(balancehash)) != 0 || memcmp(allbundles.bytes,coin->allbundles.bytes,sizeof(allbundles)) != 0 ) + { + printf("balancehash or crc.(%x %x) mismatch or allbundles.(%llx %llx) mismatch\n",crc,filecrc,(long long)allbundles.txid,(long long)coin->allbundles.txid); + iguana_truncatebalances(coin); + OS_removefile(crcfname,0); + } + else + { + printf("MATCHED balancehash numhdrsi.%d crc.%08x\n",coin->balanceswritten,crc); + if ( (fp= fopen(crcfname,"wb")) != 0 ) + { + if ( fwrite(&crc,1,sizeof(crc),fp) != sizeof(crc) || fwrite(&balancehash,1,sizeof(balancehash),fp) != sizeof(balancehash) || fwrite(&allbundles,1,sizeof(allbundles),fp) != sizeof(allbundles) ) + printf("error writing.(%s)\n",crcfname); + fclose(fp); + } + else + { + printf("volatileinit: cant create.(%s)\n",crcfname); + return(-1); + } + } + } + if ( (coin->RTheight= coin->balanceswritten * coin->chain->bundlesize) > coin->longestchain ) + coin->longestchain = coin->RTheight; + iguana_bundlestats(coin,buf,IGUANA_DEFAULTLAG); + if ( (bp= coin->bundles[coin->balanceswritten-1]) != 0 && (block= bp->blocks[bp->n-1]) != 0 ) + { + //char str[65]; + //printf("set hwmchain.%d <- %s %p\n",bp->bundleheight+bp->n-1,bits256_str(str,bp->hashes[bp->n-1]),block); + if ( block->height > coin->blocks.hwmchain.height ) + coin->blocks.hwmchain = *block; + } + //printf("end volatilesinit\n"); + if ( iguana_fastfindinit(coin) == 0 )//&& coin->PREFETCHLAG >= 0 ) + iguana_fastfindcreate(coin); + return(coin->balanceswritten); +} + +void iguana_initfinal(struct iguana_info *coin,bits256 lastbundle) +{ + int32_t i; struct iguana_bundle *bp; bits256 hash2; struct iguana_block *block; char hashstr[65]; + if ( bits256_nonz(lastbundle) > 0 ) + { + init_hexbytes_noT(hashstr,lastbundle.bytes,sizeof(bits256)); + printf("req lastbundle.(%s)\n",hashstr); + queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr),1); + } + for (i=0; ibundlescount-1; i++) + { + if ( (bp= coin->bundles[i]) == 0 || bp->emitfinish <= 1 ) + { + printf("initfinal break.[%d]: bp.%p or emit.%u utxofinish.%u\n",i,bp,bp!=0?bp->emitfinish:-1,bp!=0?bp->utxofinish:-1); + break; + } + if ( i == 0 ) + bp->utxofinish = bp->startutxo = (uint32_t)time(NULL); + } + if ( i < coin->bundlescount-1 ) + { + printf("spendvectors.[%d] max.%d missing, will regen all of them\n",i,coin->bundlescount-1); + for (i=0; ibundlescount-1; i++) + { + if ( (bp= coin->bundles[i]) != 0 ) + bp->startutxo = bp->utxofinish = 0; + } + } + else + { + for (i=0; ibundlescount-1; i++) + { + if ( (bp= coin->bundles[i]) != 0 ) + bp->converted = (uint32_t)time(NULL); + } + } + printf("i.%d bundlescount.%d\n",i,coin->bundlescount); + if ( coin->balanceswritten > 1 ) + coin->balanceswritten = iguana_volatilesinit(coin); + if ( coin->balanceswritten > 1 ) + { + for (i=0; ibalanceswritten; i++) + { + //printf("%d ",i); + iguana_validateQ(coin,coin->bundles[i]); + } + } + printf("i.%d balanceswritten.%d\n",i,coin->balanceswritten); + if ( coin->balanceswritten < coin->bundlescount ) + { + for (i=coin->balanceswritten; ibundlescount; i++) + { + if ( (bp= coin->bundles[i]) != 0 && bp->queued == 0 ) + { + //printf("%d ",i); + iguana_bundleQ(coin,bp,1000); + } + } + printf("iguana_bundlesQ %d to %d\n",coin->balanceswritten,coin->bundlescount); + } + if ( (coin->origbalanceswritten= coin->balanceswritten) > 0 ) + iguana_volatilesinit(coin); + iguana_savehdrs(coin); + iguana_fastlink(coin,coin->balanceswritten * coin->chain->bundlesize - 1); + iguana_walkchain(coin,0); + hash2 = iguana_blockhash(coin,coin->balanceswritten * coin->chain->bundlesize); + if ( bits256_nonz(hash2) != 0 && (block= iguana_blockfind("initfinal",coin,hash2)) != 0 ) + _iguana_chainlink(coin,block); +} + +int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi) +{ + int32_t hdrsi,numpkinds,iter,numhdrsi,i,numunspents,err; struct iguana_bundle *bp; + char fname[1024],fname2[1024],destfname[1024]; bits256 balancehash,allbundles; FILE *fp,*fp2; + struct iguana_utxo *Uptr; struct iguana_account *Aptr; struct sha256_vstate vstate,bstate; + vupdate_sha256(balancehash.bytes,&vstate,0,0); + numhdrsi = refhdrsi; + vupdate_sha256(balancehash.bytes,&vstate,0,0); + vupdate_sha256(allbundles.bytes,&bstate,0,0); + for (iter=0; iter<3; iter++) + { + for (hdrsi=0; hdrsibundles[hdrsi]) != 0 && bp->ramchain.H.data != 0 && (numpkinds= bp->ramchain.H.data->numpkinds) > 0 && (numunspents= bp->ramchain.H.data->numunspents) > 0 && (Aptr= bp->ramchain.A2) != 0 && (Uptr= bp->ramchain.Uextras) != 0 ) + { + sprintf(fname,"%s/%s/debits.%d_N%d",GLOBAL_TMPDIR,coin->symbol,bp->hdrsi,numhdrsi); + sprintf(fname2,"%s/%s/lastspends.%d_N%d",GLOBAL_TMPDIR,coin->symbol,bp->hdrsi,numhdrsi); + if ( iter == 0 ) + { + vupdate_sha256(balancehash.bytes,&vstate,(void *)Aptr,sizeof(*Aptr)*numpkinds); + vupdate_sha256(balancehash.bytes,&vstate,(void *)Uptr,sizeof(*Uptr)*numunspents); + vupdate_sha256(allbundles.bytes,&bstate,(void *)bp->hashes,sizeof(bp->hashes[0])*bp->n); + } + else if ( iter == 1 ) + { + if ( (fp= fopen(fname,"wb")) != 0 && (fp2= fopen(fname2,"wb")) != 0 ) + { + err = -1; + if ( fwrite(&numhdrsi,1,sizeof(numhdrsi),fp) == sizeof(numhdrsi) && fwrite(&numhdrsi,1,sizeof(numhdrsi),fp2) == sizeof(numhdrsi) && fwrite(balancehash.bytes,1,sizeof(balancehash),fp) == sizeof(balancehash) && fwrite(balancehash.bytes,1,sizeof(balancehash),fp2) == sizeof(balancehash) && fwrite(allbundles.bytes,1,sizeof(allbundles),fp) == sizeof(allbundles) && fwrite(allbundles.bytes,1,sizeof(allbundles),fp2) == sizeof(allbundles) ) + { + if ( fwrite(Aptr,sizeof(*Aptr),numpkinds,fp) == numpkinds ) + { + if ( fwrite(Uptr,sizeof(*Uptr),numunspents,fp2) == numunspents ) + { + err = 0; + printf("[%d] of %d saved (%s) and (%s)\n",hdrsi,numhdrsi,fname,fname2); + } + } + } + if ( err != 0 ) + { + printf("balanceflush.%s error iter.%d hdrsi.%d\n",coin->symbol,iter,hdrsi); + fclose(fp); + fclose(fp2); + return(-1); + } + fclose(fp), fclose(fp2); + } + else + { + printf("error opening %s or %s %p\n",fname,fname2,fp); + if ( fp != 0 ) + fclose(fp); + } + } + else if ( iter == 2 ) + { + sprintf(destfname,"%s/%s/accounts/debits.%d",GLOBAL_DBDIR,coin->symbol,bp->bundleheight); + if ( OS_copyfile(fname,destfname,1) < 0 ) + { + printf("balances error copying (%s) -> (%s)\n",fname,destfname); + return(-1); + } + sprintf(destfname,"%s/%s/accounts/lastspends.%d",GLOBAL_DBDIR,coin->symbol,bp->bundleheight); + if ( OS_copyfile(fname2,destfname,1) < 0 ) + { + printf("balances error copying (%s) -> (%s)\n",fname2,destfname); + return(-1); + } + printf("%s -> %s\n",fname,destfname); + OS_removefile(fname,0); + OS_removefile(fname2,0); + } + if ( bp->ramchain.allocatedA2 == 0 || bp->ramchain.allocatedU2 == 0 ) + { + printf("skip saving.[%d] files as not allocated\n",bp->hdrsi); + break; + } + } + else if ( hdrsi > 0 && (coin->current == 0 || hdrsi != coin->current->hdrsi) ) + { + printf("balanceflush iter.%d error loading [%d] Aptr.%p Uptr.%p numpkinds.%u numunspents.%u\n",iter,hdrsi,Aptr,Uptr,numpkinds,numunspents); + return(-1); + } + } + } + coin->allbundles = allbundles; + coin->balancehash = balancehash; + coin->balanceswritten = numhdrsi; + if ( 1 ) + { + for (hdrsi=0; hdrsibundles[hdrsi]) == 0 && bp != coin->current ) + { + iguana_volatilespurge(coin,&bp->ramchain); + if ( iguana_volatilesmap(coin,&bp->ramchain) != 0 ) + printf("error mapping bundle.[%d]\n",hdrsi); + } + } + char str[65]; printf("BALANCES WRITTEN for %d orig.%d bundles %s\n",coin->balanceswritten,coin->origbalanceswritten,bits256_str(str,coin->balancehash)); + if ( 0 && coin->balanceswritten > coin->origbalanceswritten+10 ) // strcmp(coin->symbol,"BTC") == 0 && + { + coin->active = 0; + coin->started = 0; + for (i=0; ipeers.active[i].dead = (uint32_t)time(NULL); +#ifdef __linux__ + char cmd[1024]; + sprintf(cmd,"mksquashfs %s/%s %s.%d -comp xz",GLOBAL_DBDIR,coin->symbol,coin->symbol,coin->balanceswritten); + if ( system(cmd) != 0 ) + printf("error system(%s)\n",cmd); + else + { + sprintf(cmd,"sudo umount %s/ro/%s",GLOBAL_DBDIR,coin->symbol); + if ( system(cmd) != 0 ) + printf("error system(%s)\n",cmd); + else + { + sprintf(cmd,"sudo mount %s.%d %s/ro/%s -t squashfs -o loop",coin->symbol,coin->balanceswritten,GLOBAL_DBDIR,coin->symbol); + if ( system(cmd) != 0 ) + printf("error system(%s)\n",cmd); + } + } +#endif + for (i=0; i<30; i++) + { + printf("need to exit, please restart after shutdown in %d seconds, or just ctrl-C\n",30-i); + sleep(1); + } + exit(-1); + } + coin->balanceswritten = iguana_volatilesinit(coin); + //printf("flush free\n"); + iguana_RTramchainfree(coin,bp); + return(coin->balanceswritten); +} + +int32_t iguana_spendvectorsaves(struct iguana_info *coin) +{ + int32_t i,j,n,iter; struct iguana_bundle *bp; + if ( coin->spendvectorsaved > 1 ) + return(0); + coin->spendvectorsaved = 1; + n = coin->bundlescount - 1; + //printf("SAVE SPEND VECTORS %d of %d\n",n,coin->bundlescount); + for (iter=0; iter<2; iter++) + { + for (i=0; ibundles[i]) != 0 ) + { + if ( iter == 0 ) + { + if ( bp->tmpspends != 0 )//bp->ramchain.Xspendinds == 0 && + { + for (j=0; jnumtmpspends; j++) + if ( bp->tmpspends[j].tmpflag != 0 ) + { + printf("vectorsave.[%d] vec.%d still has tmpflag\n",i,j); + return(-1); + } + } + } + else if ( iguana_spendvectorsave(coin,bp,&bp->ramchain,bp->tmpspends,bp->numtmpspends,bp->ramchain.H.data->numspends) == 0 ) + { + if ( bp->tmpspends != 0 && bp->numtmpspends > 0 && bp->tmpspends != bp->ramchain.Xspendinds ) + myfree(bp->tmpspends,sizeof(*bp->tmpspends) * bp->numtmpspends); + bp->numtmpspends = 0; + bp->tmpspends = 0; + } + } + } + } + coin->spendvectorsaved = (uint32_t)time(NULL); + return(0); +} + +int32_t iguana_spendvectorconvs(struct iguana_info *coin,struct iguana_bundle *spentbp,int32_t starti) +{ + struct iguana_bundle *bp; int16_t spent_hdrsi; uint32_t numpkinds; struct iguana_unspent *spentU; struct iguana_spendvector *vec; int32_t i,converted,j,n = coin->bundlescount; struct iguana_ramchain *ramchain; struct iguana_ramchaindata *rdata = 0; + if ( (rdata= spentbp->ramchain.H.data) == 0 ) + { + //if ( spentbp == coin->current ) + printf("iguana_spendvectorconvs: [%d] null rdata.%p\n",spentbp->hdrsi,rdata); + return(-1); + } + spent_hdrsi = spentbp->hdrsi; + ramchain = &spentbp->ramchain; + numpkinds = rdata->numpkinds; + spentU = RAMCHAIN_PTR(rdata,Uoffset); + //spentU = (void *)(long)((long)rdata + rdata->Uoffset); + for (i=converted=0; ibundles[i]) != 0 && bp->tmpspends != 0 ) + { + for (j=0; jnumtmpspends; j++) + { + vec = &bp->tmpspends[j]; + if ( vec->hdrsi == spent_hdrsi ) + { + if ( vec->tmpflag == 0 ) + { + if ( bp->tmpspends != bp->ramchain.Xspendinds && bp != coin->current ) + printf("unexpected null tmpflag [%d] j.%d spentbp.[%d]\n",bp->hdrsi,j,spentbp->hdrsi); + } + else + { + if ( _iguana_spendvectorconv(vec,&spentU[vec->unspentind],numpkinds,vec->hdrsi,vec->unspentind) != 0 ) + converted++; + else + { + printf("iguana_spendvectorconv.[%d] error [%d] at %d of T[%d/%d] [%d] u%u p%u\n",spentbp->hdrsi,bp->hdrsi,j,bp->numtmpspends,n,vec->hdrsi,vec->unspentind,spentU[vec->unspentind].pkind); + return(-1); + } + } + } + } + } + else if ( bp->hdrsi < coin->bundlescount-1 ) + { + //printf("iguana_spendvectorconvs: [%d] null bp.%p\n",i,bp); + } + } + spentbp->converted = (uint32_t)time(NULL); + //printf("spendvectorconvs.[%d] converted.%d\n",refbp->hdrsi,converted); + return(converted); +} + +int32_t iguana_convert(struct iguana_info *coin,int32_t helperid,struct iguana_bundle *bp,int32_t RTflag,int32_t starti) +{ + static int64_t total[256],depth; + int32_t i,n,m,max,converted; int64_t total_tmpspends,sum; double startmillis = OS_milliseconds(); + depth++; + if ( (converted= iguana_spendvectorconvs(coin,bp,starti)) < 0 ) + { + printf("error iguana_convert.[%d]\n",bp->hdrsi); + return(0); + } + else + { + n = coin->bundlescount; + for (i=m=total_tmpspends=0; ibundles[i] != 0 ) + { + total_tmpspends += coin->bundles[i]->numtmpspends; + if ( coin->bundles[i]->converted > 1 ) + m++; + } + } + max = (int32_t)(sizeof(total) / sizeof(*total)); + total[helperid % max] += converted; + for (i=sum=0; ihdrsi,OS_milliseconds()-startmillis,converted,m,n,(long long)sum,(long long)total_tmpspends,(int32_t)depth); + } + depth--; + return(converted); +} + +int32_t iguana_bundlevalidate(struct iguana_info *coin,struct iguana_bundle *bp,int32_t forceflag) +{ + static int32_t totalerrs,totalvalidated; + FILE *fp; char fname[1024]; uint8_t *blockspace; uint32_t now = (uint32_t)time(NULL); + int32_t i,max,len,errs = 0; struct sha256_vstate vstate; bits256 validatehash; int64_t total = 0; + if ( (coin->VALIDATENODE == 0 && coin->RELAYNODE == 0) || bp->ramchain.from_ro != 0 || bp == coin->current ) + { + bp->validated = (uint32_t)time(NULL); + return(bp->n); + } + if ( bp->validated <= 1 || forceflag != 0 ) + { + //printf("validate.[%d]\n",bp->hdrsi); + vupdate_sha256(validatehash.bytes,&vstate,0,0); + sprintf(fname,"%s/%s/validated/%d",GLOBAL_DBDIR,coin->symbol,bp->bundleheight); + //printf("validatefname.(%s)\n",fname); + if ( (fp= fopen(fname,"rb")) != 0 ) + { + if ( forceflag == 0 ) + { + if ( fread(&bp->validated,1,sizeof(bp->validated),fp) != sizeof(bp->validated) ||fread(&total,1,sizeof(total),fp) != sizeof(total) || fread(&validatehash,1,sizeof(validatehash),fp) != sizeof(validatehash) ) + { + printf("error reading.(%s)\n",fname); + total = bp->validated = 0; + } //else printf("(%s) total.%d validated.%u\n",fname,(int32_t)total,bp->validated); + } else OS_removefile(fname,1); + fclose(fp); + } + if ( forceflag != 0 || bp->validated <= 1 ) + { + max = sizeof(coin->blockspace); + blockspace = calloc(1,max); + iguana_volatilesmap(coin,&bp->ramchain); + for (i=0; in; i++) + { + if ( (len= iguana_peerblockrequest(coin,blockspace,max,0,bp->hashes[i],1)) < 0 ) + { + errs++; + iguana_blockunmark(coin,bp->blocks[i],bp,i,1); + totalerrs++; + } + else + { + vupdate_sha256(validatehash.bytes,&vstate,bp->hashes[i].bytes,sizeof(bp->hashes[i])); + total += len, totalvalidated++; + } + } + free(blockspace); + bp->validated = (uint32_t)time(NULL); + printf("VALIDATED.[%d] ht.%d duration.%d errs.%d total.%lld %u | total errs.%d validated.%d %llx\n",bp->hdrsi,bp->bundleheight,bp->validated - now,errs,(long long)total,bp->validated,totalerrs,totalvalidated,(long long)validatehash.txid); + } + if ( errs == 0 && fp == 0 ) + { + if ( (fp= fopen(fname,"wb")) != 0 ) + { + if ( fwrite(&bp->validated,1,sizeof(bp->validated),fp) != sizeof(bp->validated) || fwrite(&total,1,sizeof(total),fp) != sizeof(total) || fwrite(&validatehash,1,sizeof(validatehash),fp) != sizeof(validatehash) ) + printf("error saving.(%s) total.%lld\n",fname,(long long)total); + fclose(fp); + } + } + bp->validatehash = validatehash; + } // else printf("skip validate.[%d] validated.%u force.%d\n",bp->hdrsi,bp->validated,forceflag); + if ( errs != 0 ) + { + printf("remove.[%d]\n",bp->hdrsi); + iguana_bundleremove(coin,bp->hdrsi,0); + } + return(bp->n - errs); +} diff --git a/iguana/iguana_stake.c b/iguana/iguana_stake.c new file mode 100644 index 000000000..5eedb3a84 --- /dev/null +++ b/iguana/iguana_stake.c @@ -0,0 +1,862 @@ +#ifdef reference +// modify time.1462237906 modifier.baed58b98a00e41d + +static const int64_t COIN_YEAR_REWARD = 5 * CENT; // 5% per year +int nCoinbaseMaturity = 100; +static const int STAKE_TIMESTAMP_MASK = 15; + +// MODIFIER_INTERVAL_RATIO: +// ratio of group interval length between the last group and the first group +static const int MODIFIER_INTERVAL_RATIO = 3; + +CBigNum bnProofOfStakeLimit(~uint256(0) >> 20); +CBigNum bnProofOfStakeLimitV2(~uint256(0) >> 48); + +unsigned int nTargetSpacing = 1 * 60; // BitcoinDark - 1 minute +static const int64_t nTargetTimespan = 60 * 60; // BitcoinDark - every 1 hour +unsigned int nStakeMinAge = 8 * 60 * 60; // BitcoinDark - 8 hours +unsigned int nStakeMaxAge = -1; +unsigned int nModifierInterval = 10 * 60; // BitcoinDark - time to elapse before new modifier is + +unsigned int nStakeSplitAge = 1 * 24 * 60 * 60; +int64_t nStakeCombineThreshold = 1000 * COIN; + +enum +{ + BLOCK_PROOF_OF_STAKE = (1 << 0), // is proof-of-stake block + BLOCK_STAKE_ENTROPY = (1 << 1), // entropy bit for stake modifier + BLOCK_STAKE_MODIFIER = (1 << 2), // regenerated stake modifier +}; + +uint64_t nStakeModifier; // hash modifier for proof-of-stake +unsigned int nStakeModifierChecksum; // checksum of index; in-memeory only + + +uint256 CBlockIndex::GetBlockTrust() const +{ + CBigNum bnTarget; + bnTarget.SetCompact(nBits); + + if (bnTarget <= 0) + return 0; + + return ((CBigNum(1)<<256) / (bnTarget+1)).getuint256(); +} + +unsigned int GetStakeEntropyBit() const +{ + return ((nFlags & BLOCK_STAKE_ENTROPY) >> 1); +} + +bool SetStakeEntropyBit(unsigned int nEntropyBit) +{ + if (nEntropyBit > 1) + return false; + nFlags |= (nEntropyBit? BLOCK_STAKE_ENTROPY : 0); + return true; +} + +bool GeneratedStakeModifier() const +{ + return (nFlags & BLOCK_STAKE_MODIFIER); +} + +void SetStakeModifier(uint64_t nModifier, bool fGeneratedStakeModifier) +{ + nStakeModifier = nModifier; + if (fGeneratedStakeModifier) + nFlags |= BLOCK_STAKE_MODIFIER; +} + +// miner's coin stake reward based on coin age spent (coin-days) +int64_t GetProofOfStakeReward(int64_t nCoinAge, int64_t nFees) +{ + int64_t nSubsidy = nCoinAge * COIN_YEAR_REWARD * 33 / (365 * 33 + 8); + return(nSubsidy + nFees); +} + +// +// maximum nBits value could possible be required nTime after +// +unsigned int ComputeMaxBits(CBigNum bnTargetLimit, unsigned int nBase, int64_t nTime) +{ + CBigNum bnResult; + bnResult.SetCompact(nBase); + bnResult *= 2; + while (nTime > 0 && bnResult < bnTargetLimit) + { + // Maximum 200% adjustment per day... + bnResult *= 2; + nTime -= 24 * 60 * 60; + } + if (bnResult > bnTargetLimit) + bnResult = bnTargetLimit; + return bnResult.GetCompact(); +} + +// +// minimum amount of stake that could possibly be required nTime after +// minimum proof-of-stake required was nBase +// +unsigned int ComputeMinStake(unsigned int nBase, int64_t nTime, unsigned int nBlockTime) +{ + return ComputeMaxBits(bnProofOfStakeLimit, nBase, nTime); +} + +static CBigNum GetProofOfStakeLimit(int nHeight) +{ + if(IsPoSV2(nHeight)) + return bnProofOfStakeLimitV2; + else + return bnProofOfStakeLimit; +} + +unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfStake) +{ + CBigNum bnTargetLimit = fProofOfStake ? GetProofOfStakeLimit(pindexLast->nHeight) : bnProofOfWorkLimit; + + if (pindexLast == NULL) + return bnTargetLimit.GetCompact(); // genesis block + const CBlockIndex* pindexPrev = GetLastBlockIndex(pindexLast, fProofOfStake); + if (pindexPrev->pprev == NULL) + return bnTargetLimit.GetCompact(); // first block + const CBlockIndex* pindexPrevPrev = GetLastBlockIndex(pindexPrev->pprev, fProofOfStake); + if (pindexPrevPrev->pprev == NULL) + return bnTargetLimit.GetCompact(); // second block + + int64_t nActualSpacing = pindexPrev->GetBlockTime() - pindexPrevPrev->GetBlockTime(); + if (nActualSpacing < 0) + nActualSpacing = nTargetSpacing; + + // ppcoin: target change every block + // ppcoin: retarget with exponential moving toward target spacing + CBigNum bnNew; + bnNew.SetCompact(pindexPrev->nBits); + int64_t nInterval = nTargetTimespan / nTargetSpacing; + bnNew *= ((nInterval - 1) * nTargetSpacing + nActualSpacing + nActualSpacing); + bnNew /= ((nInterval + 1) * nTargetSpacing); + + if (bnNew <= 0 || bnNew > bnTargetLimit) + bnNew = bnTargetLimit; + + return bnNew.GetCompact(); +} + +// ppcoin: total coin age spent in transaction, in the unit of coin-days. +// Only those coins meeting minimum age requirement counts. As those +// transactions not in main chain are not currently indexed so we +// might not find out about their coin age. Older transactions are +// guaranteed to be in main chain by sync-checkpoint. This rule is +// introduced to help nodes establish a consistent view of the coin +// age (trust score) of competing branches. +bool CTransaction::GetCoinAge(CTxDB& txdb, uint64_t& nCoinAge) const +{ + CBigNum bnCentSecond = 0; // coin age in the unit of cent-seconds + nCoinAge = 0; + if (IsCoinBase()) + return true; + BOOST_FOREACH(const CTxIn& txin, vin) + { + // First try finding the previous transaction in database + CTransaction txPrev; + CTxIndex txindex; + if (!txPrev.ReadFromDisk(txdb, txin.prevout, txindex)) + continue; // previous transaction not in main chain + if (nTime < txPrev.nTime) + return false; // Transaction timestamp violation + // Read block header + CBlock block; + if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false)) + return false; // unable to read block of previous transaction + if (block.GetBlockTime() + nStakeMinAge > nTime) + continue; // only count coins meeting min age requirement + + int64_t nValueIn = txPrev.vout[txin.prevout.n].nValue; + bnCentSecond += CBigNum(nValueIn) * (nTime-txPrev.nTime) / CENT; + + if (fDebug && GetBoolArg("-printcoinage")) + printf("coin age nValueIn=%"PRId64" nTimeDiff=%d bnCentSecond=%s\n", nValueIn, nTime - txPrev.nTime, bnCentSecond.ToString().c_str()); + } + CBigNum bnCoinDay = bnCentSecond * CENT / COIN / (24 * 60 * 60); + if (fDebug && GetBoolArg("-printcoinage")) + printf("coin age bnCoinDay=%s\n", bnCoinDay.ToString().c_str()); + nCoinAge = bnCoinDay.getuint64(); + return true; +} + +// ppcoin: total coin age spent in block, in the unit of coin-days. +bool CBlock::GetCoinAge(uint64_t& nCoinAge) const +{ + nCoinAge = 0; + + CTxDB txdb("r"); + BOOST_FOREACH(const CTransaction& tx, vtx) + { + uint64_t nTxCoinAge; + if (tx.GetCoinAge(txdb, nTxCoinAge)) + nCoinAge += nTxCoinAge; + else + return false; + } + if (nCoinAge == 0) // block coin age minimum 1 coin-day + nCoinAge = 1; + if (fDebug && GetBoolArg("-printcoinage")) + printf("block coin age total nCoinDays=%"PRId64"\n", nCoinAge); + return true; +} + +// Get time weight +int64_t GetWeight(int64_t nIntervalBeginning, int64_t nIntervalEnd) +{ + // Kernel hash weight starts from 0 at the min age + // this change increases active coins participating the hash and helps + // to secure the network when proof-of-stake difficulty is low + + return min(nIntervalEnd - nIntervalBeginning - nStakeMinAge, (int64_t)nStakeMaxAge); +} + +// Get the last stake modifier and its generation time from a given block +static bool GetLastStakeModifier(const CBlockIndex* pindex, uint64_t& nStakeModifier, int64_t& nModifierTime) +{ + if (!pindex) + return error("GetLastStakeModifier: null pindex"); + while (pindex && pindex->pprev && !pindex->GeneratedStakeModifier()) + pindex = pindex->pprev; + if (!pindex->GeneratedStakeModifier()) + return error("GetLastStakeModifier: no generation at genesis block"); + nStakeModifier = pindex->nStakeModifier; + nModifierTime = pindex->GetBlockTime(); + return true; +} + +// Get selection interval section (in seconds) +static int64_t GetStakeModifierSelectionIntervalSection(int nSection) +{ + assert (nSection >= 0 && nSection < 64); + return (nModifierInterval * 63 / (63 + ((63 - nSection) * (MODIFIER_INTERVAL_RATIO - 1)))); +} + +// Get stake modifier selection interval (in seconds) +static int64_t GetStakeModifierSelectionInterval() +{ + int64_t nSelectionInterval = 0; + for (int nSection=0; nSection<64; nSection++) + nSelectionInterval += GetStakeModifierSelectionIntervalSection(nSection); + return nSelectionInterval; +} + +// select a block from the candidate blocks in vSortedByTimestamp, excluding +// already selected blocks in vSelectedBlocks, and with timestamp up to +// nSelectionIntervalStop. +static bool SelectBlockFromCandidates(vector >& vSortedByTimestamp, map& mapSelectedBlocks, + int64_t nSelectionIntervalStop, uint64_t nStakeModifierPrev, const CBlockIndex** pindexSelected) +{ + bool fSelected = false; + uint256 hashBest = 0; + *pindexSelected = (const CBlockIndex*) 0; + BOOST_FOREACH(const PAIRTYPE(int64_t, uint256)& item, vSortedByTimestamp) + { + if (!mapBlockIndex.count(item.second)) + return error("SelectBlockFromCandidates: failed to find block index for candidate block %s", item.second.ToString().c_str()); + const CBlockIndex* pindex = mapBlockIndex[item.second]; + if (fSelected && pindex->GetBlockTime() > nSelectionIntervalStop) + break; + if (mapSelectedBlocks.count(pindex->GetBlockHash()) > 0) + continue; + // compute the selection hash by hashing its proof-hash and the + // previous proof-of-stake modifier + CDataStream ss(SER_GETHASH, 0); + ss << pindex->hashProof << nStakeModifierPrev; + uint256 hashSelection = Hash(ss.begin(), ss.end()); + // the selection hash is divided by 2**32 so that proof-of-stake block + // is always favored over proof-of-work block. this is to preserve + // the energy efficiency property + if (pindex->IsProofOfStake()) + hashSelection >>= 32; + if (fSelected && hashSelection < hashBest) + { + hashBest = hashSelection; + *pindexSelected = (const CBlockIndex*) pindex; + } + else if (!fSelected) + { + fSelected = true; + hashBest = hashSelection; + *pindexSelected = (const CBlockIndex*) pindex; + } + } + if (fDebug && GetBoolArg("-printstakemodifier")) + printf("SelectBlockFromCandidates: selection hash=%s\n", hashBest.ToString().c_str()); + return fSelected; +} + +// Stake Modifier (hash modifier of proof-of-stake): +// The purpose of stake modifier is to prevent a txout (coin) owner from +// computing future proof-of-stake generated by this txout at the time +// of transaction confirmation. To meet kernel protocol, the txout +// must hash with a future stake modifier to generate the proof. +// Stake modifier consists of bits each of which is contributed from a +// selected block of a given block group in the past. +// The selection of a block is based on a hash of the block's proof-hash and +// the previous stake modifier. +// Stake modifier is recomputed at a fixed time interval instead of every +// block. This is to make it difficult for an attacker to gain control of +// additional bits in the stake modifier, even after generating a chain of +// blocks. +bool ComputeNextStakeModifier(const CBlockIndex* pindexPrev, uint64_t& nStakeModifier, bool& fGeneratedStakeModifier) +{ + nStakeModifier = 0; + fGeneratedStakeModifier = false; + if (!pindexPrev) + { + fGeneratedStakeModifier = true; + return true; // genesis block's modifier is 0 + } + // First find current stake modifier and its generation block time + // if it's not old enough, return the same stake modifier + int64_t nModifierTime = 0; + if (!GetLastStakeModifier(pindexPrev, nStakeModifier, nModifierTime)) + return error("ComputeNextStakeModifier: unable to get last modifier"); + if (fDebug) + { + printf("ComputeNextStakeModifier: prev modifier=0x%016"PRIx64" time=%s\n", nStakeModifier, DateTimeStrFormat(nModifierTime).c_str()); + } + if (nModifierTime / nModifierInterval >= pindexPrev->GetBlockTime() / nModifierInterval) + return true; + + // Sort candidate blocks by timestamp + vector > vSortedByTimestamp; + vSortedByTimestamp.reserve(64 * nModifierInterval / nTargetSpacing); + int64_t nSelectionInterval = GetStakeModifierSelectionInterval(); + int64_t nSelectionIntervalStart = (pindexPrev->GetBlockTime() / nModifierInterval) * nModifierInterval - nSelectionInterval; + const CBlockIndex* pindex = pindexPrev; + while (pindex && pindex->GetBlockTime() >= nSelectionIntervalStart) + { + vSortedByTimestamp.push_back(make_pair(pindex->GetBlockTime(), pindex->GetBlockHash())); + pindex = pindex->pprev; + } + int nHeightFirstCandidate = pindex ? (pindex->nHeight + 1) : 0; + reverse(vSortedByTimestamp.begin(), vSortedByTimestamp.end()); + sort(vSortedByTimestamp.begin(), vSortedByTimestamp.end()); + + // Select 64 blocks from candidate blocks to generate stake modifier + uint64_t nStakeModifierNew = 0; + int64_t nSelectionIntervalStop = nSelectionIntervalStart; + map mapSelectedBlocks; + for (int nRound=0; nRoundGetStakeEntropyBit()) << nRound); + // add the selected block from candidates to selected list + mapSelectedBlocks.insert(make_pair(pindex->GetBlockHash(), pindex)); + if (fDebug && GetBoolArg("-printstakemodifier")) + printf("ComputeNextStakeModifier: selected round %d stop=%s height=%d bit=%d\n", nRound, DateTimeStrFormat(nSelectionIntervalStop).c_str(), pindex->nHeight, pindex->GetStakeEntropyBit()); + } + + // Print selection map for visualization of the selected blocks + if (fDebug && GetBoolArg("-printstakemodifier")) + { + string strSelectionMap = ""; + // '-' indicates proof-of-work blocks not selected + strSelectionMap.insert(0, pindexPrev->nHeight - nHeightFirstCandidate + 1, '-'); + pindex = pindexPrev; + while (pindex && pindex->nHeight >= nHeightFirstCandidate) + { + // '=' indicates proof-of-stake blocks not selected + if (pindex->IsProofOfStake()) + strSelectionMap.replace(pindex->nHeight - nHeightFirstCandidate, 1, "="); + pindex = pindex->pprev; + } + BOOST_FOREACH(const PAIRTYPE(uint256, const CBlockIndex*)& item, mapSelectedBlocks) + { + // 'S' indicates selected proof-of-stake blocks + // 'W' indicates selected proof-of-work blocks + strSelectionMap.replace(item.second->nHeight - nHeightFirstCandidate, 1, item.second->IsProofOfStake()? "S" : "W"); + } + printf("ComputeNextStakeModifier: selection height [%d, %d] map %s\n", nHeightFirstCandidate, pindexPrev->nHeight, strSelectionMap.c_str()); + } + if (fDebug) + { + printf("ComputeNextStakeModifier: new modifier=0x%016"PRIx64" time=%s\n", nStakeModifierNew, DateTimeStrFormat(pindexPrev->GetBlockTime()).c_str()); + } + + nStakeModifier = nStakeModifierNew; + fGeneratedStakeModifier = true; + return true; +} + +// The stake modifier used to hash for a stake kernel is chosen as the stake +// modifier about a selection interval later than the coin generating the kernel +static bool GetKernelStakeModifier(uint256 hashBlockFrom, uint64_t& nStakeModifier, int& nStakeModifierHeight, int64_t& nStakeModifierTime, bool fPrintProofOfStake) +{ + nStakeModifier = 0; + if (!mapBlockIndex.count(hashBlockFrom)) + return error("GetKernelStakeModifier() : block not indexed"); + const CBlockIndex* pindexFrom = mapBlockIndex[hashBlockFrom]; + nStakeModifierHeight = pindexFrom->nHeight; + nStakeModifierTime = pindexFrom->GetBlockTime(); + int64_t nStakeModifierSelectionInterval = GetStakeModifierSelectionInterval(); + const CBlockIndex* pindex = pindexFrom; + // loop to find the stake modifier later by a selection interval + while (nStakeModifierTime < pindexFrom->GetBlockTime() + nStakeModifierSelectionInterval) + { + if (!pindex->pnext) + { // reached best block; may happen if node is behind on block chain + if (fPrintProofOfStake || (pindex->GetBlockTime() + nStakeMinAge - nStakeModifierSelectionInterval > GetAdjustedTime())) + return error("GetKernelStakeModifier() : reached best block %s at height %d from block %s", + pindex->GetBlockHash().ToString().c_str(), pindex->nHeight, hashBlockFrom.ToString().c_str()); + else + return false; + } + pindex = pindex->pnext; + if (pindex->GeneratedStakeModifier()) + { + nStakeModifierHeight = pindex->nHeight; + nStakeModifierTime = pindex->GetBlockTime(); + } + } + nStakeModifier = pindex->nStakeModifier; + return true; +} + +// ppcoin kernel protocol +// coinstake must meet hash target according to the protocol: +// kernel (input 0) must meet the formula +// hash(nStakeModifier + txPrev.block.nTime + txPrev.offset + txPrev.nTime + txPrev.vout.n + nTime) < bnTarget * nCoinDayWeight +// this ensures that the chance of getting a coinstake is proportional to the +// amount of coin age one owns. +// The reason this hash is chosen is the following: +// nStakeModifier: scrambles computation to make it very difficult to precompute +// future proof-of-stake at the time of the coin's confirmation +// txPrev.block.nTime: prevent nodes from guessing a good timestamp to +// generate transaction for future advantage +// txPrev.offset: offset of txPrev inside block, to reduce the chance of +// nodes generating coinstake at the same time +// txPrev.nTime: reduce the chance of nodes generating coinstake at the same +// time +// txPrev.vout.n: output number of txPrev, to reduce the chance of nodes +// generating coinstake at the same time +// block/tx hash should not be used here as they can be generated in vast +// quantities so as to generate blocks faster, degrading the system back into +// a proof-of-work situation. +// +bool CheckStakeKernelHashV1(unsigned int nBits, const CBlock& blockFrom, unsigned int nTxPrevOffset, const CTransaction& txPrev, const COutPoint& prevout, unsigned int nTimeTx, uint256& hashProofOfStake, uint256& targetProofOfStake, bool fPrintProofOfStake) +{ + if (nTimeTx < txPrev.nTime) // Transaction timestamp violation + return error("CheckStakeKernelHash() : nTime violation"); + + unsigned int nTimeBlockFrom = blockFrom.GetBlockTime(); + if (nTimeBlockFrom + nStakeMinAge > nTimeTx) // Min age requirement + return error("CheckStakeKernelHash() : min age violation"); + + CBigNum bnTargetPerCoinDay; + bnTargetPerCoinDay.SetCompact(nBits); + int64_t nValueIn = txPrev.vout[prevout.n].nValue; + + uint256 hashBlockFrom = blockFrom.GetHash(); + + CBigNum bnCoinDayWeight = CBigNum(nValueIn) * GetWeight((int64_t)txPrev.nTime, (int64_t)nTimeTx) / COIN / (24 * 60 * 60); + targetProofOfStake = (bnCoinDayWeight * bnTargetPerCoinDay).getuint256(); + + // Calculate hash + CDataStream ss(SER_GETHASH, 0); + uint64_t nStakeModifier = 0; + int nStakeModifierHeight = 0; + int64_t nStakeModifierTime = 0; + + if ( !GetKernelStakeModifier(hashBlockFrom, nStakeModifier, nStakeModifierHeight, nStakeModifierTime, fPrintProofOfStake) ) + return false; + ss << nStakeModifier << nTimeBlockFrom << nTxPrevOffset << txPrev.nTime << prevout.n << nTimeTx; + hashProofOfStake = Hash(ss.begin(), ss.end()); + if (fPrintProofOfStake) + { + printf("CheckStakeKernelHash() : using modifier 0x%016"PRIx64" at height=%d timestamp=%s for block from height=%d timestamp=%s\n", + nStakeModifier, nStakeModifierHeight, + DateTimeStrFormat(nStakeModifierTime).c_str(), + mapBlockIndex[hashBlockFrom]->nHeight, + DateTimeStrFormat(blockFrom.GetBlockTime()).c_str()); + printf("CheckStakeKernelHash() : check modifier=0x%016"PRIx64" nTimeBlockFrom=%u nTxPrevOffset=%u nTimeTxPrev=%u nPrevout=%u nTimeTx=%u hashProof=%s\n", + nStakeModifier, + nTimeBlockFrom, nTxPrevOffset, txPrev.nTime, prevout.n, nTimeTx, + hashProofOfStake.ToString().c_str()); + } + + // Now check if proof-of-stake hash meets target protocol + if (CBigNum(hashProofOfStake) > bnCoinDayWeight * bnTargetPerCoinDay) + return false; + if (fDebug && !fPrintProofOfStake) + { + printf("CheckStakeKernelHash() : using modifier 0x%016"PRIx64" at height=%d timestamp=%s for block from height=%d timestamp=%s\n", + nStakeModifier, nStakeModifierHeight, + DateTimeStrFormat(nStakeModifierTime).c_str(), + mapBlockIndex[hashBlockFrom]->nHeight, + DateTimeStrFormat(blockFrom.GetBlockTime()).c_str()); + printf("CheckStakeKernelHash() : pass modifier=0x%016"PRIx64" nTimeBlockFrom=%u nTxPrevOffset=%u nTimeTxPrev=%u nPrevout=%u nTimeTx=%u hashProof=%s\n", + nStakeModifier, + nTimeBlockFrom, nTxPrevOffset, txPrev.nTime, prevout.n, nTimeTx, + hashProofOfStake.ToString().c_str()); + } + return true; +} + +bool CheckStakeKernelHash(CBlockIndex* pindexPrev, unsigned int nBits, const CBlock& blockFrom, unsigned int nTxPrevOffset, const CTransaction& txPrev, const COutPoint& prevout, unsigned int nTimeTx, uint256& hashProofOfStake, uint256& targetProofOfStake, bool fPrintProofOfStake) +{ + if (IsPoSV2(pindexPrev->nHeight+1)) + return CheckStakeKernelHashV2(pindexPrev, nBits, blockFrom.GetBlockTime(), txPrev, prevout, nTimeTx, hashProofOfStake, targetProofOfStake, fPrintProofOfStake); + else + return CheckStakeKernelHashV1(nBits, blockFrom, nTxPrevOffset, txPrev, prevout, nTimeTx, hashProofOfStake, targetProofOfStake, fPrintProofOfStake); +} + +bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int64_t nSearchInterval, int64_t nFees, CTransaction& txNew, CKey& key) +{ + CBlockIndex* pindexPrev = pindexBest; + CBigNum bnTargetPerCoinDay; + bnTargetPerCoinDay.SetCompact(nBits); + + txNew.vin.clear(); + txNew.vout.clear(); + + // Mark coin stake transaction + CScript scriptEmpty; + scriptEmpty.clear(); + txNew.vout.push_back(CTxOut(0, scriptEmpty)); + + // Choose coins to use + int64_t nBalance = GetBalance(); + + if (nBalance <= nReserveBalance) + return false; + + vector vwtxPrev; + + set > setCoins; + int64_t nValueIn = 0; + + // Select coins with suitable depth + if (!SelectCoinsSimple(nBalance - nReserveBalance, txNew.nTime, nCoinbaseMaturity + 10, setCoins, nValueIn)) + return false; + + if (setCoins.empty()) + return false; + + int64_t nCredit = 0; + CScript scriptPubKeyKernel; + CTxDB txdb("r"); + BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins) + { + CTxIndex txindex; + { + LOCK2(cs_main, cs_wallet); + if (!txdb.ReadTxIndex(pcoin.first->GetHash(), txindex)) + continue; + } + + // Read block header + CBlock block; + { + LOCK2(cs_main, cs_wallet); + if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false)) + continue; + } + + static int nMaxStakeSearchInterval = 60; + if (block.GetBlockTime() + nStakeMinAge > txNew.nTime - nMaxStakeSearchInterval) + continue; // only count coins meeting min age requirement + + bool fKernelFound = false; + for (unsigned int n=0; nGetHash(), pcoin.second); + if (CheckStakeKernelHash(pindexPrev, nBits, block, txindex.pos.nTxPos - txindex.pos.nBlockPos, *pcoin.first, prevoutStake, txNew.nTime - n, hashProofOfStake, targetProofOfStake)) + { + // Found a kernel + if (fDebug && GetBoolArg("-printcoinstake")) + printf("CreateCoinStake : kernel found\n"); + vector vSolutions; + txnouttype whichType; + CScript scriptPubKeyOut; + scriptPubKeyKernel = pcoin.first->vout[pcoin.second].scriptPubKey; + if (!Solver(scriptPubKeyKernel, whichType, vSolutions)) + { + if (fDebug && GetBoolArg("-printcoinstake")) + printf("CreateCoinStake : failed to parse kernel\n"); + break; + } + if (fDebug && GetBoolArg("-printcoinstake")) + printf("CreateCoinStake : parsed kernel type=%d\n", whichType); + if (whichType != TX_PUBKEY && whichType != TX_PUBKEYHASH) + { + if (fDebug && GetBoolArg("-printcoinstake")) + printf("CreateCoinStake : no support for kernel type=%d\n", whichType); + break; // only support pay to public key and pay to address + } + if (whichType == TX_PUBKEYHASH) // pay to address type + { + // convert to pay to public key type + if (!keystore.GetKey(uint160(vSolutions[0]), key)) + { + if (fDebug && GetBoolArg("-printcoinstake")) + printf("CreateCoinStake : failed to get key for kernel type=%d\n", whichType); + break; // unable to find corresponding public key + } + scriptPubKeyOut << key.GetPubKey() << OP_CHECKSIG; + } + if (whichType == TX_PUBKEY) + { + valtype& vchPubKey = vSolutions[0]; + if (!keystore.GetKey(Hash160(vchPubKey), key)) + { + if (fDebug && GetBoolArg("-printcoinstake")) + printf("CreateCoinStake : failed to get key for kernel type=%d\n", whichType); + break; // unable to find corresponding public key + } + + if (key.GetPubKey() != vchPubKey) + { + if (fDebug && GetBoolArg("-printcoinstake")) + printf("CreateCoinStake : invalid key for kernel type=%d\n", whichType); + break; // keys mismatch + } + + scriptPubKeyOut = scriptPubKeyKernel; + } + + txNew.nTime -= n; + txNew.vin.push_back(CTxIn(pcoin.first->GetHash(), pcoin.second)); + nCredit += pcoin.first->vout[pcoin.second].nValue; + vwtxPrev.push_back(pcoin.first); + txNew.vout.push_back(CTxOut(0, scriptPubKeyOut)); + + if (GetWeight(block.GetBlockTime(), (int64_t)txNew.nTime) < nStakeSplitAge) + txNew.vout.push_back(CTxOut(0, scriptPubKeyOut)); //split stake + if (fDebug && GetBoolArg("-printcoinstake")) + printf("CreateCoinStake : added kernel type=%d\n", whichType); + fKernelFound = true; + break; + } + } + + if (fKernelFound || fShutdown) + break; // if kernel is found stop searching + } + + if (nCredit == 0 || nCredit > nBalance - nReserveBalance) + return false; + + BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins) + { + // Attempt to add more inputs + // Only add coins of the same key/address as kernel + if (txNew.vout.size() == 2 && ((pcoin.first->vout[pcoin.second].scriptPubKey == scriptPubKeyKernel || pcoin.first->vout[pcoin.second].scriptPubKey == txNew.vout[1].scriptPubKey)) + && pcoin.first->GetHash() != txNew.vin[0].prevout.hash) + { + int64_t nTimeWeight = GetWeight((int64_t)pcoin.first->nTime, (int64_t)txNew.nTime); + + // Stop adding more inputs if already too many inputs + if (txNew.vin.size() >= 100) + break; + // Stop adding more inputs if value is already pretty significant + if (nCredit >= nStakeCombineThreshold) + break; + // Stop adding inputs if reached reserve limit + if (nCredit + pcoin.first->vout[pcoin.second].nValue > nBalance - nReserveBalance) + break; + // Do not add additional significant input + if (pcoin.first->vout[pcoin.second].nValue >= nStakeCombineThreshold) + continue; + // Do not add input that is still too young + if (nTimeWeight < nStakeMinAge) + continue; + + txNew.vin.push_back(CTxIn(pcoin.first->GetHash(), pcoin.second)); + nCredit += pcoin.first->vout[pcoin.second].nValue; + vwtxPrev.push_back(pcoin.first); + } + } + + // Calculate coin age reward + { + uint64_t nCoinAge; + CTxDB txdb("r"); + if (!txNew.GetCoinAge(txdb, nCoinAge)) + return error("CreateCoinStake : failed to calculate coin age"); + + int64_t nReward = GetProofOfStakeReward(nCoinAge, nFees); + if (nReward <= 0) + return false; + + nCredit += nReward; + } + + // Set output amount + if (txNew.vout.size() == 3) + { + txNew.vout[1].nValue = (nCredit / 2 / CENT) * CENT; + txNew.vout[2].nValue = nCredit - txNew.vout[1].nValue; + } + else + txNew.vout[1].nValue = nCredit; + + // Sign + int nIn = 0; + BOOST_FOREACH(const CWalletTx* pcoin, vwtxPrev) + { + if (!SignSignature(*this, *pcoin, txNew, nIn++)) + return error("CreateCoinStake : failed to sign coinstake"); + } + + // Limit size + unsigned int nBytes = ::GetSerializeSize(txNew, SER_NETWORK, PROTOCOL_VERSION); + if (nBytes >= MAX_BLOCK_SIZE_GEN/5) + return error("CreateCoinStake : exceeded coinstake size limit"); + + // Successfully generated coinstake + return true; +} + +// Check kernel hash target and coinstake signature +bool CheckProofOfStake(CBlockIndex* pindexPrev, const CTransaction& tx, unsigned int nBits, uint256& hashProofOfStake, uint256& targetProofOfStake) +{ + if (!tx.IsCoinStake()) + return error("CheckProofOfStake() : called on non-coinstake %s", tx.GetHash().ToString().c_str()); + + // Kernel (input 0) must match the stake hash target per coin age (nBits) + const CTxIn& txin = tx.vin[0]; + + // First try finding the previous transaction in database + CTxDB txdb("r"); + CTransaction txPrev; + CTxIndex txindex; + if (!txPrev.ReadFromDisk(txdb, txin.prevout, txindex)) + return tx.DoS(1, error("CheckProofOfStake() : INFO: read txPrev failed")); // previous transaction not in main chain, may occur during initial download + + // Verify signature + if (!VerifySignature(txPrev, tx, 0, 0)) + return tx.DoS(100, error("CheckProofOfStake() : VerifySignature failed on coinstake %s", tx.GetHash().ToString().c_str())); + + // Read block header + CBlock block; + if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false)) + return fDebug? error("CheckProofOfStake() : read block failed") : false; // unable to read block of previous transaction + + if (!CheckStakeKernelHash(pindexPrev, nBits, block, txindex.pos.nTxPos - txindex.pos.nBlockPos, txPrev, txin.prevout, tx.nTime, hashProofOfStake, targetProofOfStake, fDebug)) + return tx.DoS(1, error("CheckProofOfStake() : INFO: check kernel failed on coinstake %s, hashProof=%s", tx.GetHash().ToString().c_str(), hashProofOfStake.ToString().c_str())); // may occur during initial download or if behind on block chain sync + + return true; +} + +// Check whether the coinstake timestamp meets protocol +bool CheckCoinStakeTimestamp(int64_t nTimeBlock, int64_t nTimeTx) +{ + // v0.3 protocol + return (nTimeBlock == nTimeTx); +} + +// Get stake modifier checksum +unsigned int GetStakeModifierChecksum(const CBlockIndex* pindex) +{ + //assert (pindex->pprev || pindex->GetBlockHash() == (!fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet)); + // Hash previous checksum with flags, hashProofOfStake and nStakeModifier + CDataStream ss(SER_GETHASH, 0); + if (pindex->pprev) + ss << pindex->pprev->nStakeModifierChecksum; + ss << pindex->nFlags << (pindex->IsProofOfStake() ? pindex->hashProof : 0) << pindex->nStakeModifier; + uint256 hashChecksum = Hash(ss.begin(), ss.end()); + hashChecksum >>= (256 - 32); + return hashChecksum.Get64(); +} + +// Check stake modifier hard checkpoints +bool CheckStakeModifierCheckpoints(int nHeight, unsigned int nStakeModifierChecksum) +{ + MapModifierCheckpoints& checkpoints = (fTestNet ? mapStakeModifierCheckpointsTestNet : mapStakeModifierCheckpoints); + + if (checkpoints.count(nHeight)) + return nStakeModifierChecksum == checkpoints[nHeight]; + return true; +} +// novacoin: attempt to generate suitable proof-of-stake +bool CBlock::SignBlock(CWallet& wallet, int64_t nFees) +{ + // if we are trying to sign + // something except proof-of-stake block template + if (!vtx[0].vout[0].IsEmpty()) + return false; + + // if we are trying to sign + // a complete proof-of-stake block + if (IsProofOfStake()) + return true; + + static int64_t nLastCoinStakeSearchTime = GetAdjustedTime(); // startup timestamp + + CKey key; + CTransaction txCoinStake; + int64_t nSearchTime = txCoinStake.nTime; // search to current time + + if (nSearchTime > nLastCoinStakeSearchTime) + { + if (wallet.CreateCoinStake(wallet, nBits, nSearchTime-nLastCoinStakeSearchTime, nFees, txCoinStake, key)) + { + if (txCoinStake.nTime >= max(pindexBest->GetPastTimeLimit()+1, PastDrift(pindexBest->GetBlockTime()))) + { + // make sure coinstake would meet timestamp protocol + // as it would be the same as the block timestamp + vtx[0].nTime = nTime = txCoinStake.nTime; + nTime = max(pindexBest->GetPastTimeLimit()+1, GetMaxTransactionTime()); + nTime = max(GetBlockTime(), PastDrift(pindexBest->GetBlockTime())); + // we have to make sure that we have no future timestamps in + // our transactions set + for (vector::iterator it = vtx.begin(); it != vtx.end();) + if (it->nTime > nTime) { it = vtx.erase(it); } else { ++it; } + + vtx.insert(vtx.begin() + 1, txCoinStake); + hashMerkleRoot = BuildMerkleTree(); + + // append a signature to our block + return key.Sign(GetHash(), vchBlockSig); + } + } + nLastCoinStakeSearchInterval = nSearchTime - nLastCoinStakeSearchTime; + nLastCoinStakeSearchTime = nSearchTime; + } + + return false; +} + +bool CBlock::CheckBlockSignature() const +{ + if (IsProofOfWork()) + return vchBlockSig.empty(); + + vector vSolutions; + txnouttype whichType; + + const CTxOut& txout = vtx[1].vout[1]; + + if (!Solver(txout.scriptPubKey, whichType, vSolutions)) + return false; + + if (whichType == TX_PUBKEY) + { + valtype& vchPubKey = vSolutions[0]; + CKey key; + if (!key.SetPubKey(vchPubKey)) + return false; + if (vchBlockSig.empty()) + return false; + return key.Verify(GetHash(), vchBlockSig); + } + + return false; +} + +#endif diff --git a/iguana/iguana_tx.c b/iguana/iguana_tx.c index edf4ed131..bf426d26e 100755 --- a/iguana/iguana_tx.c +++ b/iguana/iguana_tx.c @@ -22,46 +22,121 @@ //struct iguana_spend { uint32_t spendtxidind; int16_t prevout; uint16_t tbd:14,external:1,diffsequence:1; } __attribute__((packed)); -void iguana_vinset(struct iguana_info *coin,int32_t height,struct iguana_msgvin *vin,struct iguana_txid *tx,int32_t i) +int32_t iguana_scriptdata(struct iguana_info *coin,uint8_t *scriptspace,long fileptr[2],char *fname,uint64_t scriptpos,int32_t scriptlen) { - struct iguana_spend *s,*S; uint32_t spendind; struct iguana_bundle *bp; - struct iguana_ramchaindata *rdata; struct iguana_txid *T; bits256 *X; + FILE *fp; long err; int32_t retval = scriptlen; +#ifndef __PNACL__ + if ( scriptpos < 0xffffffff ) + { + if ( fileptr[0] == 0 ) + fileptr[0] = (long)OS_mapfile(fname,&fileptr[1],0); + if ( fileptr[0] != 0 ) + { + if ( (scriptpos + scriptlen) <= fileptr[1] ) + { + memcpy(scriptspace,(void *)(fileptr[0] + (uint32_t)scriptpos),scriptlen); + return(retval); + } + else if ( 0 ) + { + printf("munmap (%s)\n",fname); + munmap((void *)fileptr[0],fileptr[1]); + fileptr[0] = fileptr[1] = 0; + } + } + } +#else + static portable_mutex_t mutex; + portable_mutex_lock(&mutex); +#endif + if ( (fp= fopen(fname,"rb")) != 0 ) + { + fseek(fp,scriptpos,SEEK_SET); + if ( (err= fread(scriptspace,1,scriptlen,fp)) != scriptlen ) + { + retval = -1; + printf("%s script[%d] offset.%llu err.%ld\n",fname,scriptlen,(long long)scriptpos,err); + } //else printf("%s script[%d] offset.%llu read.%ld\n",fname,scriptlen,(long long)scriptpos,err); + fclose(fp); + } else retval = -1; +#ifdef __PNACL__ + portable_mutex_unlock(&mutex); +#endif + return(retval); +} + +int32_t iguana_vinset(struct iguana_info *coin,uint8_t *scriptspace,int32_t height,struct iguana_msgvin *vin,struct iguana_txid *tx,int32_t i) +{ + struct iguana_spend *s,*S; uint32_t spendind,unspentind; bits256 *X; struct iguana_bundle *bp; + struct iguana_ramchaindata *rdata; struct iguana_txid *T; char fname[1024]; int32_t scriptlen,err = 0; memset(vin,0,sizeof(*vin)); if ( height >= 0 && height < coin->chain->bundlesize*coin->bundlescount && (bp= coin->bundles[height / coin->chain->bundlesize]) != 0 && (rdata= bp->ramchain.H.data) != 0 ) { - S = (void *)(long)((long)rdata + rdata->Soffset); - X = (void *)(long)((long)rdata + rdata->Xoffset); - T = (void *)(long)((long)rdata + rdata->Toffset); + S = RAMCHAIN_PTR(rdata,Soffset); + X = RAMCHAIN_PTR(rdata,Xoffset); + T = RAMCHAIN_PTR(rdata,Toffset); + //S = (void *)(long)((long)rdata + rdata->Soffset); + //X = (void *)(long)((long)rdata + rdata->Xoffset); + //T = (void *)(long)((long)rdata + rdata->Toffset); spendind = (tx->firstvin + i); s = &S[spendind]; - if ( s->diffsequence == 0 ) - vin->sequence = 0xffffffff; + vin->sequence = s->sequenceid; vin->prev_vout = s->prevout; - iguana_ramchain_spendtxid(coin,&vin->prev_hash,T,rdata->numtxids,X,rdata->numexternaltxids,s); + if ( s->scriptpos != 0 && s->scriptlen > 0 ) + { + iguana_vinsfname(coin,bp->ramchain.from_ro,fname,s->fileid); + if ( (scriptlen= iguana_scriptdata(coin,scriptspace,coin->peers.vinptrs[s->fileid],fname,s->scriptpos,s->scriptlen)) != s->scriptlen ) + printf("err.%d getting %d bytes from fileid.%llu[%d] %s for s%d\n",err,s->scriptlen,(long long)s->scriptpos,s->fileid,fname,spendind); + } + vin->scriptlen = s->scriptlen; + vin->vinscript = scriptspace; + iguana_ramchain_spendtxid(coin,&unspentind,&vin->prev_hash,T,rdata->numtxids,X,rdata->numexternaltxids,s); } + if ( err != 0 ) + return(-err); + else return(vin->scriptlen); +} + +int32_t iguana_voutscript(struct iguana_info *coin,struct iguana_bundle *bp,uint8_t *scriptspace,char *asmstr,struct iguana_unspent *u,struct iguana_pkhash *p,int32_t txi) +{ + struct vin_info V; char fname[1024],coinaddr[65]; int32_t scriptlen = -1; + if ( u->scriptpos > 0 && u->scriptlen > 0 ) + { + iguana_voutsfname(coin,bp->ramchain.from_ro,fname,u->fileid); + if ( (scriptlen= iguana_scriptdata(coin,scriptspace,coin->peers.voutptrs[u->fileid],fname,u->scriptpos,u->scriptlen)) != u->scriptlen ) + printf("%d bytes from fileid.%d[%d] %s for type.%d\n",u->scriptlen,u->fileid,u->scriptpos,fname,u->type); + } + else + { + memset(&V,0,sizeof(V)); + scriptlen = iguana_scriptgen(coin,&V.M,&V.N,coinaddr,scriptspace,asmstr,p->rmd160,u->type,(const struct vin_info *)&V,txi); + } + return(scriptlen); } int32_t iguana_voutset(struct iguana_info *coin,uint8_t *scriptspace,char *asmstr,int32_t height,struct iguana_msgvout *vout,struct iguana_txid *tx,int32_t i) { struct iguana_ramchaindata *rdata; uint32_t unspentind,scriptlen = 0; struct iguana_bundle *bp; - struct iguana_unspent *u,*U; char coinaddr[65]; struct iguana_pkhash *P,*p; struct vin_info V; + struct iguana_unspent *u,*U; struct iguana_pkhash *P; int32_t err = 0; memset(vout,0,sizeof(*vout)); if ( height >= 0 && height < coin->chain->bundlesize*coin->bundlescount && (bp= coin->bundles[height / coin->chain->bundlesize]) != 0 && (rdata= bp->ramchain.H.data) != 0 && i < tx->numvouts ) { - U = (void *)(long)((long)rdata + rdata->Uoffset); - P = (void *)(long)((long)rdata + rdata->Poffset); + U = RAMCHAIN_PTR(rdata,Uoffset); + P = RAMCHAIN_PTR(rdata,Poffset); + //U = (void *)(long)((long)rdata + rdata->Uoffset); + //P = (void *)(long)((long)rdata + rdata->Poffset); unspentind = (tx->firstvout + i); u = &U[unspentind]; if ( u->txidind != tx->txidind || u->vout != i || u->hdrsi != height / coin->chain->bundlesize ) printf("iguana_voutset: txidind mismatch %d vs %d || %d vs %d || (%d vs %d)\n",u->txidind,u->txidind,u->vout,i,u->hdrsi,height / coin->chain->bundlesize); - p = &P[u->pkind]; vout->value = u->value; vout->pk_script = scriptspace; - memset(&V,0,sizeof(V)); - scriptlen = iguana_scriptgen(coin,&V.M,&V.N,coinaddr,scriptspace,asmstr,p->rmd160,u->type,(const struct vin_info *)&V,i); - } + scriptlen = iguana_voutscript(coin,bp,scriptspace,asmstr,u,&P[u->pkind],i); + } else printf("iguana_voutset unexpected path\n"); vout->pk_scriptlen = scriptlen; - return(scriptlen); + if ( err != 0 ) + return(-err); + else return(scriptlen); } struct iguana_txid *iguana_blocktx(struct iguana_info *coin,struct iguana_txid *tx,struct iguana_block *block,int32_t i) @@ -69,33 +144,158 @@ struct iguana_txid *iguana_blocktx(struct iguana_info *coin,struct iguana_txid * struct iguana_bundle *bp; uint32_t txidind; if ( i >= 0 && i < block->RO.txn_count ) { - if ( block->height >= 0 ) // + if ( block->height >= 0 ) { if ( (bp= coin->bundles[block->hdrsi]) != 0 ) { - if ( (txidind= block->RO.firsttxidind) > 0 )//bp->firsttxidinds[block->bundlei]) > 0 ) + if ( (txidind= block->RO.firsttxidind) > 0 ) { if ( iguana_bundletx(coin,bp,block->bundlei,tx,txidind+i) == tx ) return(tx); printf("error getting txidind.%d + i.%d from hdrsi.%d\n",txidind,i,block->hdrsi); return(0); - } else printf("iguana_blocktx null txidind\n"); - } else printf("iguana_blocktx no bp\n"); - } + } // else printf("iguana_blocktx null txidind [%d:%d] i.%d\n",block->hdrsi,block->bundlei,i); + } else printf("iguana_blocktx no bp.[%d]\n",block->hdrsi); + } else printf("blocktx illegal height.%d\n",block->height); } else printf("i.%d vs txn_count.%d\n",i,block->RO.txn_count); return(0); } +int32_t iguana_ramtxbytes(struct iguana_info *coin,uint8_t *serialized,int32_t maxlen,bits256 *txidp,struct iguana_txid *tx,int32_t height,struct iguana_msgvin *vins,struct iguana_msgvout *vouts,int32_t validatesigs) +{ + int32_t i,rwflag=1,len = 0; char asmstr[512],txidstr[65]; + uint32_t numvins,numvouts; struct iguana_msgvin vin; struct iguana_msgvout vout; uint8_t space[IGUANA_MAXSCRIPTSIZE]; + 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->numvins, numvouts = tx->numvouts; + len += iguana_rwvarint32(rwflag,&serialized[len],&numvins); + memset(&vin,0,sizeof(vin)); + for (i=0; i maxlen ) + return(0); + len += iguana_rwvarint32(rwflag,&serialized[len],&numvouts); + for (i=0; i maxlen ) + return(0); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(tx->locktime),&tx->locktime); + *txidp = bits256_doublesha256(txidstr,serialized,len); + if ( memcmp(txidp,tx->txid.bytes,sizeof(*txidp)) != 0 ) + { + //for (i=0; itxid)); + return(-1); + } + return(len); +} + +int32_t iguana_peerblockrequest(struct iguana_info *coin,uint8_t *blockspace,int32_t max,struct iguana_peer *addr,bits256 hash2,int32_t validatesigs) +{ + struct iguana_txid *tx,T; bits256 checktxid; int32_t i,len,total,bundlei=-2; struct iguana_block *block; struct iguana_msgblock msgB; bits256 *tree,checkhash2,merkle_root; struct iguana_bundle *bp=0; long tmp; char str[65]; + if ( (bp= iguana_bundlefind(coin,&bp,&bundlei,hash2)) != 0 && bundlei >= 0 && bundlei < bp->n ) + { + if ( (block= bp->blocks[bundlei]) != 0 ) + { + iguana_blockunconv(&msgB,block,1); + total = iguana_rwblock(1,&checkhash2,&blockspace[sizeof(struct iguana_msghdr) + 0],&msgB); + if ( bits256_cmp(checkhash2,block->RO.hash2) != 0 ) + { + printf("iguana_peerblockrequest: blockhash mismatch ht.%d\n",bp->bundleheight+bundlei); + return(-1); + } + for (i=0; iRO.txn_count; i++) + { + if ( (tx= iguana_blocktx(coin,&T,block,i)) != 0 ) + { + if ( (len= iguana_ramtxbytes(coin,&blockspace[sizeof(struct iguana_msghdr) + total],max - total,&checktxid,tx,block->height,0,0,validatesigs)) > 0 && bits256_cmp(checktxid,T.txid) == 0 ) + total += len; + else + { + char str[65],str2[65]; + printf("error getting txi.%d [%d:%d] cmp.%s %s\n",i,bp->hdrsi,bundlei,bits256_str(str,checktxid),bits256_str(str2,T.txid)); + break; + } + } + else + { + //printf("null tx error getting txi.%d [%d:%d]\n",i,bp->hdrsi,bundlei); + break; + } + } + if ( i == block->RO.txn_count ) + { + tmp = (long)&blockspace[sizeof(struct iguana_msghdr) + total + sizeof(bits256)]; + tmp &= ~(sizeof(bits256) - 1); + tree = (void *)tmp; + for (i=0; iRO.txn_count; i++) + { + if ( (tx= iguana_blocktx(coin,&T,block,i)) != 0 ) + tree[i] = T.txid; + else break; + } + if ( i == block->RO.txn_count ) + { + merkle_root = iguana_merkle(coin,tree,block->RO.txn_count); + if ( bits256_cmp(merkle_root,block->RO.merkle_root) == 0 ) + { + if ( addr != 0 ) + { + printf("Send block.%d to %s\n",total,addr->ipaddr); + return(iguana_queue_send(coin,addr,0,blockspace,"block",total,0,0)); + } + else + { + //printf("validated.[%d:%d] len.%d\n",bp->hdrsi,bundlei,total); + return(total); + } + } else printf("iguana_peerblockrequest: error merkle cmp tx.[%d] for ht.%d\n",i,bp->bundleheight+bundlei); + } else printf("iguana_peerblockrequest: error merkle verify tx.[%d] for ht.%d\n",i,bp->bundleheight+bundlei); + } //else printf("iguana_peerblockrequest: error getting tx.[%d] for ht.%d block.%p main.%d ht.%d\n",i,bp->bundleheight+bundlei,block,block!=0?block->mainchain:-1,block!=0?block->height:-1); + } + else + { + if ( block != 0 ) + printf("iguana_peerblockrequest: block.%p ht.%d mainchain.%d [%d:%d]\n",block,block->height,block->mainchain,bp->hdrsi,bundlei); + else printf("iguana_peerblockrequest: block.%p [%d:%d]\n",block,bp->hdrsi,bundlei); + } + } else printf("iguana_peerblockrequest: cant find %s\n",bits256_str(str,hash2)); + return(-1); +} + cJSON *iguana_blockjson(struct iguana_info *coin,struct iguana_block *block,int32_t txidsflag) { - char str[65],hexstr[1024]; int32_t i,len; struct iguana_txid *tx,T; struct iguana_msgblock msg; - bits256 hash2; uint8_t serialized[1024]; cJSON *array,*json = cJSON_CreateObject(); + char str[65],hexstr[1024]; int32_t i,len,size; struct iguana_txid *tx,T; struct iguana_msgblock msg; + bits256 hash2,nexthash2; uint8_t serialized[1024]; cJSON *array,*json = cJSON_CreateObject(); jaddstr(json,"result","success"); jaddstr(json,"blockhash",bits256_str(str,block->RO.hash2)); jaddnum(json,"height",block->height); //jaddnum(json,"ipbits",block->fpipbits); - jaddstr(json,"merkle_root",bits256_str(str,block->RO.merkle_root)); - jaddstr(json,"prev_block",bits256_str(str,block->RO.prev_block)); + jaddstr(json,"merkleroot",bits256_str(str,block->RO.merkle_root)); + jaddstr(json,"previousblockhash",bits256_str(str,block->RO.prev_block)); + if ( block->height > 0 ) + { + nexthash2 = iguana_blockhash(coin,block->height+1); + if ( bits256_nonz(nexthash2) != 0 ) + jaddstr(json,"nextblockhash",bits256_str(str,nexthash2)); + } jaddnum(json,"timestamp",block->RO.timestamp); jaddstr(json,"utc",utc_str(str,block->RO.timestamp)); jaddnum(json,"nonce",block->RO.nonce); @@ -110,7 +310,7 @@ cJSON *iguana_blockjson(struct iguana_info *coin,struct iguana_block *block,int3 jaddnum(json,"valid",block->valid); jaddnum(json,"txn_count",block->RO.txn_count); - jaddnum(json,"nBits",block->RO.bits); + jaddnum(json,"bits",block->RO.bits); serialized[0] = ((uint8_t *)&block->RO.bits)[3]; serialized[1] = ((uint8_t *)&block->RO.bits)[2]; serialized[2] = ((uint8_t *)&block->RO.bits)[1]; @@ -135,205 +335,12 @@ cJSON *iguana_blockjson(struct iguana_info *coin,struct iguana_block *block,int3 if ( (tx= iguana_blocktx(coin,&T,block,i)) != 0 ) jaddistr(array,bits256_str(str,tx->txid)); } - jadd(json,"txids",array); + jadd(json,"tx",array); //printf("add txids[%d]\n",block->txn_count); } + if ( (size= iguana_peerblockrequest(coin,coin->blockspace,sizeof(coin->blockspace),0,block->RO.hash2,0)) < 0 ) + jaddstr(json,"error","couldnt generate raw bytes for block"); + else jaddnum(json,"size",size); return(json); } - -/* - //char *hashstr,*txidstr,*coinaddr,*txbytes,rmd160str[41],str[65]; int32_t len,height,i,n,valid = 0; - //cJSON *addrs,*retjson,*retitem; uint8_t rmd160[20],addrtype; bits256 hash2,checktxid; - //memset(&hash2,0,sizeof(hash2)); struct iguana_txid *tx,T; struct iguana_block *block = 0; - - if ( (coinaddr= jstr(json,"address")) != 0 ) - { - if ( btc_addr2univ(&addrtype,rmd160,coinaddr) == 0 ) - { - if ( addrtype == coin->chain->pubval || addrtype == coin->chain->p2shval ) - valid = 1; - else return(clonestr("{\"error\":\"invalid addrtype\"}")); - } else return(clonestr("{\"error\":\"cant convert address to rmd160\"}")); - } - if ( strcmp(method,"block") == 0 ) - { - height = -1; - if ( ((hashstr= jstr(json,"blockhash")) != 0 || (hashstr= jstr(json,"hash")) != 0) && strlen(hashstr) == sizeof(bits256)*2 ) - decode_hex(hash2.bytes,sizeof(hash2),hashstr); - else - { - height = juint(json,"height"); - hash2 = iguana_blockhash(coin,height); - } - retitem = cJSON_CreateObject(); - if ( (block= iguana_blockfind(coin,hash2)) != 0 ) - { - if ( (height >= 0 && block->height == height) || memcmp(hash2.bytes,block->RO.hash2.bytes,sizeof(hash2)) == 0 ) - { - char str[65],str2[65]; printf("hash2.(%s) -> %s\n",bits256_str(str,hash2),bits256_str(str2,block->RO.hash2)); - return(jprint(iguana_blockjson(coin,block,juint(json,"txids")),1)); - } - } - else return(clonestr("{\"error\":\"cant find block\"}")); - } - else if ( strcmp(method,"tx") == 0 ) - { - if ( ((txidstr= jstr(json,"txid")) != 0 || (txidstr= jstr(json,"hash")) != 0) && strlen(txidstr) == sizeof(bits256)*2 ) - { - retitem = cJSON_CreateObject(); - decode_hex(hash2.bytes,sizeof(hash2),txidstr); - if ( (tx= iguana_txidfind(coin,&height,&T,hash2)) != 0 ) - { - jadd(retitem,"tx",iguana_txjson(coin,tx,height)); - return(jprint(retitem,1)); - } - return(clonestr("{\"error\":\"cant find txid\"}")); - } - else return(clonestr("{\"error\":\"invalid txid\"}")); - } - else if ( strcmp(method,"rawtx") == 0 ) - { - if ( ((txidstr= jstr(json,"txid")) != 0 || (txidstr= jstr(json,"hash")) != 0) && strlen(txidstr) == sizeof(bits256)*2 ) - { - decode_hex(hash2.bytes,sizeof(hash2),txidstr); - if ( (tx= iguana_txidfind(coin,&height,&T,hash2)) != 0 ) - { - if ( (len= iguana_txbytes(coin,coin->blockspace,sizeof(coin->blockspace),&checktxid,tx,height,0,0)) > 0 ) - { - txbytes = mycalloc('x',1,len*2+1); - init_hexbytes_noT(txbytes,coin->blockspace,len*2+1); - retitem = cJSON_CreateObject(); - jaddstr(retitem,"txid",bits256_str(str,hash2)); - jaddnum(retitem,"height",height); - jaddstr(retitem,"rawtx",txbytes); - myfree(txbytes,len*2+1); - return(jprint(retitem,1)); - } else return(clonestr("{\"error\":\"couldnt generate txbytes\"}")); - } - return(clonestr("{\"error\":\"cant find txid\"}")); - } - else return(clonestr("{\"error\":\"invalid txid\"}")); - } - else if ( strcmp(method,"txs") == 0 ) - { - if ( ((hashstr= jstr(json,"block")) != 0 || (hashstr= jstr(json,"blockhash")) != 0) && strlen(hashstr) == sizeof(bits256)*2 ) - { - decode_hex(hash2.bytes,sizeof(hash2),hashstr); - if ( (block= iguana_blockfind(coin,hash2)) == 0 ) - return(clonestr("{\"error\":\"cant find blockhash\"}")); - } - else if ( jobj(json,"height") != 0 ) - { - height = juint(json,"height"); - hash2 = iguana_blockhash(coin,height); - if ( (block= iguana_blockfind(coin,hash2)) == 0 ) - return(clonestr("{\"error\":\"cant find block at height\"}")); - } - else if ( valid == 0 ) - return(clonestr("{\"error\":\"txs needs blockhash or height or address\"}")); - retitem = cJSON_CreateArray(); - if ( block != 0 ) - { - for (i=0; iRO.txn_count; i++) - { - if ( (tx= iguana_blocktx(coin,&T,block,i)) != 0 ) - jaddi(retitem,iguana_txjson(coin,tx,-1)); - } - } - else - { - init_hexbytes_noT(rmd160str,rmd160,20); - jaddnum(retitem,"addrtype",addrtype); - jaddstr(retitem,"rmd160",rmd160str); - jaddstr(retitem,"txlist","get list of all tx for this address"); - } - return(jprint(retitem,1)); - } - - else - { - n = 0; - if ( valid == 0 ) - { - if ( (addrs= jarray(&n,json,"addrs")) == 0 ) - return(clonestr("{\"error\":\"need address or addrs\"}")); - } - for (i=0; i<=n; i++) - { - retitem = cJSON_CreateObject(); - if ( i > 0 ) - retjson = cJSON_CreateArray(); - if ( i > 0 ) - { - if ( (coinaddr= jstr(jitem(addrs,i-1),0)) == 0 ) - return(clonestr("{\"error\":\"missing address in addrs\"}")); - if ( btc_addr2univ(&addrtype,rmd160,coinaddr) < 0 ) - { - free_json(retjson); - return(clonestr("{\"error\":\"illegal address in addrs\"}")); - } - if ( addrtype != coin->chain->pubval && addrtype != coin->chain->p2shval ) - return(clonestr("{\"error\":\"invalid addrtype in addrs\"}")); - } - if ( strcmp(method,"utxo") == 0 ) - { - jaddstr(retitem,"utxo","utxo entry"); - } - else if ( strcmp(method,"unconfirmed") == 0 ) - { - jaddstr(retitem,"unconfirmed","unconfirmed entry"); - } - else if ( strcmp(method,"balance") == 0 ) - { - jaddstr(retitem,"balance","balance entry"); - } - else if ( strcmp(method,"totalreceived") == 0 ) - { - jaddstr(retitem,"totalreceived","totalreceived entry"); - } - else if ( strcmp(method,"totalsent") == 0 ) - { - jaddstr(retitem,"totalsent","totalsent entry"); - } - else if ( strcmp(method,"validateaddress") == 0 ) - { - jaddstr(retitem,"validate",coinaddr); - } - if ( n == 0 ) - return(jprint(retitem,1)); - else jaddi(retjson,retitem); - } - return(jprint(retjson,1)); - } -*/ - -/* - char *iguana_listsinceblock(struct supernet_info *myinfo,struct iguana_info *coin,bits256 blockhash,int32_t target) - { - cJSON *retitem = cJSON_CreateObject(); - return(jprint(retitem,1)); - } - - char *iguana_getinfo(struct supernet_info *myinfo,struct iguana_info *coin) - { - cJSON *retitem = cJSON_CreateObject(); - jaddstr(retitem,"result",coin->statusstr); - return(jprint(retitem,1)); - } - - char *iguana_getbestblockhash(struct supernet_info *myinfo,struct iguana_info *coin) - { - cJSON *retitem = cJSON_CreateObject(); - char str[65]; jaddstr(retitem,"result",bits256_str(str,coin->blocks.hwmchain.RO.hash2)); - return(jprint(retitem,1)); - } - - char *iguana_getblockcount(struct supernet_info *myinfo,struct iguana_info *coin) - { - cJSON *retitem = cJSON_CreateObject(); - jaddnum(retitem,"result",coin->blocks.hwmchain.height); - return(jprint(retitem,1)); - }*/ - - diff --git a/iguana/iguana_txidfind.c b/iguana/iguana_txidfind.c new file mode 100755 index 000000000..0415f3bed --- /dev/null +++ b/iguana/iguana_txidfind.c @@ -0,0 +1,604 @@ +/****************************************************************************** + * 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" + +int32_t iguana_alloctxbits(struct iguana_info *coin,struct iguana_ramchain *ramchain) +{ + static int64_t total; + if ( ramchain->txbits == 0 ) + { + int32_t tlen; uint8_t *TXbits; + TXbits = RAMCHAIN_PTR(ramchain->H.data,TXoffset); + //TXbits = (uint8_t *)((long)ramchain->H.data + ramchain->H.data->TXoffset); + tlen = (int32_t)hconv_bitlen(ramchain->H.data->numtxsparse * ramchain->H.data->txsparsebits); + ramchain->txbits = calloc(1,tlen); + memcpy(ramchain->txbits,TXbits,tlen); + total += tlen; + char str[65]; printf("alloc.[%d] txbits.%p[%d] total %s\n",ramchain->H.data->height/coin->chain->bundlesize,ramchain->txbits,tlen,mbstr(str,total)); + return(tlen); + } + return(-1); +} + +int32_t iguana_alloccacheT(struct iguana_info *coin,struct iguana_ramchain *ramchain) +{ + static int64_t total; + if ( ramchain->cacheT == 0 ) + { + int32_t i,tlen; struct iguana_txid *T; + T = RAMCHAIN_PTR(ramchain->H.data,Toffset); + //T = (void *)((long)ramchain->H.data + ramchain->H.data->Toffset); + tlen = sizeof(*T) * ramchain->H.data->numtxids; + if ( (ramchain->cacheT= calloc(1,tlen)) != 0 ) + { + //memcpy(ramchain->cacheT,T,tlen); + for (i=0; iH.data->numtxids; i++) + ramchain->cacheT[i] = T[i]; + } else ramchain->cacheT = T; + total += tlen; + char str[65]; printf("alloc.[%d] cacheT.%p[%d] total %s\n",ramchain->H.data->height/coin->chain->bundlesize,ramchain->cacheT,tlen,mbstr(str,total)); + return(tlen); + } + return(-1); +} + +uint32_t iguana_sparseadd(uint8_t *bits,uint32_t ind,int32_t width,uint32_t tablesize,uint8_t *key,int32_t keylen,uint32_t setind,void *refdata,int32_t refsize,struct iguana_ramchain *ramchain,uint32_t maxitems) +{ + static uint8_t masks[8] = { 1, 2, 4, 8, 16, 32, 64, 128 }; + int32_t i,j,x,n,modval; int64_t bitoffset; uint8_t *ptr; uint32_t *table,retval = 0; + if ( tablesize == 0 ) + { + printf("iguana_sparseadd tablesize zero illegal\n"); + return(0); + } + if ( 0 && setind == 0 ) + { + char str[65]; + for (i=n=0; i> 3]; + modval = (bitoffset & 7); + for (x=j=0; j= 8 ) + ptr++, modval = 0; + x <<= 1; + x |= (*ptr & masks[modval]) >> modval; + } + if ( x != 0 ) + printf("%s ",bits256_str(str,*(bits256 *)(refdata + x*refsize))), n++; + } + printf("tableentries.%d\n",n); + } + //if ( setind == 0 ) + // ramchain->sparsesearches++; + //else ramchain->sparseadds++; + if ( 0 && (ramchain->sparsesearches % 1000000) == 0 ) + printf("[%3d] %7d.[%-2d %8d] %5.3f adds.(%-10ld %10ld) search.(hits.%-10ld %10ld) %5.2f%% max.%ld\n",ramchain->height/ramchain->H.data->numblocks,ramchain->height,width,tablesize,(double)(ramchain->sparseadditers + ramchain->sparsesearchiters)/(1+ramchain->sparsesearches+ramchain->sparseadds),ramchain->sparseadds,ramchain->sparseadditers,ramchain->sparsehits,ramchain->sparsesearches,100.*(double)ramchain->sparsehits/(1+ramchain->sparsesearches),ramchain->sparsemax+1); + if ( width == 32 ) + { + table = (uint32_t *)bits; + for (i=0; i= tablesize ) + ind = 0; + if ( (x= table[ind]) == 0 ) + { + //if ( ++i > ramchain->sparsemax ) + // ramchain->sparsemax = i; + if ( (retval= setind) != 0 ) + { + //ramchain->sparseadditers += i; + table[ind] = setind; + } //else ramchain->sparsesearchiters += i; + return(setind); + } + else if ( x < maxitems && memcmp((void *)(long)((long)refdata + x*refsize),key,keylen) == 0 ) + { + if ( setind != 0 && setind != x ) + printf("sparseadd index collision setind.%d != x.%d refsize.%d keylen.%d\n",setind,x,refsize,keylen); + //ramchain->sparsehits++; + //if ( ++i > ramchain->sparsemax ) + // ramchain->sparsemax = i; + //ramchain->sparseadditers += i; + return(x); + } + } + } + else + { + bitoffset = (ind * width); + if ( 0 && setind == 0 ) + printf("tablesize.%d width.%d bitoffset.%d\n",tablesize,width,(int32_t)bitoffset); + for (i=0; i= tablesize ) + { + ind = 0; + bitoffset = 0; + } + x = 0; + if ( width == 32 ) + memcpy(&x,&bits[bitoffset >> 3],4); + else if ( width == 16 ) + memcpy(&x,&bits[bitoffset >> 3],2); + else if ( width != 8 ) + { + ptr = &bits[bitoffset >> 3]; + modval = (bitoffset & 7); + if ( 0 && setind == 0 ) + printf("tablesize.%d width.%d bitoffset.%d modval.%d i.%d\n",tablesize,width,(int32_t)bitoffset,modval,i); + for (x=j=0; j= 8 ) + ptr++, modval = 0; + x <<= 1; + x |= (*ptr & masks[modval]) >> modval; + } + } + else x = bits[bitoffset >> 3]; + if ( 0 && setind == 0 ) + printf("x.%d\n",x); + if ( x == 0 ) + { + if ( (x= setind) == 0 ) + { + //ramchain->sparsesearchiters += (i+1); + return(0); + } + //else ramchain->sparseadditers += (i+1); + if ( width == 32 ) + memcpy(&bits[bitoffset >> 3],&setind,4); + else if ( width == 16 ) + memcpy(&bits[bitoffset >> 3],&setind,2); + else if ( width != 8 ) + { + ptr = &bits[(bitoffset+width-1) >> 3]; + modval = ((bitoffset+width-1) & 7); + for (j=0; j>=1,modval--) + { + if ( modval < 0 ) + ptr--, modval = 7; + if ( (x & 1) != 0 ) + *ptr |= masks[modval]; + } + } + else bits[bitoffset >> 3] = setind; + if ( 0 ) + { + for (x=j=0; j ramchain->sparsemax ) + // ramchain->sparsemax = i; + return(setind); + } + else if ( x < maxitems && memcmp((void *)(long)((long)refdata + x*refsize),key,keylen) == 0 ) + { + if ( setind == 0 ) + ramchain->sparsehits++; + else if ( setind != x ) + printf("sparseadd index collision setind.%d != x.%d refsize.%d keylen.%d\n",setind,x,refsize,keylen); + if ( i > ramchain->sparsemax ) + ramchain->sparsemax = i; + return(x); + } + } + } + return(0); +} + +uint32_t iguana_sparseaddtx(uint8_t *bits,int32_t width,uint32_t tablesize,bits256 txid,struct iguana_txid *T,uint32_t txidind,struct iguana_ramchain *ramchain) +{ + uint32_t ind,retval; + //char str[65]; printf("sparseaddtx %s txidind.%d bits.%p\n",bits256_str(str,txid),txidind,bits); + ind = (txid.ulongs[0] ^ txid.ulongs[1] ^ txid.ulongs[2] ^ txid.ulongs[3]) % tablesize; + if ( (retval= iguana_sparseadd(bits,ind,width,tablesize,txid.bytes,sizeof(txid),txidind,T,sizeof(*T),ramchain,ramchain->H.data->numtxids)) != 0 ) + { + char str[65]; + if ( txidind != 0 && retval != txidind ) + printf("sparse tx collision %s %u vs %u\n",bits256_str(str,txid),retval,txidind); + return(retval); + } + return(retval); +} + +uint32_t iguana_sparseaddpk(uint8_t *bits,int32_t width,uint32_t tablesize,uint8_t rmd160[20],struct iguana_pkhash *P,uint32_t pkind,struct iguana_ramchain *ramchain) +{ + uint32_t ind,key2; uint64_t key0,key1; + //int32_t i; for (i=0; i<20; i++) + // printf("%02x",rmd160[i]); + //char str[65]; printf(" sparseaddpk pkind.%d bits.%p\n",pkind,bits); + memcpy(&key0,rmd160,sizeof(key0)); + memcpy(&key1,&rmd160[sizeof(key0)],sizeof(key1)); + memcpy(&key2,&rmd160[sizeof(key0) + sizeof(key1)],sizeof(key2)); + ind = (key0 ^ key1 ^ key2) % tablesize; + return(iguana_sparseadd(bits,ind,width,tablesize,rmd160,20,pkind,P,sizeof(*P),ramchain,ramchain->H.data->numpkinds)); +} + +int32_t iguana_ramchain_spendtxid(struct iguana_info *coin,uint32_t *unspentindp,bits256 *txidp,struct iguana_txid *T,int32_t numtxids,bits256 *X,int32_t numexternaltxids,struct iguana_spend *s) +{ + uint32_t ind,external; + *unspentindp = 0; + memset(txidp,0,sizeof(*txidp)); + ind = s->spendtxidind; + external = (ind >> 31) & 1; + ind &= ~(1 << 31); + //printf("s.%p ramchaintxid vout.%x spendtxidind.%d isext.%d ext.%d ind.%d\n",s,s->prevout,ind,s->external,external,ind); + if ( s->prevout < 0 ) + return(-1); + if ( s->external != 0 && s->external == external && ind < numexternaltxids ) + { + //printf("ind.%d X.%p[%d]\n",ind,X,numexternaltxids); + *txidp = X[ind]; + return(s->prevout); + } + else if ( s->external == 0 && s->external == external && ind < numtxids ) + { + *txidp = T[ind].txid; + *unspentindp = T[ind].firstvout + s->prevout; + return(s->prevout); + } + return(-2); +} + +struct iguana_txid *iguana_txidfind(struct iguana_info *coin,int32_t *heightp,struct iguana_txid *tx,bits256 txid,int32_t lasthdrsi) +{ + uint8_t *TXbits; struct iguana_txid *T; uint32_t txidind; int32_t i; + struct iguana_bundle *bp; struct iguana_ramchain *ramchain; //struct iguana_block *block; + *heightp = -1; + if ( lasthdrsi < 0 ) + return(0); + for (i=lasthdrsi; i>=0; i--) + { + if ( (bp= coin->bundles[i]) != 0 && (bp == coin->current || bp->emitfinish > 1) ) + { + ramchain = (bp == coin->current) ? &coin->RTramchain : &bp->ramchain; + if ( ramchain->H.data != 0 ) + { + if ( (TXbits= ramchain->txbits) == 0 ) + { + if ( coin->fastfind == 0 && bp != coin->current ) + iguana_alloctxbits(coin,ramchain); + if ( (TXbits= ramchain->txbits) == 0 ) + { + //printf("use memory mapped.[%d]\n",ramchain->H.data->height/coin->chain->bundlesize); + TXbits = RAMCHAIN_PTR(ramchain->H.data,TXoffset); + //TXbits = (void *)(long)((long)ramchain->H.data + ramchain->H.data->TXoffset); + } + } + if ( (T= ramchain->cacheT) == 0 ) + { + //if ( coin->fastfind == 0 ) + // iguana_alloccacheT(coin,ramchain); + //if ( (T= ramchain->cacheT) == 0 ) + T = RAMCHAIN_PTR(ramchain->H.data,Toffset); + //T = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Toffset); + } + if ( (txidind= iguana_sparseaddtx(TXbits,ramchain->H.data->txsparsebits,ramchain->H.data->numtxsparse,txid,T,0,ramchain)) > 0 ) + { + //printf("found txidind.%d\n",txidind); + if ( bits256_cmp(txid,T[txidind].txid) == 0 ) + { + if ( 0 ) + { + int32_t j; struct iguana_block *block; + for (j=0; jn; j++) + if ( (block= bp->blocks[j]) != 0 && txidind >= block->RO.firsttxidind && txidind < block->RO.firsttxidind+block->RO.txn_count ) + break; + if ( j < bp->n ) + { + if ( j != T[txidind].bundlei ) + printf("bundlei mismatch j.%d != %d\n",j,T[txidind].bundlei); + else + { + *heightp = bp->bundleheight + T[txidind].bundlei; + //printf("found height.%d\n",*heightp); + *tx = T[txidind]; + return(tx); + } + } + } + else + { + *heightp = bp->bundleheight + T[txidind].bundlei; + //printf("found height.%d\n",*heightp); + *tx = T[txidind]; + return(tx); + } + } + char str[65],str2[65]; printf("iguana_txidfind mismatch.[%d:%d] %d %s vs %s\n",bp->hdrsi,T[txidind].extraoffset,txidind,bits256_str(str,txid),bits256_str(str2,T[txidind].txid)); + return(0); + } + } + } + } + return(0); +} + +int32_t iguana_txidfastfind(struct iguana_info *coin,int32_t *heightp,bits256 txid,int32_t lasthdrsi) +{ + uint8_t *sorted,*item; int32_t i,j,val,num,tablesize,*hashtable; uint32_t firstvout; + if ( (sorted= coin->fast[txid.bytes[31]]) != 0 ) + { + memcpy(&num,sorted,sizeof(num)); + memcpy(&tablesize,&sorted[sizeof(num)],sizeof(tablesize)); + if ( (hashtable= coin->fasttables[txid.bytes[31]]) == 0 ) + { + hashtable = (int32_t *)((long)sorted + (1 + num)*16); + //printf("backup hashtable\n"); + } + val = (txid.uints[4] % tablesize); + for (j=0; j= tablesize ) + val = 0; + if ( (i= hashtable[val]) == 0 ) + return(-1); + else + { + if ( i > num ) + { + printf("illegal val.%d vs num.%d tablesize.%d fastfind.%02x\n",i,num,tablesize,txid.bytes[31]); + return(-1); + } + else + { + item = (void *)((long)sorted + i*16); + if ( memcmp(&txid.txid,item,sizeof(uint64_t)) == 0 ) + { + memcpy(&firstvout,&item[sizeof(uint64_t)],sizeof(firstvout)); + memcpy(heightp,&item[sizeof(uint64_t) + sizeof(firstvout)],sizeof(*heightp)); + //printf("i.%d val.%d height.%d firstvout.%d j.%d\n",i,val,*heightp,firstvout,j); + if ( *heightp >= (lasthdrsi+1)*coin->chain->bundlesize ) + { + printf("txidfastfind: unexpected height.%d with lasthdrsi.%d\n",*heightp,lasthdrsi); + return(-1); + } + return(firstvout); + } + else if ( 0 ) + { + int32_t k; + for (k=-16; k<0; k++) + printf("%02x ",item[k]); + printf("<"); + for (k=0; k<16; k++) + printf("%02x ",item[k]); + printf(">"); + for (k=16; k<32; k++) + printf("%02x ",item[k]); + printf("\n"); + printf("txid.%llx vs item.%llx ht.%d 1st.%d\n",(long long)txid.txid,*(long long *)item,*(int32_t *)&item[sizeof(uint64_t)],*(int32_t *)&item[sizeof(uint64_t)+sizeof(uint32_t)]); + } + } + } + } + } + return(-1); +} + +int32_t iguana_fastfindadd(struct iguana_info *coin,bits256 txid,int32_t height,uint32_t firstvout) +{ + FILE *fp; + if ( bits256_nonz(txid) != 0 && (fp= coin->fastfps[txid.bytes[31]]) != 0 ) + { + txid.uints[6] = firstvout; + txid.uints[7] = height; + if ( fwrite(&txid,1,sizeof(txid),fp) == sizeof(txid) ) + return(1); + } + return(0); +} + +int64_t iguana_fastfindinitbundle(struct iguana_info *coin,struct iguana_bundle *bp,int32_t iter) +{ + int32_t i; struct iguana_txid *T; struct iguana_ramchaindata *rdata; int64_t n = 0; + if ( (rdata= bp->ramchain.H.data) != 0 ) + { + T = RAMCHAIN_PTR(rdata,Toffset); + //T = (void *)(long)((long)rdata + rdata->Toffset); + n = rdata->numtxids; + if ( iter == 1 ) + { + for (i=0; ibundleheight + T[i].bundlei,T[i].firstvout); + fprintf(stderr,"[%d:%u] ",bp->hdrsi,(int32_t)n); + } + } + return(n); +} + +static int _bignum_cmp(const void *a,const void *b) +{ + uint8_t *biga,*bigb; int32_t i,diff; + biga = (uint8_t *)a; + bigb = (uint8_t *)b; + for (i=0; i<32; i++) + { + if ( (diff= (biga[i] - bigb[i])) > 0 ) + return(1); + else if ( diff < 0 ) + return(-1); + } + return(0); +} + +uint32_t iguana_fastfindinit(struct iguana_info *coin) +{ + int32_t i,j,iter,num,tablesize,*hashtable; uint8_t *sorted; char fname[1024]; + //if ( strcmp("BTC",coin->symbol) != 0 ) + // return(0); + if ( coin->fastfind != 0 ) + return(coin->fastfind); + for (iter=0; iter<2; iter++) + { + for (i=0; i<0x100; i++) + { + sprintf(fname,"DB/%s%s/fastfind/%02x.all",iter!=0?"ro/":"",coin->symbol,i), OS_compatible_path(fname); + if ( (coin->fast[i]= OS_mapfile(fname,&coin->fastsizes[i],0)) == 0 ) + break; + else + { + fprintf(stderr,"."); + sorted = coin->fast[i]; + if ( 0 ) + { + coin->fast[i] = calloc(1,coin->fastsizes[i]); + memcpy(coin->fast[i],sorted,coin->fastsizes[i]); + munmap(sorted,coin->fastsizes[i]); + } + sorted = coin->fast[i]; + memcpy(&num,sorted,sizeof(num)); + memcpy(&tablesize,&sorted[sizeof(num)],sizeof(tablesize)); + if ( (num+1)*16 + tablesize*sizeof(*hashtable) == coin->fastsizes[i] ) + { + hashtable = (int32_t *)((long)sorted + (1 + num)*16); + if ( 0 ) + { + coin->fasttables[i] = calloc(tablesize,sizeof(*hashtable)); + memcpy(coin->fasttables[i],hashtable,tablesize * sizeof(*hashtable)); + } + } + else + { + printf("size error num.%d tablesize.%d -> %u vs %ld\n",num,tablesize,(int32_t)((num+1)*16 + tablesize*sizeof(*hashtable)),coin->fastsizes[i]); + break; + } + } + } + if ( i == 0x100 ) + { + coin->fastfind = (uint32_t)time(NULL); + printf("initialized fastfind.%s iter.%d\n",coin->symbol,iter); + return(coin->fastfind); + } + else + { + for (j=0; jfast[i],coin->fastsizes[i]); + free(coin->fasttables[i]); + coin->fast[i] = 0; + coin->fastsizes[i] = 0; + } + } + } + return(0); +} + +int64_t iguana_fastfindcreate(struct iguana_info *coin) +{ + int32_t i,j,val,iter,errs,num,ind,tablesize,*hashtable; bits256 *sortbuf,hash2; long allocsize; struct iguana_bundle *bp; char fname[512]; uint8_t buf[16]; int64_t total = 0; + if ( coin->current != 0 && coin->bundlescount == coin->current->hdrsi+1 ) + { + sprintf(fname,"DB/%s/fastfind",coin->symbol), OS_ensure_directory(fname); + for (i=0; i<0x100; i++) + { + sprintf(fname,"DB/%s/fastfind/%02x",coin->symbol,i), OS_compatible_path(fname); + if ( (coin->fastfps[i]= fopen(fname,"wb")) == 0 ) + break; + } + if ( i == 0x100 ) + { + for (iter=0; iter<2; iter++) + { + total = 0; + for (i=0; ibundlescount-1; i++) + if ( (bp= coin->bundles[i]) != 0 ) + total += iguana_fastfindinitbundle(coin,bp,iter); + printf("iguana_fastfindinit iter.%d total.%lld\n",iter,(long long)total); + } + for (i=errs=0; i<0x100; i++) + { + fclose(coin->fastfps[i]); + sprintf(fname,"DB/%s/fastfind/%02x",coin->symbol,i), OS_compatible_path(fname); + //printf("%s\n",fname); + if ( (sortbuf= OS_filestr(&allocsize,fname)) != 0 ) + { + OS_removefile(fname,0); + num = (int32_t)allocsize/sizeof(bits256); + qsort(sortbuf,num,sizeof(bits256),_bignum_cmp); + strcat(fname,".all"); + if ( (coin->fastfps[i]= fopen(fname,"wb")) != 0 ) + { + tablesize = (num << 1); + hashtable = calloc(sizeof(*hashtable),tablesize); + for (ind=1; ind<=num; ind++) + { + hash2 = sortbuf[ind-1]; + val = (hash2.uints[4] % tablesize); + for (j=0; j= tablesize ) + val = 0; + if ( hashtable[val] == 0 ) + { + hashtable[val] = ind; + break; + } + } + } + memset(&hash2,0,sizeof(hash2)); + hash2.uints[0] = num; + hash2.uints[1] = tablesize; + for (j=0; j<=num; j++) + { + memcpy(buf,&hash2.txid,sizeof(hash2.txid)); + memcpy(&buf[sizeof(hash2.txid)],&hash2.uints[6],sizeof(hash2.uints[6])); + memcpy(&buf[sizeof(hash2.txid) + sizeof(hash2.uints[6])],&hash2.uints[7],sizeof(hash2.uints[7])); + fwrite(buf,1,sizeof(buf),coin->fastfps[i]); + //fwrite(hash2,1,sizeof(hash2),coin->fastfps[i]); + if ( j < num ) + { + hash2 = sortbuf[j]; + //char str[65]; printf("%d %s\n",j,bits256_str(str,hash2)); + } + } + if ( fwrite(hashtable,sizeof(*hashtable),tablesize,coin->fastfps[i]) == tablesize ) + { + fclose(coin->fastfps[i]); + coin->fastfps[i] = 0; + if ( (coin->fast[i]= OS_mapfile(fname,&coin->fastsizes[i],0)) != 0 ) + { + } else errs++; + printf("%s fastfind.[%02x] num.%d tablesize.%d errs.%d %p[%ld]\n",fname,i,num,tablesize,errs,coin->fast[i],coin->fastsizes[i]); + } + else + { + printf("error saving (%s)\n",fname); + OS_removefile(fname,0); + fclose(coin->fastfps[i]); + coin->fastfps[i] = 0; + } + free(hashtable); + } else printf("couldnt overwrite (%s)\n",fname); + free(sortbuf); + } else printf("couldnt load sortbuf (%s)\n",fname); + } + printf("initialized with errs.%d\n",errs); + if ( errs == 0 ) + coin->fastfind = (uint32_t)time(NULL); + } + } + return(total); +} diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c new file mode 100755 index 000000000..861f6434a --- /dev/null +++ b/iguana/iguana_unspents.c @@ -0,0 +1,390 @@ +/****************************************************************************** + * 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 uthash_malloc(size) iguana_memalloc(&coin->RThashmem,size,1) +//#define uthash_free(ptr,size) + +#include "iguana777.h" +#include "exchanges/bitcoin.h" + +int32_t iguana_unspentindfind(struct iguana_info *coin,char *coinaddr,uint8_t *spendscript,int32_t *spendlenp,uint64_t *valuep,int32_t *heightp,bits256 txid,int32_t vout,int32_t lasthdrsi) +{ + struct iguana_txid *tp,TX; struct iguana_pkhash *P; struct iguana_unspent *U; struct iguana_bundle *bp; struct iguana_ramchaindata *rdata; int64_t RTspend; int32_t pkind,hdrsi,firstvout,spentheight,unspentind = -1; + if ( valuep != 0 ) + *valuep = 0; + if ( coinaddr != 0 ) + coinaddr[0] = 0; + if ( coin->fastfind != 0 && (firstvout= iguana_txidfastfind(coin,heightp,txid,lasthdrsi)) >= 0 ) + unspentind = (firstvout + vout); + else if ( (tp= iguana_txidfind(coin,heightp,&TX,txid,lasthdrsi)) != 0 ) + unspentind = (tp->firstvout + vout); + if ( coinaddr != 0 && unspentind > 0 && (hdrsi= *heightp/coin->chain->bundlesize) >= 0 && hdrsi < coin->bundlescount && (bp= coin->bundles[hdrsi]) != 0 && (rdata= bp->ramchain.H.data) != 0 && unspentind < rdata->numunspents ) + { + U = RAMCHAIN_PTR(rdata,Uoffset); + P = RAMCHAIN_PTR(rdata,Poffset); + //U = (void *)(long)((long)rdata + rdata->Uoffset); + //P = (void *)(long)((long)rdata + rdata->Poffset); + pkind = U[unspentind].pkind; + if ( pkind > 0 && pkind < rdata->numpkinds ) + { + RTspend = 0; + if ( iguana_spentflag(coin,&RTspend,&spentheight,bp == coin->current ? &coin->RTramchain : &bp->ramchain,bp->hdrsi,unspentind,0,1,coin->longestchain,U[unspentind].value) == 0 ) + { + if ( valuep != 0 ) + *valuep = U[unspentind].value; + bitcoin_address(coinaddr,iguana_addrtype(coin,U[unspentind].type),P[pkind].rmd160,sizeof(P[pkind].rmd160)); + if ( spendscript != 0 && spendlenp != 0 ) + *spendlenp = iguana_voutscript(coin,bp,spendscript,0,&U[unspentind],&P[pkind],1); + } + } + } + return(unspentind); +} + +cJSON *ramchain_unspentjson(struct iguana_unspent *up,uint32_t unspentind) +{ + cJSON *item = cJSON_CreateObject(); + jaddnum(item,"hdrsi",up->hdrsi); + jaddnum(item,"pkind",up->pkind); + jaddnum(item,"unspentind",unspentind); + jaddnum(item,"prevunspentind",up->prevunspentind); + jadd64bits(item,"satoshis",up->value); + jaddnum(item,"txidind",up->txidind); + jaddnum(item,"vout",up->vout); + jaddnum(item,"type",up->type); + jaddnum(item,"fileid",up->fileid); + jaddnum(item,"scriptpos",up->scriptpos); + jaddnum(item,"scriptlen",up->scriptlen); + return(item); +} + +cJSON *iguana_unspentjson(struct supernet_info *myinfo,struct iguana_info *coin,int32_t hdrsi,uint32_t unspentind,struct iguana_txid *T,struct iguana_unspent *up,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33) +{ + /*{ + "txid" : "d54994ece1d11b19785c7248868696250ab195605b469632b7bd68130e880c9a", + "vout" : 1, + "address" : "mgnucj8nYqdrPFh2JfZSB1NmUThUGnmsqe", + "account" : "test label", + "scriptPubKey" : "76a9140dfc8bafc8419853b34d5e072ad37d1a5159f58488ac", + "amount" : 0.00010000, + "confirmations" : 6210, + "spendable" : true + },*/ + //struct iguana_unspent { uint64_t value; uint32_t txidind,pkind,prevunspentind; uint16_t hdrsi:12,type:4,vout; } __attribute__((packed)); + struct iguana_waccount *wacct; struct iguana_waddress *waddr; int32_t height; char scriptstr[8192],asmstr[sizeof(scriptstr)+1024]; cJSON *item; uint32_t checkind; + item = cJSON_CreateObject(); + jaddbits256(item,"txid",T[up->txidind].txid); + jaddnum(item,"vout",up->vout); + jaddstr(item,"address",coinaddr); + if ( iguana_scriptget(coin,scriptstr,asmstr,sizeof(scriptstr),hdrsi,unspentind,T[up->txidind].txid,up->vout,rmd160,up->type,pubkey33) != 0 ) + jaddstr(item,"scriptPubKey",scriptstr); + jaddnum(item,"amount",dstr(up->value)); + if ( (checkind= iguana_unspentindfind(coin,0,0,0,0,&height,T[up->txidind].txid,up->vout,coin->bundlescount-1)) != 0 ) + { + jaddnum(item,"confirmations",coin->blocks.hwmchain.height - height + 1); + jaddnum(item,"checkind",checkind); + } + if ( (waddr= iguana_waddresssearch(myinfo,coin,&wacct,coinaddr)) != 0 ) + { + jaddstr(item,"account",wacct->account); + jadd(item,"spendable",jtrue()); + } else jadd(item,"spendable",jfalse()); + jadd(item,"unspent",ramchain_unspentjson(up,unspentind)); + return(item); +} + +struct iguana_pkhash *iguana_pkhashfind(struct iguana_info *coin,struct iguana_ramchain **ramchainp,int64_t *depositsp,uint32_t *lastunspentindp,struct iguana_pkhash *p,uint8_t rmd160[20],int32_t firsti,int32_t endi) +{ + uint8_t *PKbits; struct iguana_pkhash *P; uint32_t pkind,numpkinds,i; struct iguana_bundle *bp; struct iguana_ramchain *ramchain; struct iguana_ramchaindata *rdata; struct iguana_account *ACCTS; + *depositsp = 0; + *ramchainp = 0; + *lastunspentindp = 0; + for (i=firsti; ibundlescount&&i<=endi; i++) + { + if ( (bp= coin->bundles[i]) != 0 ) + { + if ( 0 && coin->RTramchain_busy != 0 ) + { + printf("iguana_pkhashfind: unexpected access when RTramchain_busy\n"); + return(0); + } + ramchain = (bp != coin->current) ? &bp->ramchain : &coin->RTramchain; + if ( (rdata= ramchain->H.data) != 0 ) + { + numpkinds = rdata->numpkinds; + PKbits = RAMCHAIN_PTR(rdata,PKoffset); + P = RAMCHAIN_PTR(rdata,Poffset); + //PKbits = (void *)(long)((long)rdata + rdata->PKoffset); + //P = (void *)(long)((long)rdata + rdata->Poffset); + if ( bp == coin->current ) + ACCTS = ramchain->A; + else ACCTS = RAMCHAIN_PTR(rdata,Aoffset); //ACCTS = (void *)(long)((long)rdata + rdata->Aoffset); + if ( (pkind= iguana_sparseaddpk(PKbits,rdata->pksparsebits,rdata->numpksparse,rmd160,P,0,ramchain)) > 0 && pkind < numpkinds ) + { + *ramchainp = ramchain; + *depositsp = ACCTS[pkind].total; + *lastunspentindp = ACCTS[pkind].lastunspentind; + printf("[%d] return pkind.%u of %u P.%p %.8f last.%u ACCTS.%p %p\n",i,pkind,numpkinds,P,dstr(*depositsp),*lastunspentindp,ACCTS,ramchain->A); + if ( P != 0 ) + *p = P[pkind]; + return(p); + } + else if ( pkind != 0 ) + printf("[%d] not found pkind.%d vs num.%d RT.%d rdata.%p\n",i,pkind,rdata->numpkinds,bp->isRT,rdata); + } else printf("%s.[%d] error null rdata isRT.%d\n",coin->symbol,i,bp->isRT); + } + } + return(0); +} + +int32_t iguana_uheight(struct iguana_info *coin,int32_t bundleheight,struct iguana_txid *T,int32_t numtxids,struct iguana_unspent *up) +{ + if ( up->txidind > 0 && up->txidind < numtxids ) + return(bundleheight + T[up->txidind].bundlei); + else return(bundleheight); +} + +int64_t iguana_pkhashbalance(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *array,int64_t *spentp,uint64_t *unspents,int32_t *nump,struct iguana_ramchain *ramchain,struct iguana_pkhash *p,uint32_t lastunspentind,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33,int32_t hdrsi,int32_t lastheight,int32_t minconf,int32_t maxconf) +{ + struct iguana_unspent *U; struct iguana_utxo *U2; struct iguana_spend *S; int32_t max,uheight,spentheight; uint32_t pkind=0,unspentind; int64_t spent = 0,checkval,deposits = 0; struct iguana_txid *T; struct iguana_account *A2; struct iguana_ramchaindata *rdata = 0; int64_t RTspend = 0; + max = *nump; + *spentp = *nump = 0; + if ( 0 && coin->RTramchain_busy != 0 ) + { + printf("iguana_pkhashbalance: unexpected access when RTramchain_busy\n"); + return(0); + } + if ( ramchain->Uextras == 0 || (rdata= ramchain->H.data) == 0 ) + { + printf("iguana_pkhashbalance: unexpected null spents.%p or rdata.%p\n",ramchain->Uextras,rdata); + return(0); + } + unspentind = lastunspentind; + U = RAMCHAIN_PTR(rdata,Uoffset); + T = RAMCHAIN_PTR(rdata,Toffset); + //U = (void *)(long)((long)rdata + rdata->Uoffset); + //T = (void *)(long)((long)rdata + rdata->Toffset); + RTspend = 0; + if ( lastheight == 0 ) + lastheight = IGUANA_MAXHEIGHT; + while ( unspentind > 0 ) + { + uheight = iguana_uheight(coin,ramchain->height,T,rdata->numtxids,&U[unspentind]); + if ( uheight < lastheight ) + { + deposits += U[unspentind].value; + if ( lastheight < 0 || iguana_spentflag(coin,&RTspend,&spentheight,ramchain,hdrsi,unspentind,lastheight,minconf,maxconf,U[unspentind].value) == 0 ) + { + if ( *nump < max && unspents != 0 ) + unspents[*nump] = ((uint64_t)hdrsi << 32) | unspentind; + (*nump)++; + if ( array != 0 ) + jaddi(array,iguana_unspentjson(myinfo,coin,hdrsi,unspentind,T,&U[unspentind],rmd160,coinaddr,pubkey33)); + } else spent += U[unspentind].value; + if ( p->pkind != U[unspentind].pkind ) + printf("warning: [%d] p->pkind.%u vs U->pkind.%u for u%d\n",hdrsi,p->pkind,U[unspentind].pkind,unspentind); + } + pkind = p->pkind; + unspentind = U[unspentind].prevunspentind; + } + if ( lastheight > 0 && (A2= ramchain->A2) != 0 && (U2= ramchain->Uextras) != 0 ) + { + S = RAMCHAIN_PTR(rdata,Soffset); + //S = (void *)(long)((long)rdata + rdata->Soffset); + unspentind = A2[pkind].lastunspentind; + checkval = 0; + while ( unspentind > 0 ) + { + uheight = iguana_uheight(coin,ramchain->height,T,rdata->numtxids,&U[unspentind]); + if ( uheight < lastheight ) + { + checkval += U[unspentind].value; + //printf("u%u %.8f spentflag.%d prev.%u fromheight.%d\n",unspentind,dstr(U[unspentind].value),U2[unspentind].spentflag,U2[unspentind].prevunspentind,U2[unspentind].fromheight); + } + unspentind = U2[unspentind].prevunspentind; + } + if ( llabs(spent - checkval - RTspend) > SMALLVAL ) + printf("spend %s: [%d] deposits %.8f spent %.8f check %.8f (%.8f) vs A2[%u] %.8f\n",lastheight==IGUANA_MAXHEIGHT?"checkerr":"",hdrsi,dstr(deposits),dstr(spent),dstr(checkval)+dstr(RTspend),dstr(*spentp),pkind,dstr(A2[pkind].total)); + } + (*spentp) = spent; + //printf("spent %.8f, RTspent %.8f deposits %.8f\n",dstr(spent),dstr(RTspend),dstr(deposits)); + return(deposits - spent); +} + +int32_t iguana_pkhasharray(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *array,int32_t minconf,int32_t maxconf,int64_t *totalp,struct iguana_pkhash *P,int32_t max,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33,int32_t lastheight,uint64_t *unspents,int32_t *numunspentsp,int32_t maxunspents) +{ + int32_t i,n,m,numunspents = *numunspentsp; int64_t spent,deposits,netbalance,total; uint32_t lastunspentind; struct iguana_pkhash *p,_p; struct iguana_ramchain *ramchain; struct iguana_bundle *bp; + if ( 0 && coin->RTramchain_busy != 0 ) + { + printf("iguana_pkhasharray: unexpected access when RTramchain_busy\n"); + return(-1); + } + if ( lastheight == 0 ) + lastheight = IGUANA_MAXHEIGHT; + if ( max > coin->bundlescount ) + max = coin->bundlescount; + for (total=n=0,i=max-1; i>=0; i--) + { + if ( (bp= coin->bundles[i]) == 0 ) + continue; + if ( lastheight > 0 && bp->bundleheight > lastheight ) + break; + if ( (coin->blocks.hwmchain.height - (bp->bundleheight + bp->n - 1)) > maxconf ) + continue; + if ( (coin->blocks.hwmchain.height - bp->bundleheight) < minconf ) + break; + if ( iguana_pkhashfind(coin,&ramchain,&deposits,&lastunspentind,P != 0 ? &P[n] : &_p,rmd160,i,i) != 0 ) + { + m = maxunspents; + p = (P == 0) ? &_p : &P[n]; + if ( (netbalance= iguana_pkhashbalance(myinfo,coin,array,&spent,unspents != 0 ? &unspents[numunspents] : 0,&m,ramchain,p,lastunspentind,rmd160,coinaddr,pubkey33,i,lastheight,minconf,maxconf)) != deposits-spent && lastheight == IGUANA_MAXHEIGHT && minconf == 1 && maxconf > coin->blocks.hwmchain.height ) + { + printf("pkhash balance mismatch from m.%d check %.8f vs %.8f spent %.8f [%.8f]\n",m,dstr(netbalance),dstr(deposits),dstr(spent),dstr(deposits)-dstr(spent)); + } + else + { + //printf("pkhash balance.[%d] from m.%d check %.8f vs %.8f spent %.8f [%.8f]\n",i,m,dstr(netbalance),dstr(deposits),dstr(spent),dstr(deposits)-dstr(spent)); + total += netbalance; + n++; + } + maxunspents -= m; + numunspents += m; + printf("%d: balance %.8f, lastunspent.%u m.%d num.%d max.%d\n",i,dstr(total),lastunspentind,m,numunspents,maxunspents); + } + } + if ( numunspentsp != 0 ) + *numunspentsp = numunspents; + printf("numunspents.%d [%d] max.%d\n",numunspents,*numunspentsp,maxunspents); + *totalp += total; + return(n); +} + +int64_t iguana_unspents(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *array,int32_t minconf,int32_t maxconf,uint8_t *rmdarray,int32_t numrmds,int32_t lastheight,uint64_t *unspents,int32_t *numunspentsp) +{ + int64_t total=0,sum=0; struct iguana_pkhash *P; uint8_t *addrtypes,*pubkeys; int32_t i,numunspents,maxunspents,flag = 0; char coinaddr[64]; + if ( 0 && coin->RTramchain_busy != 0 ) + { + printf("iguana_pkhasharray: unexpected access when RTramchain_busy\n"); + return(sum); + } + numunspents = 0; + maxunspents = *numunspentsp; + if ( rmdarray == 0 ) + rmdarray = iguana_walletrmds(myinfo,coin,&numrmds), flag++; + if ( numrmds > 0 && rmdarray != 0 ) + { + addrtypes = &rmdarray[numrmds * 20], pubkeys = &rmdarray[numrmds * 21]; + P = calloc(coin->bundlescount,sizeof(*P)); + for (i=0; ibundlescount,&rmdarray[i * 20],coinaddr,&pubkeys[33*i],lastheight,&unspents[numunspents],numunspentsp,maxunspents); + printf("iguana_unspents: i.%d of %d: %s %.8f numunspents.%d\n",i,numrmds,coinaddr,dstr(total),*numunspentsp); + maxunspents -= *numunspentsp; + numunspents += *numunspentsp; + sum += total; + } + printf("sum %.8f\n",dstr(sum)); + free(P); + } + *numunspentsp = numunspents; + if ( flag != 0 && rmdarray != 0 ) + free(rmdarray); + return(sum); +} + +uint8_t *iguana_rmdarray(struct iguana_info *coin,int32_t *numrmdsp,cJSON *array,int32_t firsti) +{ + int32_t i,n,j=0; char *coinaddr,rmdstr[41]; uint8_t *addrtypes,*rmdarray = 0; + *numrmdsp = 0; + if ( array != 0 && (n= cJSON_GetArraySize(array)) > 0 ) + { + *numrmdsp = n - firsti; + rmdarray = calloc(1,(n-firsti) * (21 + 33)); + addrtypes = &rmdarray[(n-firsti) * 20]; + for (i=firsti; iwallet,wacct,tmp) + { + HASH_ITER(hh,wacct->waddr,waddr,tmp2) + { + if ( waddr->addrtype != coin->chain->pubtype || (bits256_nonz(waddr->privkey) == 0 && waddr->scriptlen == 0) ) + continue; + total = 0; + n = 0; + iguana_pkhasharray(myinfo,coin,0,coin->minconfirms,coin->longestchain,&total,0,coin->bundlescount,waddr->rmd160,waddr->coinaddr,waddr->pubkey,coin->blocks.hwmchain.height - coin->minconfirms,(uint64_t *)coin->blockspace,&n,(int32_t)(sizeof(coin->blockspace)/sizeof(*waddr->unspents))); + if ( n > 0 ) + { + if ( waddr->unspents == 0 || waddr->maxunspents < n ) + { + waddr->unspents = realloc(waddr->unspents,sizeof(*waddr->unspents) * n); + waddr->maxunspents = n; + } + memcpy(waddr->unspents,coin->blockspace,sizeof(*waddr->unspents) * n); + waddr->numunspents = n; + waddr->balance = total; + sum += total; + numunspents += n; + } + } + } + printf("available %.8f\n",dstr(sum)); + return(sum); +} + +int32_t iguana_unspentslists(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waddress **waddrs,int32_t maxwaddrs,int64_t required,int32_t minconf,char *account) +{ + int64_t remains; int32_t num = 0; struct iguana_waccount *wacct,*tmp; struct iguana_waddress *waddr,*tmp2; + remains = required * 1.1; + HASH_ITER(hh,myinfo->wallet,wacct,tmp) + { + if ( account != 0 && strcmp(account,wacct->account) != 0 ) + continue; + HASH_ITER(hh,wacct->waddr,waddr,tmp2) + { + if ( waddr->addrtype != coin->chain->pubtype || (bits256_nonz(waddr->privkey) == 0 && waddr->scriptlen == 0) ) + continue; + if ( waddr->balance > 0 ) + { + remains -= waddr->balance; + waddrs[num++] = waddr; + if ( num >= maxwaddrs || remains <= 0 ) + break; + } + } + if ( num >= maxwaddrs || remains <= 0 ) + break; + } + return(num); +} + diff --git a/iguana/iguana_volatiles.c b/iguana/iguana_volatiles.c new file mode 100755 index 000000000..5d616d7aa --- /dev/null +++ b/iguana/iguana_volatiles.c @@ -0,0 +1,346 @@ +/****************************************************************************** + * 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" + +struct iguana_hhutxo *iguana_hhutxofind(struct iguana_info *coin,uint64_t uval) +{ + struct iguana_hhutxo *hhutxo; + HASH_FIND(hh,coin->utxotable,&uval,sizeof(uval),hhutxo); + return(hhutxo); +} + +struct iguana_hhaccount *iguana_hhaccountfind(struct iguana_info *coin,uint64_t pval) +{ + struct iguana_hhaccount *hhacct; + HASH_FIND(hh,coin->accountstable,&pval,sizeof(pval),hhacct); + return(hhacct); +} + +int32_t iguana_utxoupdate(struct iguana_info *coin,int16_t spent_hdrsi,uint32_t spent_unspentind,uint32_t spent_pkind,uint64_t spent_value,uint32_t spendind,uint32_t fromheight) +{ + //static struct iguana_hhutxo *HHUTXO; static struct iguana_hhaccount *HHACCT; static uint32_t numHHUTXO,maxHHUTXO,numHHACCT,maxHHACCT; + struct iguana_hhutxo *hhutxo,*tmputxo; struct iguana_hhaccount *hhacct,*tmpacct; uint64_t uval,pval; + if ( spent_hdrsi < 0 ) + { + printf(">>>>>>>>>>> RESET UTXO HASH <<<<<<<<<\n"); + if ( coin->utxotable != 0 ) + { + HASH_ITER(hh,coin->utxotable,hhutxo,tmputxo) + { + //HASH_DEL(coin->utxotable,hhutxo); + hhutxo->u.spentflag = 0; + hhutxo->u.fromheight = 0; + hhutxo->u.prevunspentind = 0; + //free(hhutxo); + } + //coin->utxotable = 0; + } + if ( coin->accountstable != 0 ) + { + HASH_ITER(hh,coin->accountstable,hhacct,tmpacct) + { + //HASH_DEL(coin->accountstable,hhacct); + hhacct->a.lastunspentind = 0; + hhacct->a.total = 0; + //free(hhacct); + } + //coin->accountstable = 0; + } + /*if ( HHUTXO != 0 ) + { + free(HHUTXO); + maxHHUTXO = numHHUTXO = 0; + HHUTXO = 0; + } + if ( HHACCT != 0 ) + { + free(HHACCT); + maxHHACCT = numHHACCT = 0; + HHACCT = 0; + }*/ + return(0); + } + uval = ((uint64_t)spent_hdrsi << 32) | spent_unspentind; + pval = ((uint64_t)spent_hdrsi << 32) | spent_pkind; + if ( (hhutxo= iguana_hhutxofind(coin,uval)) != 0 && hhutxo->u.spentflag != 0 ) + { + printf("hhutxo.%p spentflag.%d\n",hhutxo,hhutxo->u.spentflag); + return(-1); + } + /*if ( 0 && numHHUTXO+1 >= maxHHUTXO ) + { + maxHHUTXO += 1; + HHUTXO = realloc(HHUTXO,sizeof(*HHUTXO) * maxHHUTXO); + }*/ + hhutxo = calloc(1,sizeof(*hhutxo));//&HHUTXO[numHHUTXO++], memset(hhutxo,0,sizeof(*hhutxo)); + hhutxo->uval = uval; + HASH_ADD_KEYPTR(hh,coin->utxotable,&hhutxo->uval,sizeof(hhutxo->uval),hhutxo); + if ( (hhacct= iguana_hhaccountfind(coin,pval)) == 0 ) + { + /*if ( 0 && numHHACCT+1 >= maxHHACCT ) + { + maxHHACCT += 1; + HHACCT = realloc(HHACCT,sizeof(*HHACCT) * maxHHACCT); + }*/ + hhacct = calloc(1,sizeof(*hhacct)); // &HHACCT[numHHACCT++], memset(hhacct,0,sizeof(*hhacct)); + hhacct->pval = pval; + HASH_ADD_KEYPTR(hh,coin->accountstable,&hhacct->pval,sizeof(hhacct->pval),hhacct); + } + //printf("create hhutxo.%p hhacct.%p from.%d\n",hhutxo,hhacct,fromheight); + hhutxo->u.spentflag = 1; + hhutxo->u.fromheight = fromheight; + hhutxo->u.prevunspentind = hhacct->a.lastunspentind; + hhacct->a.lastunspentind = spent_unspentind; + hhacct->a.total += spent_value; + /*if ( iguana_hhutxofind(coin,uval) == 0 || iguana_hhaccountfind(coin,pval) == 0 ) + { + printf("null hh find.(%ld %ld) %p %p\n",(long)uval,(long)pval,iguana_hhutxofind(coin,uval),iguana_hhaccountfind(coin,pval)); + }*/ + return(0); +} + +int32_t iguana_spentflag(struct iguana_info *coin,int64_t *RTspendp,int32_t *spentheightp,struct iguana_ramchain *ramchain,int16_t spent_hdrsi,uint32_t spent_unspentind,int32_t height,int32_t minconf,int32_t maxconf,uint64_t amount) +{ + uint32_t numunspents; struct iguana_hhutxo *hhutxo; struct iguana_utxo utxo; uint64_t confs,val,RTspend = 0; + *spentheightp = 0; + numunspents = ramchain->H.data->numunspents; + memset(&utxo,0,sizeof(utxo)); + val = ((uint64_t)spent_hdrsi << 32) | spent_unspentind; + if ( spent_unspentind != 0 && spent_unspentind < numunspents ) + { + if ( ramchain->Uextras != 0 ) + utxo = ramchain->Uextras[spent_unspentind]; + if ( ramchain->Uextras == 0 || utxo.spentflag == 0 ) + { + //printf("check hhutxo [%d] u%u %p\n",spent_hdrsi,spent_unspentind,iguana_hhutxofind(coin,((uint64_t)202<<32)|3909240)); + if ( (hhutxo= iguana_hhutxofind(coin,val)) != 0 ) + { + utxo = hhutxo->u; + if ( utxo.spentflag != 0 ) + RTspend = amount; + } + } + } + else + { + printf("illegal unspentind.%u vs %u hdrs.%d\n",spent_unspentind,numunspents,spent_hdrsi); + return(-1); + } + if ( utxo.spentflag != 0 && utxo.fromheight == 0 ) + { + printf("illegal unspentind.%u vs %u hdrs.%d zero fromheight?\n",spent_unspentind,numunspents,spent_hdrsi); + return(-1); + } + //printf("[%d] u%u %.8f, spentheight.%d vs height.%d spentflag.%d\n",spent_hdrsi,spent_unspentind,dstr(amount),utxo.fromheight,height,utxo.spentflag); + *spentheightp = utxo.fromheight; + if ( (confs= coin->blocks.hwmchain.height - utxo.fromheight) >= minconf && confs < maxconf && (height == 0 || utxo.fromheight < height) ) + { + (*RTspendp) += RTspend; + if ( utxo.spentflag != 0 ) + return(1); + else if ( utxo.lockedflag != 0 ) + return(-1); + else return(0); + } + return(0); +} + +int32_t iguana_volatileupdate(struct iguana_info *coin,int32_t incremental,struct iguana_ramchain *spentchain,int16_t spent_hdrsi,uint32_t spent_unspentind,uint32_t spent_pkind,uint64_t spent_value,uint32_t spendind,uint32_t fromheight) +{ + struct iguana_account *A2; struct iguana_ramchaindata *rdata; struct iguana_utxo *utxo; + if ( (rdata= spentchain->H.data) != 0 ) + { + if ( incremental == 0 ) + { + if ( spentchain->Uextras == 0 || spentchain->A2 == 0 ) + iguana_volatilesmap(coin,spentchain); + if ( spentchain->Uextras != 0 && (A2= spentchain->A2) != 0 ) + { + utxo = &spentchain->Uextras[spent_unspentind]; + if ( utxo->spentflag == 0 ) + { + if ( 0 && fromheight/coin->chain->bundlesize >= coin->current->hdrsi ) + printf("iguana_volatileupdate.%d: [%d] spent.(u%u %.8f pkind.%d) fromht.%d [%d] spendind.%d\n",incremental,spent_hdrsi,spent_unspentind,dstr(spent_value),spent_pkind,fromheight,fromheight/coin->chain->bundlesize,spendind); + utxo->prevunspentind = A2[spent_pkind].lastunspentind; + utxo->spentflag = 1; + utxo->fromheight = fromheight; + A2[spent_pkind].total += spent_value; + A2[spent_pkind].lastunspentind = spent_unspentind; + return(0); + } + else + { + printf("from.%d spent_unspentind[%d] in hdrs.[%d] is spent fromht.%d %.8f\n",fromheight,spent_unspentind,spent_hdrsi,utxo->fromheight,dstr(spent_value)); + } + } else printf("null ptrs.[%d] u.%u p.%u %.8f from ht.%d s.%u\n",spent_hdrsi,spent_unspentind,spent_pkind,dstr(spent_value),fromheight,spendind); + } + else // do the equivalent of historical, ie mark as spent, linked list, balance + { + //double startmillis = OS_milliseconds(); static double totalmillis; static int32_t utxon; + if ( iguana_utxoupdate(coin,spent_hdrsi,spent_unspentind,spent_pkind,spent_value,spendind,fromheight) == 0 ) + { + /*totalmillis += (OS_milliseconds() - startmillis); + if ( (++utxon % 100000) == 0 ) + printf("ave utxo[%d] %.2f micros total %.2f seconds\n",utxon,(1000. * totalmillis)/utxon,totalmillis/1000.);*/ + return(0); + } + } + printf("iguana_volatileupdate.%d: [%d] spent.(u%u %.8f pkind.%d) double spend? at ht.%d [%d] spendind.%d (%p %p)\n",incremental,spent_hdrsi,spent_unspentind,dstr(spent_value),spent_pkind,fromheight,fromheight/coin->chain->bundlesize,spendind,spentchain->Uextras,spentchain->A2); + if ( coin->current != 0 && fromheight >= coin->current->bundleheight ) + coin->RTdatabad = 1; + else + { + printf("from.%d vs current.%d\n",fromheight,coin->current->bundleheight); + iguana_bundleremove(coin,spent_hdrsi,0); + iguana_bundleremove(coin,fromheight/coin->chain->bundlesize,0); + } + exit(-1); + } else printf("volatileupdate error null rdata [%d]\n",spentchain->height/coin->current->bundleheight); + return(-1); +} + +void iguana_volatilesalloc(struct iguana_info *coin,struct iguana_ramchain *ramchain,int32_t copyflag) +{ + int32_t i; struct iguana_utxo *U2; struct iguana_account *A2; struct iguana_ramchaindata *rdata = 0; + if ( ramchain != 0 && (rdata= ramchain->H.data) != 0 && (coin->current == 0 || coin->current->bundleheight > ramchain->height) ) + { + //printf("volatilesalloc.[%d] %p %p\n",ramchain->height/coin->chain->bundlesize,ramchain->debitsfileptr,ramchain->lastspendsfileptr); + if ( ramchain->allocatedA2 == 0 ) + { + ramchain->A2 = calloc(sizeof(*ramchain->A2),rdata->numpkinds + 16); + ramchain->allocatedA2 = sizeof(*ramchain->A2) * rdata->numpkinds; + } + if ( ramchain->allocatedU2 == 0 ) + { + ramchain->Uextras = calloc(sizeof(*ramchain->Uextras),rdata->numunspents + 16); + ramchain->allocatedU2 = sizeof(*ramchain->Uextras) * rdata->numunspents; + } + if ( ramchain->debitsfileptr != 0 ) + { + if ( copyflag != 0 ) + { + A2 = (void *)((long)ramchain->debitsfileptr + sizeof(int32_t) + 2*sizeof(bits256)); + if ( ramchain->debitsfilesize != sizeof(int32_t) + 2*sizeof(bits256) + sizeof(*A2)*rdata->numpkinds ) + printf("A2 size mismatch %ld != %d\n",ramchain->debitsfilesize,(int32_t)(sizeof(int32_t) + 2*sizeof(bits256) + sizeof(*A2)*rdata->numpkinds)); + for (i=0; inumpkinds; i++) + ramchain->A2[i] = A2[i]; + } + munmap(ramchain->debitsfileptr,ramchain->debitsfilesize); + ramchain->debitsfileptr = 0; + ramchain->debitsfilesize = 0; + } + if ( ramchain->lastspendsfileptr != 0 ) + { + if ( copyflag != 0 ) + { + U2 = (void *)((long)ramchain->lastspendsfileptr + sizeof(int32_t) + 2*sizeof(bits256)); + if ( ramchain->lastspendsfilesize != sizeof(int32_t) + 2*sizeof(bits256) + sizeof(*U2)*rdata->numunspents ) + printf("U2 size mismatch %ld != %d\n",ramchain->lastspendsfilesize,(int32_t)(sizeof(int32_t) + 2*sizeof(bits256) + sizeof(*U2)*rdata->numunspents)); + for (i=0; inumunspents; i++) + ramchain->Uextras[i] = U2[i]; + } + munmap(ramchain->lastspendsfileptr,ramchain->lastspendsfilesize); + ramchain->lastspendsfileptr = 0; + ramchain->lastspendsfilesize = 0; + } + } else printf("illegal ramchain.%p rdata.%p\n",ramchain,rdata); +} + +void iguana_volatilespurge(struct iguana_info *coin,struct iguana_ramchain *ramchain) +{ + if ( ramchain != 0 ) + { + //printf("volatilespurge.[%d] (%p %p) %p %p\n",ramchain->height/coin->chain->bundlesize,ramchain->A2,ramchain->Uextras,ramchain->debitsfileptr,ramchain->lastspendsfileptr); + if ( ramchain->allocatedA2 != 0 && ramchain->A2 != 0 && ramchain->A2 != ramchain->debitsfileptr+sizeof(bits256)*2+sizeof(int32_t) ) + free(ramchain->A2); + if ( ramchain->allocatedU2 != 0 && ramchain->Uextras != 0 && ramchain->Uextras != ramchain->lastspendsfileptr+sizeof(bits256)*2+sizeof(int32_t) ) + free(ramchain->Uextras); + ramchain->A2 = 0; + ramchain->Uextras = 0; + ramchain->allocatedA2 = ramchain->allocatedU2 = 0; + if ( ramchain->debitsfileptr != 0 ) + { + munmap(ramchain->debitsfileptr,ramchain->debitsfilesize); + ramchain->debitsfileptr = 0; + ramchain->debitsfilesize = 0; + } + if ( ramchain->lastspendsfileptr != 0 ) + { + munmap(ramchain->lastspendsfileptr,ramchain->lastspendsfilesize); + ramchain->lastspendsfileptr = 0; + ramchain->lastspendsfilesize = 0; + } + } +} + +int32_t iguana_volatilesmap(struct iguana_info *coin,struct iguana_ramchain *ramchain) +{ + int32_t iter,numhdrsi,err = -1; char fname[1024]; bits256 balancehash,allbundles; struct iguana_ramchaindata *rdata; + if ( (rdata= ramchain->H.data) == 0 ) + { + if ( ramchain->height > 0 ) + printf("volatilesmap.[%d] no rdata\n",ramchain->height/coin->chain->bundlesize); + return(-1); + } + if ( ramchain->debitsfileptr != 0 && ramchain->lastspendsfileptr != 0 ) + return(0); + for (iter=0; iter<2; iter++) + { + sprintf(fname,"%s/%s%s/accounts/debits.%d",GLOBAL_DBDIR,iter==0?"ro/":"",coin->symbol,ramchain->height); + if ( (ramchain->debitsfileptr= OS_mapfile(fname,&ramchain->debitsfilesize,0)) != 0 && ramchain->debitsfilesize == sizeof(int32_t) + 2*sizeof(bits256) + sizeof(*ramchain->A2) * ramchain->H.data->numpkinds ) + { + ramchain->from_roA = (iter == 0); + numhdrsi = *(int32_t *)ramchain->debitsfileptr; + memcpy(balancehash.bytes,(void *)((long)ramchain->debitsfileptr + sizeof(numhdrsi)),sizeof(balancehash)); + memcpy(allbundles.bytes,(void *)((long)ramchain->debitsfileptr + sizeof(numhdrsi) + sizeof(balancehash)),sizeof(allbundles)); + if ( coin->balanceswritten == 0 ) + { + coin->balanceswritten = numhdrsi; + coin->balancehash = balancehash; + coin->allbundles = allbundles; + } + if ( numhdrsi == coin->balanceswritten && memcmp(balancehash.bytes,coin->balancehash.bytes,sizeof(balancehash)) == 0 && memcmp(allbundles.bytes,coin->allbundles.bytes,sizeof(allbundles)) == 0 ) + { + ramchain->A2 = (void *)((long)ramchain->debitsfileptr + sizeof(numhdrsi) + 2*sizeof(bits256)); + sprintf(fname,"%s/%s%s/accounts/lastspends.%d",GLOBAL_DBDIR,iter==0?"ro/":"",coin->symbol,ramchain->height); + if ( (ramchain->lastspendsfileptr= OS_mapfile(fname,&ramchain->lastspendsfilesize,0)) != 0 && ramchain->lastspendsfilesize == sizeof(int32_t) + 2*sizeof(bits256) + sizeof(*ramchain->Uextras) * ramchain->H.data->numunspents ) + { + numhdrsi = *(int32_t *)ramchain->lastspendsfileptr; + memcpy(balancehash.bytes,(void *)((long)ramchain->lastspendsfileptr + sizeof(numhdrsi)),sizeof(balancehash)); + memcpy(allbundles.bytes,(void *)((long)ramchain->lastspendsfileptr + sizeof(numhdrsi) + sizeof(balancehash)),sizeof(allbundles)); + if ( numhdrsi == coin->balanceswritten && memcmp(balancehash.bytes,coin->balancehash.bytes,sizeof(balancehash)) == 0 && memcmp(allbundles.bytes,coin->allbundles.bytes,sizeof(allbundles)) == 0 ) + { + ramchain->Uextras = (void *)((long)ramchain->lastspendsfileptr + sizeof(numhdrsi) + 2*sizeof(bits256)); + ramchain->from_roU = (iter == 0); + //printf("volatilesmap.[%d] %p %p\n",ramchain->height/coin->chain->bundlesize,ramchain->debitsfileptr,ramchain->lastspendsfileptr); + err = 0; + } else printf("ramchain map error2 balanceswritten %d vs %d hashes %x %x\n",coin->balanceswritten,numhdrsi,coin->balancehash.uints[0],balancehash.uints[0]); + } else printf("ramchain map error3 %s\n",fname); + } + else + { + printf("ramchain.[%d] map error balanceswritten %d vs %d hashes %x %x\n",ramchain->H.data->height,coin->balanceswritten,numhdrsi,coin->balancehash.uints[0],balancehash.uints[0]); + err++; + OS_removefile(fname,0); + } + } + if ( err == 0 ) + return(0); + } + //printf("couldnt map [%d]\n",ramchain->height/coin->chain->bundlesize); + iguana_volatilespurge(coin,ramchain); + return(err); +} diff --git a/iguana/iguana_wallet.c b/iguana/iguana_wallet.c index 9c38e1fd9..b2e67e629 100755 --- a/iguana/iguana_wallet.c +++ b/iguana/iguana_wallet.c @@ -14,153 +14,1416 @@ ******************************************************************************/ #include "iguana777.h" +#include "exchanges/bitcoin.h" -struct iguana_waccount *iguana_waccountcreate(struct iguana_info *coin,char *account) +void scrubfree(char *sensitivestr) { - struct iguana_waccount *waddr; int32_t len = (int32_t)strlen(account)+1; - HASH_FIND(hh,coin->wallet,account,len,waddr); - if ( waddr != 0 ) - return(waddr); - waddr = mycalloc('w',1,sizeof(*waddr) + len); - strcpy(waddr->account,account); - HASH_ADD(hh,coin->wallet,account,len,waddr); + long len,i; + if ( sensitivestr != 0 ) + { + len = strlen(sensitivestr); + memset(sensitivestr,0,len); + for (i=0; iwaddr,coinaddr,len,waddr); + if ( waddr != 0 && coin != 0 && strcmp(coin->symbol,waddr->symbol) != 0 ) + return(0); + //printf("%s (%s).%d in (%s)\n",waddr==0?"couldnt find":"found",coinaddr,len,wacct->account); return(waddr); } -struct iguana_waccount *iguana_waccountfind(struct iguana_info *coin,char *account) +struct iguana_waddress *iguana_waddressalloc(uint8_t addrtype,char *symbol,char *coinaddr,char *redeemScript) { - struct iguana_waccount *waddr; - HASH_FIND(hh,coin->wallet,account,strlen(account)+1,waddr); + struct iguana_waddress *waddr; int32_t scriptlen; + scriptlen = (redeemScript != 0) ? ((int32_t)strlen(redeemScript) >> 1) : 0; + waddr = mycalloc('w',1,sizeof(*waddr) + scriptlen); + waddr->addrtype = addrtype; + strcpy(waddr->coinaddr,coinaddr); + strcpy(waddr->symbol,symbol); + if ( (waddr->scriptlen= scriptlen) != 0 ) + decode_hex(waddr->redeemScript,scriptlen,redeemScript); return(waddr); } -struct iguana_waccount *iguana_waccountadd(struct iguana_info *coin,char *walletaccount,struct iguana_waddress *waddr) +struct iguana_waccount *iguana_waccountfind(struct supernet_info *myinfo,struct iguana_info *coin,char *account) { - struct iguana_waccount *acct; - if ( (acct= iguana_waccountfind(coin,walletaccount)) == 0 ) - acct = iguana_waccountcreate(coin,walletaccount); - return(acct); + struct iguana_waccount *wacct; + HASH_FIND(hh,myinfo->wallet,account,strlen(account)+1,wacct); + //printf("waccountfind.(%s) -> wacct.%p\n",account,wacct); + return(wacct); } -int32_t iguana_waccountswitch(struct iguana_info *coin,char *account,struct iguana_waccount *oldwaddr,int32_t oldind,char *coinaddr) +struct iguana_waccount *iguana_waccountcreate(struct supernet_info *myinfo,struct iguana_info *coin,char *account) { - // what if coinaddr is already in an account? - //printf("change %s walletaccount.(%s) (%s) <- %s\n",coin->symbol,waddr->account,waddr->coinaddr,coinaddr); - return(0); + struct iguana_waccount *wacct,*ptr; int32_t len = (int32_t)strlen(account)+1; + HASH_FIND(hh,myinfo->wallet,account,len,wacct); + if ( wacct == 0 ) + { + wacct = mycalloc('w',1,sizeof(*wacct)); + strcpy(wacct->account,account); + HASH_ADD_KEYPTR(hh,myinfo->wallet,wacct->account,len,wacct); + //printf("waccountcreate.(%s) -> wacct.%p\n",account,wacct); + myinfo->dirty = (uint32_t)time(NULL); + if ( (ptr= iguana_waccountfind(myinfo,coin,account)) != wacct ) + printf("iguana_waccountcreate verify error %p vs %p\n",ptr,wacct); + } + return(wacct); +} + +struct iguana_waddress *iguana_waddresscreate(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waccount *wacct,char *coinaddr,char *redeemScript) +{ + struct iguana_waddress *waddr,*ptr; int32_t len = (int32_t)strlen(coinaddr)+1; + if ( wacct == 0 ) + wacct = iguana_waccountcreate(myinfo,coin,""); + HASH_FIND(hh,wacct->waddr,coinaddr,len,waddr); + if ( waddr == 0 ) + { + if ( (waddr= iguana_waddressalloc(redeemScript==0?coin->chain->pubtype : coin->chain->p2shtype,coin->symbol,coinaddr,redeemScript)) != 0 ) + { + HASH_ADD_KEYPTR(hh,wacct->waddr,waddr->coinaddr,len,waddr); + myinfo->dirty = (uint32_t)time(NULL); + printf("create (%s).%d scriptlen.%d -> (%s)\n",coinaddr,len,waddr->scriptlen,wacct->account); + } else printf("error iguana_waddressalloc null waddr\n"); + } //else printf("have (%s) in (%s)\n",coinaddr,wacct->account); + if ( (ptr= iguana_waddressfind(myinfo,coin,wacct,coinaddr)) != waddr ) + printf("iguana_waddresscreate verify error %p vs %p\n",ptr,waddr); + return(waddr); } -struct iguana_waccount *iguana_waddressfind(struct iguana_info *coin,int32_t *indp,char *coinaddr) +struct iguana_waddress *iguana_waddressadd(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waccount *wacct,struct iguana_waddress *addwaddr,char *redeemScript) { + struct iguana_waddress *waddr,*ptr; int32_t len = (int32_t)strlen(addwaddr->coinaddr)+1; + HASH_FIND(hh,wacct->waddr,addwaddr->coinaddr,len,waddr); + if ( waddr == 0 ) + { + if ( (waddr= iguana_waddressalloc(redeemScript==0?coin->chain->pubtype : coin->chain->p2shtype,coin->symbol,addwaddr->coinaddr,redeemScript)) != 0 ) + { + HASH_ADD_KEYPTR(hh,wacct->waddr,waddr->coinaddr,len,waddr); + myinfo->dirty = (uint32_t)time(NULL); + printf("add (%s).%d scriptlen.%d -> (%s) wif.(%s)\n",waddr->coinaddr,len,waddr->scriptlen,wacct->account,waddr->wifstr); + } else printf("error iguana_waddressalloc null waddr\n"); + } //else printf("have (%s) in (%s)\n",waddr->coinaddr,wacct->account); + if ( (ptr= iguana_waddressfind(myinfo,coin,wacct,waddr->coinaddr)) != waddr ) + printf("iguana_waddressadd verify error %p vs %p\n",ptr,waddr); + if ( waddr != 0 && waddr != addwaddr ) + { + waddr->wiftype = coin->chain->wiftype; + if ( redeemScript != 0 && (addwaddr->scriptlen= (int32_t)strlen(redeemScript) >> 1) != 0 ) + { + if ( waddr->scriptlen != addwaddr->scriptlen ) + { + if ( waddr->scriptlen < addwaddr->scriptlen ) + { + printf("unexpected waddr->scriptlen mismatch\n"); + } + waddr->scriptlen = addwaddr->scriptlen; + decode_hex(waddr->redeemScript,waddr->scriptlen,redeemScript); + } + waddr->addrtype = coin->chain->p2shtype; + memset(&waddr->privkey,0,sizeof(waddr->privkey)); + memset(waddr->pubkey,0,sizeof(waddr->pubkey)); + } + else + { + waddr->addrtype = coin->chain->pubtype; + waddr->wiftype = addwaddr->wiftype; + if ( bits256_nonz(waddr->privkey) == 0 ) + waddr->privkey = addwaddr->privkey; + if ( addwaddr->wifstr[0] != 0 ) + strcpy(waddr->wifstr,addwaddr->wifstr); + memcpy(waddr->pubkey,addwaddr->pubkey,sizeof(waddr->pubkey)); + } + memcpy(waddr->rmd160,addwaddr->rmd160,sizeof(waddr->rmd160)); + strcpy(waddr->coinaddr,addwaddr->coinaddr); + myinfo->dirty = (uint32_t)time(NULL); + } + if ( waddr != 0 && waddr->symbol[0] == 0 ) + strcpy(waddr->symbol,coin->symbol); + return(waddr); +} + +struct iguana_waddress *iguana_waddressdelete(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waccount *wacct,char *coinaddr) +{ + struct iguana_waddress *waddr = 0; int32_t len = (int32_t)strlen(coinaddr)+1; + HASH_FIND(hh,wacct->waddr,coinaddr,len,waddr); + if ( waddr != 0 ) + { + HASH_DELETE(hh,wacct->waddr,waddr); + myinfo->dirty = (uint32_t)time(NULL); + } + return(waddr); +} + +struct iguana_waddress *iguana_waddresssearch(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waccount **wacctp,char *coinaddr) +{ + struct iguana_waccount *wacct,*tmp; struct iguana_waddress *waddr; + HASH_ITER(hh,myinfo->wallet,wacct,tmp) + { + if ( (waddr= iguana_waddressfind(myinfo,coin,wacct,coinaddr)) != 0 ) + { + if ( waddr != 0 && bits256_nonz(waddr->privkey) != 0 ) + { + if ( bitcoin_priv2wif(waddr->wifstr,waddr->privkey,coin->chain->wiftype) > 0 ) + { + if ( waddr->wiftype != coin->chain->wiftype ) + printf("waddresssearch warning: mismatched wiftype %02x != %02x\n",waddr->wiftype,coin->chain->wiftype); + if ( waddr->addrtype != coin->chain->pubtype ) + printf("waddresssearch warning: mismatched wiftype %02x != %02x\n",waddr->addrtype,coin->chain->pubtype); + } + } + (*wacctp) = wacct; + return(waddr); + } + } return(0); } -int32_t iguana_addressvalidate(struct iguana_info *coin,char *coinaddr) +struct iguana_waddress *iguana_waddresscalc(struct supernet_info *myinfo,uint8_t pubtype,uint8_t wiftype,struct iguana_waddress *addr,bits256 privkey) { + addr->privkey = privkey; + bitcoin_pubkey33(myinfo->ctx,addr->pubkey,addr->privkey); + calc_rmd160_sha256(addr->rmd160,addr->pubkey,33); + bitcoin_address(addr->coinaddr,pubtype,addr->rmd160,sizeof(addr->rmd160)); + if ( bits256_nonz(privkey) != 0 ) + { + if ( bitcoin_priv2wif(addr->wifstr,addr->privkey,wiftype) > 0 ) + { + addr->wiftype = wiftype; + addr->addrtype = pubtype; + return(addr); + } + } else printf("waddress_calc null privkey\n"); return(0); } -char *getnewaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *account) +struct iguana_waddress *iguana_waccountswitch(struct supernet_info *myinfo,struct iguana_info *coin,char *account,char *coinaddr,char *redeemScript) { - struct iguana_waddress addr; char str[67]; cJSON *retjson = cJSON_CreateObject(); - if ( iguana_waddresscalc(coin->chain->pubtype,coin->chain->wiftype,&addr,rand256(1)) == 0 ) + struct iguana_waccount *wacct = 0; struct iguana_waddress addr,*waddr = 0; int32_t flag = 0; + if ( (waddr= iguana_waddresssearch(myinfo,coin,&wacct,coinaddr)) != 0 ) { - jaddstr(retjson,"result",addr.coinaddr); - init_hexbytes_noT(str,addr.pubkey,33); - jaddstr(retjson,"pubkey",str); - jaddstr(retjson,"privkey",bits256_str(str,addr.privkey)); - jaddstr(retjson,"wif",addr.wifstr); - init_hexbytes_noT(str,addr.rmd160,20); - jaddstr(retjson,"rmd160",str); - if ( iguana_waccountadd(coin,account,&addr) < 0 ) - jaddstr(retjson,"account","error adding to account"); - else jaddstr(retjson,"account",account); - } else jaddstr(retjson,"error","cant create address"); - return(jprint(retjson,1)); + if ( strcmp(wacct->account,account) != 0 ) + { + addr = *waddr; + flag = 1; + iguana_waddressdelete(myinfo,coin,wacct,coinaddr); + } + } + if ( waddr == 0 && (wacct= iguana_waccountcreate(myinfo,coin,account)) != 0 ) + { + waddr = iguana_waddresscreate(myinfo,coin,wacct,coinaddr,redeemScript); + if ( flag != 0 && redeemScript == 0 ) + iguana_waddresscalc(myinfo,coin->chain->pubtype,coin->chain->wiftype,waddr,addr.privkey); + } + return(waddr); } -char *getaccountaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *account) +uint8_t *iguana_walletrmds(struct supernet_info *myinfo,struct iguana_info *coin,int32_t *numrmdsp) { - struct iguana_waccount *wacct; struct iguana_waddress *waddr=0,addr; char str[67];cJSON *retjson; - if ( account != 0 && account[0] != 0 ) + int32_t iter,n,m; struct iguana_waccount *acct,*tmp; uint8_t *pubkeys,*addrtypes,*rmdarray = 0; struct iguana_waddress *waddr,*tmp2; + for (iter=n=m=0; iter<2; iter++) { - if ( (wacct= iguana_waccountfind(coin,account)) == 0 ) + HASH_ITER(hh,myinfo->wallet,acct,tmp) { - if ( (waddr= iguana_waddresscalc(coin->chain->pubtype,coin->chain->wiftype,&addr,rand256(1))) == 0 ) - return(clonestr("{\"error\":\"cant generate address\"}")); - iguana_waccountswitch(coin,account,0,-1,addr.coinaddr); + HASH_ITER(hh,acct->waddr,waddr,tmp2) + { + if ( iter == 0 ) + n++; + else if ( m < n ) + { + addrtypes[m] = waddr->addrtype; + memcpy(&rmdarray[m * 20],waddr->rmd160,20); + memcpy(&pubkeys[m * 33],waddr->pubkey,33); + m++; + } + } + } + if ( iter == 0 ) + { + rmdarray = calloc(n,20 + 1 + 33); + addrtypes = &rmdarray[n * 20]; + pubkeys = &rmdarray[n * 21]; } - retjson = cJSON_CreateObject(); - jaddstr(retjson,"result",waddr->coinaddr); - init_hexbytes_noT(str,addr.pubkey,33); - jaddstr(retjson,"pubkey",str); - jaddstr(retjson,"privkey",bits256_str(str,waddr->privkey)); - jaddstr(retjson,"wif",waddr->wifstr); - init_hexbytes_noT(str,waddr->rmd160,20); - jaddstr(retjson,"rmd160",str); - jaddstr(retjson,"account",account); - return(jprint(retjson,1)); } - return(clonestr("{\"error\":\"no account specified\"}")); + return(rmdarray); +} + +cJSON *getaddressesbyaccount(struct supernet_info *myinfo,struct iguana_info *coin,char *account) +{ + struct iguana_waccount *subset; struct iguana_waddress *waddr,*tmp; cJSON *retjson,*array; + retjson = cJSON_CreateObject(); + array = cJSON_CreateArray(); + if ( (subset= iguana_waccountfind(myinfo,coin,account)) != 0 ) + { + HASH_ITER(hh,subset->waddr,waddr,tmp) + { + jaddistr(array,waddr->coinaddr); + } + } else jaddstr(retjson,"result","cant find account"); + return(array); +} + +struct iguana_waddress *iguana_ismine(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t addrtype,uint8_t pubkey[65],uint8_t rmd160[20]) +{ + char coinaddr[65]; struct iguana_waccount *wacct; struct iguana_waddress *waddr = 0; + if ( bitcoin_address(coinaddr,addrtype,rmd160,20) > 0 ) + waddr = iguana_waddresssearch(myinfo,coin,&wacct,coinaddr); + return(waddr); } -char *setaccount(struct supernet_info *myinfo,struct iguana_info *coin,char *account,char *coinaddr) +int32_t iguana_addressvalidate(struct iguana_info *coin,uint8_t *addrtypep,uint8_t rmd160[20],char *address) { - struct iguana_waccount *wacct; struct iguana_waddress *waddr=0,addr; int32_t ind=-1; + char checkaddr[64]; + bitcoin_addr2rmd160(addrtypep,rmd160,address); + if ( bitcoin_address(checkaddr,*addrtypep,rmd160,20) == checkaddr && strcmp(address,checkaddr) == 0 && (*addrtypep == coin->chain->pubtype || *addrtypep == coin->chain->p2shtype) ) + return(0); + else return(-1); +} + +cJSON *iguana_waddressjson(cJSON *item,struct iguana_waddress *waddr) +{ + char str[256],redeemScript[4096]; + if ( item == 0 ) + item = cJSON_CreateObject(); + jaddstr(item,"address",waddr->coinaddr); + //jaddstr(item,"privkey",bits256_str(str,waddr->privkey)); + //jaddstr(item,"wif",waddr->wifstr); + init_hexbytes_noT(str,waddr->rmd160,20); + jaddstr(item,"rmd160",str); + jaddstr(item,"coin",waddr->symbol); + if ( waddr->scriptlen > 0 ) + { + init_hexbytes_noT(redeemScript,waddr->redeemScript,waddr->scriptlen); + jaddstr(item,"redeemScript",redeemScript); + } + else + { + init_hexbytes_noT(str,waddr->pubkey,33); + jaddstr(item,"pubkey",str); + } + return(item); +} + +char *setaccount(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waddress **waddrp,char *account,char *coinaddr,char *redeemScript) +{ + uint8_t addrtype,rmd160[20]; struct iguana_waddress *waddr=0; + if ( waddrp != 0 ) + *waddrp = 0; if ( coinaddr != 0 && coinaddr[0] != 0 && account != 0 && account[0] != 0 ) { - if ( iguana_addressvalidate(coin,coinaddr) < 0 ) + if ( iguana_addressvalidate(coin,&addrtype,rmd160,coinaddr) < 0 ) return(clonestr("{\"error\":\"invalid coin address\"}")); - if ( (wacct= iguana_waddressfind(coin,&ind,coinaddr)) == 0 ) + if ( (waddr= iguana_waccountswitch(myinfo,coin,account,coinaddr,redeemScript)) != 0 ) { - if ( (waddr= iguana_waddresscalc(coin->chain->pubtype,coin->chain->wiftype,&addr,rand256(1))) == 0 ) - return(clonestr("{\"error\":\"cant generate address\"}")); + if ( waddrp != 0 ) + *waddrp = waddr; + return(clonestr("{\"result\":\"success\"}")); } - iguana_waccountswitch(coin,account,wacct,ind,coinaddr); - return(clonestr("{\"result\":\"account set\"}")); + else return(clonestr("{\"error\":\"couldnt set account\"}")); } return(clonestr("{\"error\":\"need address and account\"}")); } char *getaccount(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr) { - struct iguana_waccount *wacct; cJSON *retjson; int32_t ind; - if ( iguana_addressvalidate(coin,coinaddr) < 0 ) + struct iguana_waccount *wacct; struct iguana_waddress *waddr; uint8_t addrtype,rmd160[20]; cJSON *retjson; + if ( iguana_addressvalidate(coin,&addrtype,rmd160,coinaddr) < 0 ) return(clonestr("{\"error\":\"invalid coin address\"}")); - if ( (wacct= iguana_waddressfind(coin,&ind,coinaddr)) == 0 ) + if ( (waddr= iguana_waddresssearch(myinfo,coin,&wacct,coinaddr)) == 0 ) return(clonestr("{\"result\":\"no account for address\"}")); + if ( wacct != 0 ) + { + retjson = iguana_waddressjson(0,waddr); + jaddstr(retjson,"account",wacct->account); + jaddstr(retjson,"result","success"); + return(jprint(retjson,1)); + } else return(clonestr("{\"result\":\"\"}")); +} + +char *jsuccess() +{ + cJSON *retjson = cJSON_CreateObject(); + return(jprint(retjson,1)); +} + +char *iguana_addressconv(struct iguana_info *coin,char *destaddr,struct iguana_info *other,int32_t isp2sh,uint8_t rmd160[20]) +{ + if ( bitcoin_address(destaddr,isp2sh != 0 ? other->chain->pubtype : other->chain->p2shtype,rmd160,20) == destaddr ) + return(destaddr); + else return(0); +} + +int32_t iguana_loginsave(struct supernet_info *myinfo,struct iguana_info *coin,char *newstr) +{ + cJSON *loginjson; char *passphrase,destfname[1024]; + if ( (loginjson= cJSON_Parse(newstr)) != 0 ) + { + if ( (passphrase= jstr(loginjson,"passphrase")) != 0 ) + { + _SuperNET_encryptjson(destfname,passphrase,0,myinfo->permanentfile,0,loginjson); + //printf("loginsave.(%s) <= (%s)\n",destfname,newstr); + //iguana_walletlock(myinfo); + } + free_json(loginjson); + return(0); + } return(-1); +} + +int32_t iguana_payloadupdate(struct supernet_info *myinfo,struct iguana_info *coin,char *retstr,struct iguana_waddress *waddr,char *account) +{ + cJSON *retjson,*accountobj,*payload,*obj; char *newstr; int32_t retval = -1; + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( account == 0 || account[0] == 0 ) + account = "default"; + payload = cJSON_DetachItemFromObject(retjson,"wallet"); + if ( payload == 0 ) + payload = cJSON_CreateObject(); + if ( waddr != 0 ) + { + if ( (accountobj= jobj(payload,account)) != 0 && (obj= jobj(accountobj,waddr->coinaddr)) != 0 ) + { + free_json(retjson); + free_json(payload); + return(0); + } + if ( accountobj == 0 ) + { + accountobj = cJSON_CreateObject(); + jaddbits256(accountobj,waddr->coinaddr,waddr->privkey); + jadd(payload,account,accountobj); + } else jaddbits256(accountobj,waddr->coinaddr,waddr->privkey); + } + jadd(retjson,"wallet",payload); + newstr = jprint(retjson,1); + retval = iguana_loginsave(myinfo,coin,newstr); + //printf("newstr.(%s) retval.%d\n",newstr,retval); + free(newstr); + } else printf("iguana_payloadupdate: error parsing.(%s)\n",retstr); + return(retval); +} + +cJSON *iguana_payloadmerge(cJSON *loginjson,cJSON *importjson) +{ + cJSON *retjson,*item,*obj; char *field; + if ( loginjson == 0 ) + return(importjson); + else if ( importjson == 0 ) + return(loginjson); + retjson = jduplicate(loginjson); + item = importjson->child; + while ( item != 0 ) + { + if ( (field= jfieldname(item)) != 0 ) + { + if ( (obj= jobj(retjson,field)) == 0 ) + { + if ( strlen(field) == 20*2 ) + jaddstr(retjson,field,jstr(item,0)); + else jaddbits256(retjson,field,jbits256(item,0)); + } + } + item = item->next; + } + return(retjson); +} + +cJSON *iguana_walletadd(struct supernet_info *myinfo,struct iguana_waddress **waddrp,struct iguana_info *coin,char *retstr,char *account,struct iguana_waddress *refwaddr,int32_t setcurrent,char *redeemScript) +{ + cJSON *retjson=0; struct iguana_waccount *wacct; struct iguana_waddress *waddr; + if ( (wacct= iguana_waccountfind(myinfo,coin,account)) == 0 ) + wacct = iguana_waccountcreate(myinfo,coin,account); + if ( wacct != 0 ) + { + //waddr = iguana_waddressfind(myinfo,coin,wacct,refwaddr->coinaddr); + waddr = iguana_waddressadd(myinfo,coin,wacct,refwaddr,redeemScript); + if ( setcurrent != 0 ) + wacct->current = waddr; + if ( iguana_payloadupdate(myinfo,coin,retstr,waddr,account) < 0 ) + { + retjson = cJSON_CreateObject(); + jaddstr(retjson,"error","couldnt update wallet payload"); + } + else + { + retjson = iguana_waddressjson(retjson,waddr); + jaddstr(retjson,"account",account); + jaddstr(retjson,"result","success"); + } + } + if ( waddrp != 0 ) + (*waddrp) = waddr; + return(retjson); +} + +cJSON *iguana_walletjson(struct supernet_info *myinfo) +{ + struct iguana_waccount *wacct,*tmp; struct iguana_waddress *waddr,*tmp2; cJSON *wallet,*account; char scriptstr[4096]; + wallet = cJSON_CreateObject(); + HASH_ITER(hh,myinfo->wallet,wacct,tmp) + { + account = cJSON_CreateObject(); + HASH_ITER(hh,wacct->waddr,waddr,tmp2) + { + if ( bits256_nonz(waddr->privkey) == 0 && waddr->scriptlen == 0 ) + { + free_json(account); + free_json(wallet); + printf("found a null privkey in wallet, abort saving\n"); + return(0); + } + if ( waddr->scriptlen != 0 ) + { + init_hexbytes_noT(scriptstr,waddr->redeemScript,waddr->scriptlen); + jaddstr(account,waddr->coinaddr,scriptstr); + } else jaddbits256(account,waddr->coinaddr,waddr->privkey); + } + jadd(wallet,wacct->account,account); + } + return(wallet); +} + +int32_t iguana_walletemit(struct supernet_info *myinfo,char *fname,struct iguana_info *coin,cJSON *array) +{ + cJSON *item,*child; uint8_t addrtype,wiftype,rmd160[20]; char p2shaddr[128],str[64],wifstr[128],*account,*coinaddr,*privkeystr; int32_t i,j,n; FILE *fp; bits256 privkey; + if ( (fp= fopen(fname,"wb")) == 0 ) + return(-1); + n = cJSON_GetArraySize(array); + item = array->child; + for (i=0; istring) != 0 ) + { + child = item->child; + while ( child != 0 ) + { + coinaddr = child->string; + privkeystr = child->valuestring; + if ( coinaddr != 0 && privkeystr != 0 ) + { + bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr); + wiftype = 188; + for (j=0; jchain != 0 ) + { + if ( addrtype == coin->chain->pubtype ) + { + wiftype = coin->chain->wiftype; + privkey = bits256_conv(privkeystr); + if ( bits256_nonz(privkey) != 0 && bitcoin_priv2wif(wifstr,privkey,wiftype) > 0 ) + { + fprintf(fp,"%s %s %32s=%d # addr=%s\n",wifstr,utc_str(str,(uint32_t)time(NULL)),account,i+1,coinaddr); + } + break; + } + else if ( addrtype == coin->chain->p2shtype ) + { + fprintf(fp,"%s %s %32s=%d # addr=%s # p2sh\n",privkeystr,utc_str(str,(uint32_t)time(NULL)),account,i+1,p2shaddr); + break; + } + } + } + } + child = child->next; + } + //printf("account.(%s)\n",account); + } + item = item->next; + } + fclose(fp); + return(0); +} + +char *walleterrstr[] = { "P2SH_withpriv", "P2SH_withpub", "rmd160_mismatch", "pubkey_mismatch", "missing_pubkey", "account_mismatch" }; +uint8_t iguana_waddrvalidate(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waccount *wacct,struct iguana_waddress *waddr,int32_t repairflag,int32_t *errors) +{ + struct iguana_waccount *checkwacct; struct iguana_waddress *checkwaddr; uint8_t checkpub[33],rmd160[20],addrtype,checktype,plen,flag=0; + if ( waddr != 0 ) + { + if ( (checkwaddr= iguana_waddresssearch(myinfo,coin,&checkwacct,waddr->coinaddr)) != waddr || checkwacct != wacct ) + { + errors[5]++; + flag |= (5 << 0); + if ( repairflag > 0 ) + { + printf("waddrvalidate: need to manually setaccount to fix mismatch (%s:%s) <- (%s:%s)\n",checkwacct != 0 ? checkwacct->account : "",checkwaddr != 0 ? checkwaddr->coinaddr : "",wacct != 0 ? wacct->account : "",waddr->coinaddr); + } + } + if ( waddr->scriptlen > 0 ) + { + checktype = coin->chain->p2shtype; + if ( bits256_nonz(waddr->privkey) != 0 ) + { + errors[0]++; + flag |= (1 << 0); + if ( repairflag > 0 ) + memset(&waddr->privkey,0,sizeof(waddr->privkey)); + } + if ( bitcoin_pubkeylen(waddr->pubkey) > 0 ) + { + errors[1]++; + flag |= (1 << 1); + if ( repairflag > 0 ) + memset(waddr->pubkey,0,sizeof(waddr->pubkey)); + } + } + else checktype = coin->chain->pubtype; + if ( bitcoin_addr2rmd160(&addrtype,rmd160,waddr->coinaddr) != sizeof(rmd160) || addrtype != checktype || memcmp(rmd160,waddr->rmd160,sizeof(rmd160)) != 0 ) + { + errors[2]++; + flag |= (1 << 2); + if ( repairflag > 0 ) + { + waddr->addrtype = checktype; + memcpy(waddr->rmd160,rmd160,sizeof(rmd160)); + } + } + if ( waddr->scriptlen == 0 ) + { + if ( bits256_nonz(waddr->privkey) != 0 ) + { + bitcoin_pubkey33(myinfo->ctx,checkpub,waddr->privkey); + if ( memcmp(checkpub,waddr->pubkey,sizeof(checkpub)) != 0 ) + { + errors[3]++; + flag |= (1 << 3); + if ( repairflag > 0 ) + memcpy(waddr->pubkey,checkpub,sizeof(checkpub)); + } + } + if ( (plen= bitcoin_pubkeylen(waddr->pubkey)) > 0 ) + { + calc_rmd160_sha256(rmd160,waddr->pubkey,plen); + if ( memcmp(rmd160,waddr->rmd160,sizeof(rmd160)) != 0 ) + { + errors[4]++; + flag |= (1 << 4); + if ( repairflag > 0 ) + { + printf("waddrvalidate unrecoverable error: cant determine pubkey from rmd160\n"); + } + } + } + } + } + return(flag); +} + +cJSON *iguana_walletiterate(struct supernet_info *myinfo,struct iguana_info *coin,int32_t flag,cJSON *array,int32_t *goodp,int32_t *badp,int32_t *errors) +{ + struct iguana_waccount *wacct,*tmp; struct iguana_waddress *waddr=0,*tmp2; uint8_t errorflags; int32_t i,good=0,bad=0,_errors[8]; cJSON *item; + if ( errors == 0 ) + errors = _errors; + HASH_ITER(hh,myinfo->wallet,wacct,tmp) + { + HASH_ITER(hh,wacct->waddr,waddr,tmp2) + { + if ( flag < 0 ) + { + memset(&waddr->privkey,0,sizeof(waddr->privkey)); + memset(waddr->wifstr,0,sizeof(waddr->wifstr)); + for (i=0; iprivkey); i++) + waddr->privkey.bytes[i] = rand(); + for (i=0; iwifstr); i++) + waddr->wifstr[i] = rand(); + if ( flag < -1 ) + { + HASH_DELETE(hh,wacct->waddr,waddr); + if ( waddr->unspents != 0 ) + free(waddr->unspents); + printf("%p free %s\n",waddr,waddr->coinaddr); + myfree(waddr,sizeof(*waddr) + waddr->scriptlen); + } + } + else + { + wacct->current = waddr; + if ( (errorflags= iguana_waddrvalidate(myinfo,coin,wacct,waddr,flag,errors)) != 0 ) + { + bad++; + if ( array != 0 && (item= cJSON_CreateObject()) != 0 ) + { + jaddnum(item,waddr->coinaddr,errorflags); + jaddi(array,item); + } + } else good++; + } + } + if ( flag < -1 ) + { + HASH_DELETE(hh,myinfo->wallet,wacct); + myfree(wacct,sizeof(*wacct)); + } + } + if ( goodp != 0 ) + *goodp = good; + if ( badp != 0 ) + *badp = bad; + return(array); +} + +char *iguana_walletscan(struct supernet_info *myinfo,struct iguana_info *coin,int32_t repairflag) +{ + cJSON *retjson; int32_t i,good,bad,errors[8]; + memset(errors,0,sizeof(errors)); + good = bad = 0; retjson = cJSON_CreateObject(); - jaddstr(retjson,"result",wacct->account); + jadd(retjson,"result",iguana_walletiterate(myinfo,coin,repairflag,cJSON_CreateArray(),&good,&bad,errors)); + jaddnum(retjson,"good",good); + jaddnum(retjson,"bad",bad); + for (i=0; iwallet == 0 && myinfo->decryptstr != 0 && (payload= cJSON_Parse(myinfo->decryptstr)) != 0 ) + { + if ( (array= jobj(payload,"wallet")) != 0 ) + { + n = cJSON_GetArraySize(array); + //printf("item.(%s) size.%d\n",jprint(array,0),n); + item = array->child; + for (i=0; istring) != 0 ) + { + child = item->child; + while ( child != 0 ) + { + coinaddr = child->string; + privkeystr = child->valuestring; + if ( coinaddr != 0 && privkeystr != 0 ) + { + if ( (wacct= iguana_waccountcreate(myinfo,coin,account)) != 0 ) + { + if ( iguana_waddresssearch(myinfo,coin,&tmp,coinaddr) == 0 ) + { + memset(&waddr,0,sizeof(waddr)); + strcpy(waddr.coinaddr,coinaddr); + waddr.addrtype = coin->chain->p2shtype; + if ( bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr) == sizeof(rmd160) && addrtype == coin->chain->p2shtype ) + iguana_waddressadd(myinfo,coin,wacct,&waddr,privkeystr); + else + { + waddr.addrtype = coin->chain->pubtype; + privkey = bits256_conv(privkeystr); + if ( iguana_waddresscalc(myinfo,coin->chain->pubtype,coin->chain->wiftype,&waddr,privkey) != 0 ) + iguana_waddressadd(myinfo,coin,wacct,&waddr,0); + } + } else printf("dup.(%s) ",coinaddr); + len = (int32_t)strlen(privkeystr); + for (j=0; jnext; + } + printf("account.(%s)\n",account); + } + item = item->next; + } + } + free_json(payload); + myinfo->decryptstr = 0; + scrubfree(myinfo->decryptstr); + myinfo->dirty = 0; + } + iguana_walletiterate(myinfo,coin,1,0,0,0,0); +} + +void iguana_walletlock(struct supernet_info *myinfo,struct iguana_info *coin) +{ + memset(&myinfo->persistent_priv,0,sizeof(myinfo->persistent_priv)); + memset(myinfo->secret,0,sizeof(myinfo->secret)); + memset(myinfo->permanentfile,0,sizeof(myinfo->permanentfile)); + if ( myinfo->decryptstr != 0 ) + scrubfree(myinfo->decryptstr), myinfo->decryptstr = 0; + myinfo->expiration = 0; + iguana_walletiterate(myinfo,coin,-2,0,0,0,0); +} + +int64_t iguana_waccountbalance(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waccount *wacct,int32_t minconf,int32_t lastheight) +{ + int64_t balance; int32_t numrmds=0,numunspents = 0; uint8_t *rmdarray=0; + if ( minconf == 0 ) + minconf = 1; + rmdarray = iguana_rmdarray(coin,&numrmds,getaddressesbyaccount(myinfo,coin,wacct->account),0); + balance = iguana_unspents(myinfo,coin,0,minconf,(1 << 30),rmdarray,numrmds,lastheight,0,&numunspents); + if ( rmdarray != 0 ) + free(rmdarray); + return(balance); +} + +#include "../includes/iguana_apidefs.h" +#include "../includes/iguana_apideclares.h" + +int64_t iguana_addressreceived(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *json,char *remoteaddr,cJSON *txids,cJSON *vouts,char *coinaddr,int32_t minconf) +{ + int64_t balance = 0; cJSON *unspentsjson,*balancejson,*item; int32_t i,n; char *balancestr; + if ( (balancestr= iguana_balance(IGUANA_CALLARGS,coin->symbol,coinaddr,-1,minconf)) != 0 ) + { + printf("balancestr.(%s) (%s)\n",balancestr,coinaddr); + if ( (balancejson= cJSON_Parse(balancestr)) != 0 ) + { + balance = jdouble(balancejson,"balance") * SATOSHIDEN; + if ( (txids != 0 || vouts != 0) && (unspentsjson= jarray(&n,balancejson,"unspents")) != 0 ) + { + for (i=0; iexpiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + myinfo->expiration++; + if ( retstr != 0 ) + { + memset(&addr,0,sizeof(addr)); + if ( iguana_waddresscalc(myinfo,coin->chain->pubtype,coin->chain->wiftype,&addr,bitcoin_randkey(myinfo->ctx)) != 0 ) + retjson = iguana_walletadd(myinfo,waddrp,coin,retstr,account,&addr,1,0); + else return(clonestr("{\"error\":\"couldnt calculate waddr\"}")); + } else return(clonestr("{\"error\":\"no wallet data\"}")); + return(jprint(retjson,1)); +} + +STRING_ARG(bitcoinrpc,validateaddress,address) +{ + cJSON *retjson; int32_t i; uint8_t addrtype,rmd160[20],pubkey[65]; struct iguana_info *other; char str[256]; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( iguana_addressvalidate(coin,&addrtype,rmd160,address) < 0 ) + return(clonestr("{\"error\":\"invalid coin address\"}")); retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddnum(retjson,"addrtype",addrtype); + init_hexbytes_noT(str+6,rmd160,sizeof(rmd160)); + jaddstr(retjson,"rmd160",str+6); + memcpy(str,"76a914",6); + strcat(str,"88ac"); + jaddstr(retjson,"scriptPubKey",str); + jadd(retjson,"isscript",(addrtype == coin->chain->p2shtype) ? jtrue() : jfalse()); + if ( iguana_ismine(myinfo,coin,addrtype,pubkey,rmd160) > 0 ) + { + init_hexbytes_noT(str,pubkey,bitcoin_pubkeylen(pubkey)); + jaddstr(retjson,"pubkey",str); + cJSON_AddTrueToObject(retjson,"ismine"); + } + else cJSON_AddFalseToObject(retjson,"ismine"); + for (i=0; isymbol,coin->symbol) != 0 ) + { + iguana_addressconv(coin,str,other,addrtype == coin->chain->p2shtype,rmd160); + jaddstr(retjson,other->symbol,str); + } + } + return(jprint(retjson,1)); +} + +ZERO_ARGS(bitcoinrpc,getinfo) +{ + cJSON *retjson; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + retjson = cJSON_CreateObject(); + if ( coin != 0 ) + { + jaddstr(retjson,"result","success"); + jaddnum(retjson,"protocolversion",PROTOCOL_VERSION); + jaddnum(retjson,"kbfee",dstr(coin->txfee_perkb)); + jaddnum(retjson,"blocks",coin->blocks.hwmchain.height); + jaddnum(retjson,"longestchain",coin->longestchain); + jaddnum(retjson,"port",coin->chain->portp2p); + jaddnum(retjson,"connections",coin->peers.numranked); + jaddnum(retjson,"difficulty",coin->blocks.hwmchain.PoW); + jaddstr(retjson,"status",coin->statusstr); + jaddstr(retjson,"coin",coin->symbol); + } + return(jprint(retjson,1)); +} + +TWO_STRINGS(bitcoinrpc,setaccount,address,account) +{ + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + myinfo->expiration++; + return(setaccount(myinfo,coin,0,account,address,0)); +} + +STRING_ARG(bitcoinrpc,getaccount,address) +{ + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + return(getaccount(myinfo,coin,address)); +} + +STRING_ARG(bitcoinrpc,getnewaddress,account) +{ + char *retstr,*newretstr; struct iguana_waddress *waddr; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + myinfo->expiration++; + if ( (retstr= SuperNET_login(IGUANA_CALLARGS,myinfo->handle,myinfo->secret,myinfo->permanentfile,0)) != 0 ) + { + free(retstr); + retstr = myinfo->decryptstr, myinfo->decryptstr = 0; + newretstr = getnewaddress(myinfo,&waddr,coin,account,retstr); + if ( retstr != 0 ) + scrubfree(retstr); + return(newretstr); + } + else return(clonestr("{\"error\":\"no wallet payload\"}")); +} + +STRING_ARG(bitcoinrpc,getaccountaddress,account) +{ + char *retstr,*newstr; struct iguana_waccount *wacct; struct iguana_waddress *waddr=0; cJSON *retjson; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + myinfo->expiration++; + if ( account != 0 && account[0] != 0 ) + { + if ( (wacct= iguana_waccountfind(myinfo,coin,account)) == 0 ) + wacct = iguana_waccountcreate(myinfo,coin,account); + if ( wacct != 0 ) + { + if ( (waddr= wacct->current) == 0 ) + { + if ( (retstr= SuperNET_login(IGUANA_CALLARGS,myinfo->handle,myinfo->secret,myinfo->permanentfile,0)) != 0 ) + { + free(retstr); + retstr = myinfo->decryptstr, myinfo->decryptstr = 0; + printf("loginstr.(%s)\n",retstr); + newstr = getnewaddress(myinfo,&waddr,coin,account,retstr); + if ( retstr != 0 ) + scrubfree(retstr); + retstr = newstr; + } else return(clonestr("{\"error\":\"no wallet payload\"}")); + } + if ( waddr != 0 ) + retjson = iguana_waddressjson(0,waddr); + else return(clonestr("{\"error\":\"couldnt create address\"}")); + jaddstr(retjson,"account",account); + jaddstr(retjson,"result","success"); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"cant find account\"}")); + } + return(clonestr("{\"error\":\"no account specified\"}")); +} + +ZERO_ARGS(bitcoinrpc,walletlock) +{ + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + iguana_walletlock(myinfo,coin); + return(jsuccess()); +} + +TWOSTRINGS_AND_INT(bitcoinrpc,walletpassphrase,password,permanentfile,timeout) +{ + char *retstr; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( timeout <= 0 ) + return(clonestr("{\"error\":\"timeout must be positive\"}")); + myinfo->expiration = (uint32_t)time(NULL) + timeout; + retstr = SuperNET_login(IGUANA_CALLARGS,myinfo->handle,password,permanentfile,0); + iguana_walletinitcheck(myinfo,coin); + return(retstr); +} + +THREE_STRINGS(bitcoinrpc,encryptwallet,passphrase,password,permanentfile) +{ + char *retstr; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( password == 0 || password[0] == 0 ) + password = passphrase; + retstr = SuperNET_login(IGUANA_CALLARGS,myinfo->handle,password,permanentfile,passphrase); + //iguana_walletlock(myinfo); + return(retstr); +} + +FOUR_STRINGS(bitcoinrpc,walletpassphrasechange,oldpassword,newpassword,oldpermanentfile,newpermanentfile) +{ + char destfname[1024],*tmpstr,*loginstr,*passphrase,*retstr = 0; cJSON *tmpjson,*loginjson; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( (tmpstr= SuperNET_login(IGUANA_CALLARGS,myinfo->handle,oldpassword,oldpermanentfile,0)) != 0 ) + { + free(tmpstr); + tmpstr = myinfo->decryptstr, myinfo->decryptstr = 0; + if ( (tmpjson= cJSON_Parse(tmpstr)) != 0 ) + { + if ( (loginstr= SuperNET_login(IGUANA_CALLARGS,myinfo->handle,newpassword,newpermanentfile,0)) != 0 ) + { + if ( myinfo->decryptstr != 0 && (loginjson= cJSON_Parse(myinfo->decryptstr)) != 0 ) + { + if ( (passphrase= jstr(loginjson,"passphrase")) != 0 ) + { + _SuperNET_encryptjson(destfname,passphrase,0,newpermanentfile,0,loginjson); + //iguana_walletlock(myinfo); + retstr = SuperNET_login(IGUANA_CALLARGS,myinfo->handle,newpassword,newpermanentfile,0); + } + free_json(loginjson); + } + free(loginstr); + } + free_json(tmpjson); + } + if ( tmpstr != 0 ) + scrubfree(tmpstr); + } + if ( retstr == 0 ) + retstr = clonestr("{\"error\":\"error changing walletpassphrase\"}"); + return(retstr); +} + +TWOSTRINGS_AND_INT(bitcoinrpc,importprivkey,wif,account,rescan) +{ + bits256 privkey; char *retstr,*str; cJSON *retjson; struct iguana_waddress addr,*waddr; struct iguana_waccount *wacct = 0; uint8_t type,redeemScript[4096]; int32_t len; struct vin_info V; bits256 debugtxid; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + myinfo->expiration++; + if ( account == 0 || account[0] == 0 ) + account = "default"; + len = (int32_t)strlen(wif); + if ( is_hexstr(wif,len) > 0 ) + { + len >>= 1; + decode_hex(redeemScript,len,wif); + if ( (type= iguana_calcrmd160(coin,0,&V,redeemScript,len,debugtxid,-1,0xffffffff)) == IGUANA_SCRIPT_P2SH || type == IGUANA_SCRIPT_1of1 || V.N > 1 ) + { + if ( (str= setaccount(myinfo,coin,&waddr,account,V.coinaddr,wif)) != 0 ) + free(str); + retjson = iguana_p2shjson(myinfo,coin,0,waddr); + return(jprint(retjson,1)); + } + } + privkey = iguana_str2priv(myinfo,coin,wif); + if ( bits256_nonz(privkey) == 0 ) + return(clonestr("{\"error\":\"illegal privkey\"}")); + memset(&addr,0,sizeof(addr)); + if ( iguana_waddresscalc(myinfo,coin->chain->pubtype,coin->chain->wiftype,&addr,privkey) != 0 ) + { + if ( (waddr= iguana_waddresssearch(myinfo,coin,&wacct,addr.coinaddr)) != 0 ) + { + waddr = iguana_waccountswitch(myinfo,coin,account,addr.coinaddr,0); + return(clonestr("{\"result\":\"privkey already in wallet\"}")); + } + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + myinfo->expiration++; + if ( (retstr= SuperNET_login(IGUANA_CALLARGS,myinfo->handle,myinfo->secret,myinfo->permanentfile,0)) != 0 ) + { + free(retstr); + retstr = myinfo->decryptstr, myinfo->decryptstr = 0; + if ( waddr == 0 ) + waddr = &addr; + iguana_waddresscalc(myinfo,coin->chain->pubtype,coin->chain->wiftype,waddr,privkey); + retjson = iguana_walletadd(myinfo,0,coin,retstr,account,waddr,0,0); + if ( retstr != 0 ) + scrubfree(retstr); + return(jprint(retjson,1)); + } + } + return(clonestr("{\"error\":\"cant calculate waddress\"}")); +} + +STRING_ARG(bitcoinrpc,dumpprivkey,address) +{ + cJSON *retjson; int32_t len,p2shflag=0; struct iguana_waddress *waddr; struct iguana_waccount *wacct; uint8_t addrtype,type,redeemScript[IGUANA_MAXSCRIPTSIZE],rmd160[20]; char *coinaddr; struct vin_info V; bits256 debugtxid; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + myinfo->expiration++; + len = (int32_t)strlen(address); + coinaddr = address; + if ( is_hexstr(address,len) > 0 ) + { + len >>= 1; + decode_hex(redeemScript,len,address); + if ( (type= iguana_calcrmd160(coin,0,&V,redeemScript,len,debugtxid,-1,0xffffffff)) == IGUANA_SCRIPT_P2SH || type == IGUANA_SCRIPT_1of1 || V.N > 1 ) + { + p2shflag = 1; + coinaddr = V.coinaddr; + } + } + if ( strlen(coinaddr) > sizeof(V.coinaddr) || iguana_addressvalidate(coin,&addrtype,rmd160,coinaddr) < 0 ) + return(clonestr(p2shflag == 0 ? "{\"error\":\"invalid address\"}" : "{\"error\":\"invalid P2SH address\"}")); + if ( (waddr= iguana_waddresssearch(myinfo,coin,&wacct,coinaddr)) != 0 ) + { + if ( (waddr->wifstr[0] != 0 || waddr->scriptlen > 0) ) + { + retjson = cJSON_CreateObject(); + if ( waddr->scriptlen == 0 && waddr->wifstr[0] != 0 ) + jaddstr(retjson,"result",waddr->wifstr); + else iguana_p2shjson(myinfo,coin,retjson,waddr); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"no privkey for address\"}")); + } else return(clonestr("{\"error\":\"couldnt find address in wallet\"}")); +} + +STRING_ARG(bitcoinrpc,dumpwallet,filename) +{ + char *retstr,*walletstr; cJSON *retjson,*walletobj,*strobj; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration != 0 ) + { + myinfo->expiration++; + if ( (retstr= SuperNET_login(IGUANA_CALLARGS,myinfo->handle,myinfo->secret,myinfo->permanentfile,0)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (walletstr= myinfo->decryptstr) != 0 ) + { + myinfo->decryptstr = 0; + if ( (strobj= cJSON_Parse(walletstr)) != 0 ) + { + if ( (walletobj= jobj(strobj,"wallet")) != 0 ) + jadd(retjson,"wallet",jduplicate(walletobj)); + if ( 0 && (walletobj= iguana_walletjson(myinfo)) != 0 ) + jadd(retjson,"memory",walletobj); + free_json(strobj); + } + scrubfree(walletstr); + } + return(jprint(retjson,1)); + } else printf("cant parse retstr.(%s)\n",retstr); + } else return(clonestr("{\"error\":\"couldnt decrypt wallet\"}")); + } + return(clonestr("{\"error\":\"wallet is locked, cant backup\"}")); +} + +STRING_ARG(bitcoinrpc,backupwallet,filename) +{ + char *loginstr,*retstr = 0; cJSON *retjson,*payload; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration != 0 ) + { + myinfo->expiration++; + if ( (loginstr= SuperNET_login(IGUANA_CALLARGS,myinfo->handle,myinfo->secret,myinfo->permanentfile,0)) != 0 ) + { + retstr = clonestr("{\"error\":\"couldnt backup wallet\"}"); + free(loginstr); + loginstr = myinfo->decryptstr, myinfo->decryptstr = 0; + if ( (retjson= cJSON_Parse(loginstr)) != 0 ) + { + if ( (payload= jobj(retjson,"wallet")) != 0 && iguana_walletemit(myinfo,filename,coin,payload) == 0 ) + retstr = clonestr("{\"result\":\"wallet backup saved\"}"); + free_json(retjson); + } + if ( loginstr != 0 ) + scrubfree(loginstr); + return(retstr); + } else return(clonestr("{\"error\":\"no wallet payload\"}")); + } else return(clonestr("{\"error\":\"need to unlock wallet\"}")); +} + +STRING_ARG(bitcoinrpc,importwallet,filename) +{ + cJSON *retjson = 0,*importjson,*loginjson = 0; long filesize; char *importstr,*loginstr; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration != 0 ) + { + myinfo->expiration++; + if ( (importstr= OS_filestr(&filesize,filename)) != 0 ) + { + if ( (importjson= cJSON_Parse(importstr)) != 0 ) + { + if ( (loginstr= SuperNET_login(IGUANA_CALLARGS,myinfo->handle,myinfo->secret,myinfo->permanentfile,0)) != 0 ) + { + free(loginstr); + loginstr = myinfo->decryptstr, myinfo->decryptstr = 0; + loginjson = cJSON_Parse(loginstr); + if ( loginstr != 0 ) + scrubfree(loginstr); + } + retjson = iguana_payloadmerge(loginjson,importjson); + if ( importjson != 0 && importjson != retjson ) + free_json(importjson); + if ( loginjson != 0 && loginjson != retjson ) + free_json(loginjson); + } + else + { + free(importstr); + return(clonestr("{\"error\":\"couldnt parse import file\"}")); + } + return(clonestr("{\"result\":\"wallet imported\"}")); + } else return(clonestr("{\"error\":\"couldnt open import file\"}")); + } + return(clonestr("{\"error\":\"need to unlock wallet\"}")); +} + +ZERO_ARGS(bitcoinrpc,checkwallet) +{ + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + myinfo->expiration++; + return(iguana_walletscan(myinfo,coin,1)); +} + +ZERO_ARGS(bitcoinrpc,repairwallet) +{ + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + myinfo->expiration++; + return(iguana_walletscan(myinfo,coin,0)); +} + +// multiple address +STRING_AND_THREEINTS(bitcoinrpc,getbalance,account,minconf,includeempty,lastheight) +{ + int64_t balance; int32_t numunspents,numrmds=0; uint8_t *rmdarray=0; cJSON *retjson; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + if ( account == 0 ) + account = ""; + if ( minconf == 0 ) + minconf = 1; + if ( strcmp(account,"*") != 0 ) + rmdarray = iguana_rmdarray(coin,&numrmds,getaddressesbyaccount(myinfo,coin,account),0); + numunspents = 0; + balance = iguana_unspents(myinfo,coin,0,minconf,(1 << 30),rmdarray,numrmds,lastheight,0,&numunspents); + if ( rmdarray != 0 ) + free(rmdarray); + retjson = cJSON_CreateObject(); + jaddnum(retjson,"result",dstr(balance)); + return(jprint(retjson,1)); +} + +STRING_ARG(bitcoinrpc,getaddressesbyaccount,account) +{ + cJSON *retjson; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + retjson = cJSON_CreateObject(); + jadd(retjson,"result",getaddressesbyaccount(myinfo,coin,account)); + return(jprint(retjson,1)); +} + +STRING_AND_INT(bitcoinrpc,getreceivedbyaccount,account,minconf) +{ + cJSON *retjson; struct iguana_waccount *wacct; int64_t balance; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + retjson = cJSON_CreateObject(); + if ( (wacct= iguana_waccountfind(myinfo,coin,account)) != 0 ) + { + balance = iguana_waccountbalance(myinfo,coin,wacct,minconf,0); + jaddnum(retjson,"result",dstr(balance)); + } + return(jprint(retjson,1)); +} + +STRING_AND_THREEINTS(bitcoinrpc,listtransactions,account,count,skip,includewatchonly) +{ + cJSON *retjson,*retarray,*txids,*vouts,*item,*array; int32_t vout,i,j,total,m,n = 0; struct iguana_waccount *wacct; char *coinaddr; bits256 txid; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + retjson = cJSON_CreateObject(); + retarray = cJSON_CreateArray(); + if ( (wacct= iguana_waccountfind(myinfo,coin,account)) != 0 ) + { + if ( (array= getaddressesbyaccount(myinfo,coin,account)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + total = 0; + for (i=0; i 0 ) + { + for (j=0; jaccount); + jaddstr(item,"address",coinaddr); + jaddbits256(item,"txid",txid); + jaddnum(item,"vout",vout); + //return(bitcoinrpc_getrawtransaction(IGUANA_CALLARGS,txid,1)); + + jaddi(retarray,item); + } + } + } + } + free_json(txids); + } + } + } + } + } + jadd(retjson,"result",retarray); + return(jprint(retjson,1)); +} + +THREE_INTS(bitcoinrpc,listreceivedbyaccount,minconf,includeempty,watchonly) +{ + cJSON *retjson,*item,*array; struct iguana_waccount *wacct,*tmp; int64_t balance; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + array = cJSON_CreateArray(); + HASH_ITER(hh,myinfo->wallet,wacct,tmp) + { + balance = iguana_waccountbalance(myinfo,coin,wacct,minconf,0); + item = cJSON_CreateObject(); + jaddstr(item,"account",wacct->account); + jaddnum(item,"amount",dstr(balance)); + jaddnum(item,"confirmations",minconf); + jaddi(array,item); + } + retjson = cJSON_CreateObject(); + jadd(retjson,"result",array); + return(jprint(retjson,1)); +} + +THREE_INTS(bitcoinrpc,listreceivedbyaddress,minconf,includeempty,flag) +{ + cJSON *retjson,*item,*array,*txids,*vouts; struct iguana_waccount *wacct,*tmp; struct iguana_waddress *waddr,*tmp2; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); array = cJSON_CreateArray(); - if ( (subset= iguana_waccountfind(coin,account)) != 0 ) + HASH_ITER(hh,myinfo->wallet,wacct,tmp) { - HASH_ITER(hh,subset->waddrs,waddr,tmp) + HASH_ITER(hh,wacct->waddr,waddr,tmp2) { - jaddistr(array,waddr->coinaddr); + item = cJSON_CreateObject(); + jaddstr(item,"address",waddr->coinaddr); + txids = cJSON_CreateArray(); + vouts = cJSON_CreateArray(); + jaddnum(item,"amount",dstr(iguana_addressreceived(myinfo,coin,0,remoteaddr,txids,vouts,waddr->coinaddr,minconf))); + jadd(item,"txids",txids); + jadd(item,"vouts",vouts); + jaddi(array,item); } - } else jaddstr(retjson,"result","cant find account"); - jadd(retjson,"addresses",array); + } + retjson = cJSON_CreateObject(); + jadd(retjson,"result",array); return(jprint(retjson,1)); } -char *sendtoaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr,double amount,char *comment,char *comment2) +STRING_AND_INT(bitcoinrpc,getreceivedbyaddress,address,minconf) { - //char *coinaddr; - //sendtoaddress [comment] [comment-to] is a real and is rounded to 8 decimal places. Returns the transaction ID if successful. Y - if ( coinaddr != 0 && coinaddr[0] != 0 && amount > 0. ) + char *balancestr; cJSON *balancejson,*retjson = cJSON_CreateObject(); + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + if ( (balancestr= iguana_balance(IGUANA_CALLARGS,coin->symbol,address,-1,minconf)) != 0 ) { - if ( iguana_addressvalidate(coin,coinaddr) < 0 ) - return(clonestr("{\"error\":\"invalid coin address\"}")); - //amount = jdouble(params[1],0); - //comment = jstr(params[2],0); - //comment2 = jstr(params[3],0); - printf("need to generate send %.8f to %s [%s] [%s]\n",dstr(amount),coinaddr,comment!=0?comment:"",comment2!=0?comment2:""); + if ( (balancejson= cJSON_Parse(balancestr)) != 0 ) + { + jaddnum(retjson,"result",dstr(jdouble(balancejson,"balance"))); + free_json(balancejson); + } } - return(clonestr("{\"error\":\"need address and amount\"}")); + if ( jobj(retjson,"result") == 0 ) + jaddstr(retjson,"error","couldnt get received by address"); + return(jprint(retjson,1)); +} + +TWO_INTS(bitcoinrpc,listaccounts,minconf,includewatchonly) +{ + cJSON *retjson,*array; int64_t balance; struct iguana_waccount *wacct,*tmp; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + array = cJSON_CreateObject(); + HASH_ITER(hh,myinfo->wallet,wacct,tmp) + { + balance = iguana_waccountbalance(myinfo,coin,wacct,minconf,0); + jaddnum(array,wacct->account,dstr(balance)); + } + retjson = cJSON_CreateObject(); + jadd(retjson,"result",array); + return(jprint(retjson,1)); } + +#include "../includes/iguana_apiundefs.h" + diff --git a/iguana/images/img1.png b/iguana/images/img1.png old mode 100644 new mode 100755 diff --git a/iguana/images/img2.jpg b/iguana/images/img2.jpg old mode 100644 new mode 100755 diff --git a/iguana/images/img3.png b/iguana/images/img3.png old mode 100644 new mode 100755 diff --git a/iguana/images/img4.png b/iguana/images/img4.png old mode 100644 new mode 100755 diff --git a/iguana/index.html b/iguana/index.html old mode 100644 new mode 100755 index 58fe10620..50efa9c89 --- a/iguana/index.html +++ b/iguana/index.html @@ -20,7 +20,6 @@ - -